Version 2.8.0-dev.13.0
Merge commit '30a12a349e0aa03a760016703d80fc89d12f3ec7' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8fcdcd5..9146f83 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -104,6 +104,9 @@
`package:js` interop specification must now be wrapped with a call to
`allowInterop`. This behavior was always enforced by `dart2js`, but was not
enforced consistently in `ddc`. It will now be enforced in both.
+* **Breaking Change**: Constructors in `@JS()` classes must be marked with
+ `external`. Previously the external could be omitted in some cases with DDC
+ but doing so would cause incorrect behavior with `dart2js`.
* JS interop classes with an index operator are now static errors.
* Removed the `dart:mirrors` library from the SDK. Use of this library on the
web has been unsupported and prevented by the Dart build systems since Dart
@@ -127,6 +130,10 @@
* **Breaking Change**: Types are now normalized. See [normalization] for the
full specification. Types will now be printed in their normal form, and
mutual subtypes with the same normal form will now be considered equal.
+* **Breaking Change**: Constructors in `@JS()` classes must be marked with
+ `external`. Previously the external could be omitted for unused constructors.
+ Omitting `external` for a constructor which is used would cause incorrect
+ behavior at runtime, now omitting it on any constructor is a static error.
[normalization]: https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@@ -140,6 +147,10 @@
* new lint: `unnecessary_string_escapes`
* incompatible rule documentation improvements
+#### Analyzer
+
+ * Removed support for the deprecated analysis options file name `.analysis_options`.
+
#### Pub
* `pub get` and `pub upgrade` now fetches version information about hosted
diff --git a/DEPS b/DEPS
index b0780a6..141a264 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
# co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
# hashes. It requires access to the dart-build-access group, which EngProd
# has.
- "co19_rev": "def1183bacc28f008db4fdd3d0442ed05f1889f8",
+ "co19_rev": "34a1386e6e7d3e27f5f2b4461aeb6f8794ab55c7",
"co19_2_rev": "368bfa9e877a2df003547f64bb17e30596af10c7",
# As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
@@ -47,7 +47,7 @@
# The list of revisions for these tools comes from Fuchsia, here:
# https://fuchsia.googlesource.com/buildtools/+/master/fuchsia.ensure
# If there are problems with the toolchain, contact fuchsia-toolchain@.
- "clang_revision": "b25fc4123c77097c05ea221e023fa5c6a16e0f41",
+ "clang_revision": "7e9747b50bcb1be28d4a3236571e8050835497a6",
"gn_revision": "239533d2d91a04b3317ca9101cf7189f4e651e4d",
# Scripts that make 'git cl format' work.
@@ -86,7 +86,7 @@
# For more details, see https://github.com/dart-lang/sdk/issues/30164
"dart_style_tag": "1.3.2", # Please see the note above before updating.
- "dartdoc_tag" : "v0.30.1",
+ "dartdoc_tag" : "v0.30.2",
"ffi_tag": "ea88d71b043ee14b268c3aedff14e9eb32e20959",
"fixnum_tag": "0.10.9",
"glob_tag": "1.1.7",
@@ -126,10 +126,10 @@
"root_certificates_rev": "16ef64be64c7dfdff2b9f4b910726e635ccc519e",
"rust_revision": "60960a260f7b5c695fd0717311d72ce62dd4eb43",
"shelf_static_rev": "v0.2.8",
- "shelf_packages_handler_tag": "1.0.4",
+ "shelf_packages_handler_tag": "2.0.0",
"shelf_tag": "0.7.3+3",
"shelf_web_socket_tag": "0.2.2+3",
- "source_map_stack_trace_tag": "1.1.5",
+ "source_map_stack_trace_tag": "2.0.0",
"source_maps-0.9.4_rev": "38524",
"source_maps_tag": "8af7cc1a1c3a193c1fba5993ce22a546a319c40e",
"source_span_tag": "1.5.5",
@@ -141,12 +141,12 @@
"test_process_tag": "1.0.3",
"term_glyph_tag": "1.0.1",
"test_reflective_loader_tag": "0.1.9",
- "test_tag": "test-v1.6.4",
+ "test_tag": "test_core-v0.3.2",
"tflite_native_rev": "3c777c40608a2a9f1427bfe0028ab48e7116b4c1",
"typed_data_tag": "1.1.6",
"unittest_rev": "2b8375bc98bb9dc81c539c91aaea6adce12e1072",
"usage_tag": "3.4.0",
- "watcher_rev": "0.9.7+13",
+ "watcher_rev": "0.9.7+14",
"web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
"web_socket_channel_tag": "1.0.9",
"WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
@@ -286,8 +286,6 @@
Var("dart_git") + "dart_style.git" + "@" + Var("dart_style_tag"),
Var("dart_root") + "/third_party/pkg/dart2js_info":
Var("dart_git") + "dart2js_info.git" + "@" + Var("dart2js_info_tag"),
- Var("dart_root") + "/third_party/pkg/args":
- Var("dart_git") + "args.git" + "@" + Var("args_tag"),
Var("dart_root") + "/third_party/pkg/dartdoc":
Var("dart_git") + "dartdoc.git" + "@" + Var("dartdoc_tag"),
Var("dart_root") + "/third_party/pkg/ffi":
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 673f2ed..60eb94d 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -229,16 +229,16 @@
/// Information tracked by [AssignedVariables] for a single node.
class AssignedVariablesNodeInfo<Variable> {
+ /// The set of local variables that are potentially written in the node.
final Set<Variable> _written = new Set<Variable>.identity();
- // The set of local variables that are potentially written in the node.
+ /// The set of local variables for which a potential write is captured by a
+ /// local function or closure inside the node.
final Set<Variable> _captured = new Set<Variable>.identity();
- // The set of local variables for which a potential write is captured by a
- // local function or closure inside the node.
+ /// The set of local variables that are declared in the node.
final Set<Variable> _declared = new Set<Variable>.identity();
- // The set of local variables that are declared in the node.
String toString() =>
'AssignedVariablesNodeInfo(_written=$_written, _captured=$_captured, '
'_declared=$_declared)';
@@ -341,6 +341,13 @@
/// ("?:"). [condition] should be the expression preceding the "?".
void conditional_thenBegin(Expression condition);
+ /// Register a declaration of the [variable] in the current state.
+ /// Should also be called for function parameters.
+ ///
+ /// A local variable is [initialized] if its declaration has an initializer.
+ /// A function parameter is always initialized, so [initialized] is `true`.
+ void declare(Variable variable, bool initialized);
+
/// Call this method before visiting the body of a "do-while" statement.
/// [doStatement] should be the same node that was passed to
/// [AssignedVariables.endNode] for the do-while statement.
@@ -494,10 +501,6 @@
/// - Call [ifStatement_end], passing `true` for `hasElse`.
void ifStatement_thenBegin(Expression condition);
- /// Register an initialized declaration of the given [variable] in the current
- /// state. Should also be called for function parameters.
- void initialize(Variable variable);
-
/// Return whether the [variable] is definitely assigned in the current state.
bool isAssigned(Variable variable);
@@ -775,6 +778,12 @@
}
@override
+ void declare(Variable variable, bool initialized) {
+ _wrap('declare($variable, $initialized)',
+ () => _wrapped.declare(variable, initialized));
+ }
+
+ @override
void doStatement_bodyBegin(Statement doStatement) {
return _wrap('doStatement_bodyBegin($doStatement)',
() => _wrapped.doStatement_bodyBegin(doStatement));
@@ -904,11 +913,6 @@
}
@override
- void initialize(Variable variable) {
- _wrap('initialize($variable)', () => _wrapped.initialize(variable));
- }
-
- @override
bool isAssigned(Variable variable) {
return _wrap('isAssigned($variable)', () => _wrapped.isAssigned(variable),
isQuery: true);
@@ -1152,20 +1156,24 @@
}());
}
+ /// Register a declaration of the [variable].
+ /// Should also be called for function parameters.
+ ///
+ /// A local variable is [initialized] if its declaration has an initializer.
+ /// A function parameter is always initialized, so [initialized] is `true`.
+ FlowModel<Variable, Type> declare(Variable variable, bool initialized) {
+ VariableModel<Type> newInfoForVar = _freshVariableInfo;
+ if (initialized) {
+ newInfoForVar = newInfoForVar.initialize();
+ }
+
+ return _updateVariableInfo(variable, newInfoForVar);
+ }
+
/// Gets the info for the given [variable], creating it if it doesn't exist.
VariableModel<Type> infoFor(Variable variable) =>
variableInfo[variable] ?? _freshVariableInfo;
- /// Updates the state to indicate that the given [variable] was initialized.
- /// The variable is marked as definitely assigned, and any previous type
- /// promotion is removed.
- FlowModel<Variable, Type> initialize(Variable variable) {
- VariableModel<Type> infoForVar = infoFor(variable);
- VariableModel<Type> newInfoForVar = infoForVar.initialize();
- if (identical(newInfoForVar, infoForVar)) return this;
- return _updateVariableInfo(variable, newInfoForVar);
- }
-
/// Updates the state to indicate that the given [writtenVariables] are no
/// longer promoted; they are presumed to have their declared types.
///
@@ -1245,28 +1253,24 @@
in variableInfo.entries) {
Variable variable = entry.key;
VariableModel<Type> thisModel = entry.value;
- VariableModel<Type> otherModel = other.infoFor(variable);
+ VariableModel<Type> otherModel = other.variableInfo[variable];
+ if (otherModel == null) {
+ variableInfoMatchesThis = false;
+ continue;
+ }
VariableModel<Type> restricted = thisModel.restrict(
typeOperations, otherModel, unsafe.contains(variable));
- if (!identical(restricted, _freshVariableInfo)) {
- newVariableInfo[variable] = restricted;
- }
+ newVariableInfo[variable] = restricted;
if (!identical(restricted, thisModel)) variableInfoMatchesThis = false;
if (!identical(restricted, otherModel)) variableInfoMatchesOther = false;
}
- for (MapEntry<Variable, VariableModel<Type>> entry
- in other.variableInfo.entries) {
- Variable variable = entry.key;
- if (variableInfo.containsKey(variable)) continue;
- VariableModel<Type> thisModel = _freshVariableInfo;
- VariableModel<Type> otherModel = entry.value;
- VariableModel<Type> restricted = thisModel.restrict(
- typeOperations, otherModel, unsafe.contains(variable));
- if (!identical(restricted, _freshVariableInfo)) {
- newVariableInfo[variable] = restricted;
+ if (variableInfoMatchesOther) {
+ for (Variable variable in other.variableInfo.keys) {
+ if (!variableInfo.containsKey(variable)) {
+ variableInfoMatchesOther = false;
+ break;
+ }
}
- if (!identical(restricted, thisModel)) variableInfoMatchesThis = false;
- if (!identical(restricted, otherModel)) variableInfoMatchesOther = false;
}
assert(variableInfoMatchesThis ==
_variableInfosEqual(newVariableInfo, variableInfo));
@@ -1347,10 +1351,13 @@
/// previous type promotion is removed.
FlowModel<Variable, Type> write(Variable variable, Type writtenType,
TypeOperations<Variable, Type> typeOperations) {
- VariableModel<Type> infoForVar = infoFor(variable);
+ VariableModel<Type> infoForVar = variableInfo[variable];
+ if (infoForVar == null) return this;
+
VariableModel<Type> newInfoForVar =
infoForVar.write(writtenType, typeOperations);
if (identical(newInfoForVar, infoForVar)) return this;
+
return _updateVariableInfo(variable, newInfoForVar);
}
@@ -2054,6 +2061,11 @@
}
@override
+ void declare(Variable variable, bool initialized) {
+ _current = _current.declare(variable, initialized);
+ }
+
+ @override
void doStatement_bodyBegin(Statement doStatement) {
AssignedVariablesNodeInfo<Variable> info =
_assignedVariables._getInfoForNode(doStatement);
@@ -2268,11 +2280,6 @@
}
@override
- void initialize(Variable variable) {
- _current = _current.initialize(variable);
- }
-
- @override
bool isAssigned(Variable variable) {
return _current.infoFor(variable).assigned;
}
@@ -2441,10 +2448,10 @@
_stack.last as _TryContext<Variable, Type>;
_current = context._beforeCatch;
if (exceptionVariable != null) {
- _current = _current.initialize(exceptionVariable);
+ _current = _current.declare(exceptionVariable, true);
}
if (stackTraceVariable != null) {
- _current = _current.initialize(stackTraceVariable);
+ _current = _current.declare(stackTraceVariable, true);
}
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index ae3f371..18cf339 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -5304,6 +5304,17 @@
tip: r"""Try replacing with a normal method.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeJsInteropNonExternalConstructor =
+ messageJsInteropNonExternalConstructor;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageJsInteropNonExternalConstructor = const MessageCode(
+ "JsInteropNonExternalConstructor",
+ message:
+ r"""JS interop classes do not support non-external constructors.""",
+ tip: r"""Try annotating with `external`.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(String name)> templateLabelNotFound = const Template<
Message Function(String name)>(
@@ -6208,7 +6219,7 @@
"NonNullableOptOut",
message: r"""Null safety features are disabled for this library.""",
tip:
- r"""Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.""");
+ r"""Try removing the `@dart=` annotation or setting the language version higher.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeNonNullableOptOutComment = messageNonNullableOptOutComment;
@@ -8682,6 +8693,16 @@
message: r"""This expression has type 'void' and can't be used.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeVoidWithTypeArguments = messageVoidWithTypeArguments;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageVoidWithTypeArguments = const MessageCode(
+ "VoidWithTypeArguments",
+ index: 100,
+ message: r"""Type 'void' can't have type arguments.""",
+ tip: r"""Try removing the type arguments.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
String string,
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
index 305c634..253b762 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -1570,6 +1570,11 @@
}
@override
+ void handleVoidKeywordWithTypeArguments(Token token) {
+ listener?.handleVoidKeywordWithTypeArguments(token);
+ }
+
+ @override
void logEvent(String name) {
listener?.logEvent(name);
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index aaa33b3..112bfe6 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -1551,6 +1551,12 @@
logEvent("VoidKeyword");
}
+ /// The parser saw a void with type arguments (e.g. void<int>).
+ /// This is not valid - an error has already been emitted.
+ void handleVoidKeywordWithTypeArguments(Token token) {
+ logEvent("handleVoidKeywordWithTypeArguments");
+ }
+
void beginYieldStatement(Token token) {}
void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
index 465402a..84964e7 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart
@@ -355,14 +355,39 @@
@override
Token parseType(Token token, Parser parser) {
- token = token.next;
- parser.listener.handleVoidKeyword(token);
+ Token voidKeyword = token = token.next;
+ bool hasTypeArguments = false;
+
+ // Recovery: Skip past, but issue problem, if followed by type arguments.
+ if (optional('<', token.next)) {
+ TypeParamOrArgInfo typeParam = computeTypeParamOrArg(token);
+ if (typeParam != noTypeParamOrArg) {
+ hasTypeArguments = true;
+ parser.reportRecoverableError(
+ token.next, codes.messageVoidWithTypeArguments);
+ token = typeParam.parseArguments(token, parser);
+ }
+ }
+ if (hasTypeArguments) {
+ parser.listener.handleVoidKeywordWithTypeArguments(voidKeyword);
+ } else {
+ // Normal case.
+ parser.listener.handleVoidKeyword(voidKeyword);
+ }
return token;
}
@override
Token skipType(Token token) {
- return token.next;
+ token = token.next;
+ // Recovery: Skip past if followed by type arguments.
+ if (optional('<', token.next)) {
+ TypeParamOrArgInfo typeParam = computeTypeParamOrArg(token);
+ if (typeParam != noTypeParamOrArg) {
+ token = typeParam.skip(token);
+ }
+ }
+ return token;
}
}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index be78085..b66c3d4 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -403,7 +403,7 @@
h.declare(y, initialized: true);
h.promote(y, 'int');
flow.for_conditionBegin(forStatement);
- flow.initialize(x);
+ flow.declare(x, true);
flow.for_bodyBegin(_Statement(), _Expression());
flow.for_updaterBegin();
flow.for_end();
@@ -697,18 +697,17 @@
test('functionExpression_begin() handles not-yet-seen variables', () {
var h = _Harness();
var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
var functionNode = _Node();
h.assignedVariables(
(vars) => vars.function(functionNode, () => vars.write(x)));
h.run((flow) {
- h.declare(y, initialized: true);
- h.promote(y, 'int');
flow.functionExpression_begin(functionNode);
flow.functionExpression_end();
+ // x is declared after the local function, so the local function
+ // cannot possibly write to x.
h.declare(x, initialized: true);
h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
+ expect(flow.promotedType(x).type, 'int');
});
});
@@ -1569,7 +1568,7 @@
h.declare(y, initialized: true);
h.promote(y, 'int');
flow.whileStatement_conditionBegin(whileStatement);
- flow.initialize(x);
+ flow.declare(x, true);
flow.whileStatement_bodyBegin(_Statement(), _Expression());
flow.whileStatement_end();
});
@@ -1789,17 +1788,27 @@
group('write', () {
var objectQVar = _Var('x', _Type('Object?'));
+
+ test('without declaration', () {
+ // This should not happen in valid code, but test that we don't crash.
+ var h = _Harness();
+ var s =
+ FlowModel<_Var, _Type>(true).write(objectQVar, _Type('Object?'), h);
+ expect(s.variableInfo[objectQVar], isNull);
+ });
+
test('unchanged', () {
var h = _Harness();
- var s1 =
- FlowModel<_Var, _Type>(true).write(objectQVar, _Type('Object?'), h);
+ var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
+ .write(objectQVar, _Type('Object?'), h);
var s2 = s1.write(objectQVar, _Type('Object?'), h);
expect(s2, same(s1));
});
test('marks as assigned', () {
var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(true);
+ var s1 = FlowModel<_Var, _Type>(true).declare(objectQVar, false);
var s2 = s1.write(objectQVar, _Type('int?'), h);
expect(s2.reachable, true);
expect(
@@ -1811,6 +1820,7 @@
test('un-promotes fully', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('int'))
.ifTrue;
@@ -1826,6 +1836,7 @@
test('un-promotes partially, when no exact match', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifTrue
@@ -1848,6 +1859,7 @@
test('un-promotes partially, when exact match', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifTrue
@@ -1874,6 +1886,7 @@
test('leaves promoted, when exact match', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifTrue
@@ -1893,6 +1906,7 @@
test('leaves promoted, when writing a subtype', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifTrue
@@ -1912,6 +1926,7 @@
test('Promotes to type of interest when not previously promoted', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifFalse;
@@ -1927,6 +1942,7 @@
test('Promotes to type of interest when previously promoted', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifTrue
@@ -1947,6 +1963,7 @@
() {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('int?'))
.ifFalse
@@ -1968,6 +1985,7 @@
() {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifFalse
@@ -1987,6 +2005,7 @@
test('Multiple candidate types of interest; ambiguous', () {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifFalse
@@ -2006,6 +2025,7 @@
() {
var h = _Harness();
var s1 = FlowModel<_Var, _Type>(true)
+ .declare(objectQVar, false)
.write(objectQVar, _Type('Object?'), h)
.tryPromote(h, objectQVar, _Type('num?'))
.ifFalse
@@ -2025,36 +2045,20 @@
});
});
- group('initialize', () {
+ group('declare', () {
var objectQVar = _Var('x', _Type('Object?'));
- test('unchanged', () {
- var s1 = FlowModel<_Var, _Type>(true).initialize(objectQVar);
- var s2 = s1.initialize(objectQVar);
- expect(s2, same(s1));
+
+ test('initialized', () {
+ var s = FlowModel<_Var, _Type>(true).declare(objectQVar, true);
+ expect(s.variableInfo, {
+ objectQVar: _matchVariableModel(assigned: true),
+ });
});
- test('marks as assigned', () {
- var s1 = FlowModel<_Var, _Type>(true);
- var s2 = s1.initialize(objectQVar);
- expect(s2.reachable, true);
- expect(
- s2.infoFor(objectQVar),
- _matchVariableModel(
- chain: null, ofInterest: isEmpty, assigned: true));
- });
-
- test('un-promotes fully', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(true)
- .initialize(objectQVar)
- .tryPromote(h, objectQVar, _Type('int'))
- .ifTrue;
- expect(s1.variableInfo, contains(objectQVar));
- var s2 = s1.initialize(objectQVar);
- expect(s2.reachable, true);
- expect(s2.variableInfo, {
- objectQVar: _matchVariableModel(
- chain: null, ofInterest: isEmpty, assigned: true)
+ test('not initialized', () {
+ var s = FlowModel<_Var, _Type>(true).declare(objectQVar, false);
+ expect(s.variableInfo, {
+ objectQVar: _matchVariableModel(assigned: false),
});
});
});
@@ -2157,7 +2161,11 @@
var b = _Var('b', _Type('int'));
var c = _Var('c', _Type('int'));
var d = _Var('d', _Type('int'));
- var s0 = FlowModel<_Var, _Type>(true);
+ var s0 = FlowModel<_Var, _Type>(true)
+ .declare(a, false)
+ .declare(b, false)
+ .declare(c, false)
+ .declare(d, false);
var s1 = s0.write(a, _Type('int'), h).write(b, _Type('int'), h);
var s2 = s0.write(a, _Type('int'), h).write(c, _Type('int'), h);
var result = s1.restrict(h, s2, Set());
@@ -2173,7 +2181,11 @@
var b = _Var('b', _Type('int'));
var c = _Var('c', _Type('int'));
var d = _Var('d', _Type('int'));
- var s0 = FlowModel<_Var, _Type>(true);
+ var s0 = FlowModel<_Var, _Type>(true)
+ .declare(a, false)
+ .declare(b, false)
+ .declare(c, false)
+ .declare(d, false);
// In s1, a and b are write captured. In s2, a and c are.
var s1 = s0.removePromotedAll([a, b], [a, b]);
var s2 = s0.removePromotedAll([a, c], [a, c]);
@@ -2189,7 +2201,9 @@
List<String> expectedChain) {
var h = _Harness();
var x = _Var('x', _Type('Object?'));
- var s0 = FlowModel<_Var, _Type>(true).write(x, _Type('Object?'), h);
+ var s0 = FlowModel<_Var, _Type>(true)
+ .declare(x, false)
+ .write(x, _Type('Object?'), h);
var s1 = thisType == null
? s0
: s0.tryPromote(h, x, _Type(thisType)).ifTrue;
@@ -2241,8 +2255,9 @@
List<String> inFinally, List<String> expectedResult) {
var h = _Harness();
var x = _Var('x', _Type('Object?'));
- var initialModel =
- FlowModel<_Var, _Type>(true).write(x, _Type('Object?'), h);
+ var initialModel = FlowModel<_Var, _Type>(true)
+ .declare(x, false)
+ .write(x, _Type('Object?'), h);
for (var t in before) {
initialModel = initialModel.tryPromote(h, x, _Type(t)).ifTrue;
}
@@ -2294,11 +2309,11 @@
var h = _Harness();
var x = _Var('x', _Type('Object?'));
var s0 = FlowModel<_Var, _Type>(true);
- var s1 = s0.write(x, _Type('Object?'), h);
- expect(s0.restrict(h, s1, {}), same(s1));
- expect(s0.restrict(h, s1, {x}), same(s1));
- expect(s1.restrict(h, s0, {}), same(s1));
- expect(s1.restrict(h, s0, {x}), same(s1));
+ var s1 = s0.declare(x, false).write(x, _Type('Object?'), h);
+ expect(s0.restrict(h, s1, {}), same(s0));
+ expect(s0.restrict(h, s1, {x}), same(s0));
+ expect(s1.restrict(h, s0, {}), same(s0));
+ expect(s1.restrict(h, s0, {x}), same(s0));
});
});
});
@@ -2850,9 +2865,7 @@
this, _assignedVariables);
void declare(_Var v, {@required bool initialized}) {
- if (initialized) {
- _flow.initialize(v);
- }
+ _flow.declare(v, initialized);
}
/// Creates a [LazyExpression] representing an `== null` check performed on
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/function_expression.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/function_expression.dart
index 6b7f51d..e44c4a7 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/function_expression.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/function_expression.dart
@@ -22,12 +22,16 @@
void isType_mutatedInclosure2() {
void g(Object x) {
if (x is String) {
- x;
+ /*String*/ x;
}
void h() {
x = 42;
}
+
+ if (x is String) {
+ x;
+ }
}
}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/inside_closure.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/inside_closure.dart
index 27821bd..56c1c1c 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/inside_closure.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/inside_closure.dart
@@ -6,9 +6,7 @@
void inner(Object x) {
if (x is String) {
f();
- // TODO(paulberry): x should be promoted here.
- // See https://github.com/dart-lang/sdk/issues/38791
- x;
+ /*String*/ x;
}
f(() {
if (x is String) {
diff --git a/pkg/_js_interop_checks/lib/js_interop_checks.dart b/pkg/_js_interop_checks/lib/js_interop_checks.dart
index 045c0d5..ef93efe 100644
--- a/pkg/_js_interop_checks/lib/js_interop_checks.dart
+++ b/pkg/_js_interop_checks/lib/js_interop_checks.dart
@@ -5,7 +5,11 @@
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:_fe_analyzer_shared/src/messages/codes.dart'
- show Message, LocatedMessage, messageJsInteropIndexNotSupported;
+ show
+ Message,
+ LocatedMessage,
+ messageJsInteropIndexNotSupported,
+ messageJsInteropNonExternalConstructor;
import 'src/js_interop.dart';
@@ -31,4 +35,15 @@
procedure.location.file);
}
}
+
+ @override
+ void visitConstructor(Constructor constructor) {
+ if (!constructor.isExternal && !constructor.isSynthetic) {
+ _diagnosticsReporter.report(
+ messageJsInteropNonExternalConstructor,
+ constructor.fileOffset,
+ constructor.name.name.length,
+ constructor.location.file);
+ }
+ }
}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 5c60bc7..a86a695 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -39,6 +39,7 @@
import 'package:analysis_server/src/plugin/plugin_watcher.dart';
import 'package:analysis_server/src/protocol_server.dart' as server;
import 'package:analysis_server/src/search/search_domain.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/server/error_notifier.dart';
@@ -167,11 +168,13 @@
ResourceProvider baseResourceProvider,
AnalysisServerOptions options,
this.sdkManager,
+ CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
this.instrumentationService, {
this.requestStatistics,
DiagnosticServer diagnosticServer,
this.detachableFileSystemManager,
- }) : super(options, diagnosticServer, baseResourceProvider) {
+ }) : super(options, diagnosticServer, crashReportingAttachmentsBuilder,
+ baseResourceProvider) {
notificationManager = NotificationManager(channel, resourceProvider);
pluginManager = PluginManager(
@@ -866,15 +869,7 @@
// TODO(scheglov) Implement notifications for AnalysisService.IMPLEMENTED.
}
});
- analysisDriver.exceptions.listen((nd.ExceptionResult result) {
- String message = 'Analysis failed: ${result.path}';
- if (result.contextKey != null) {
- message += ' context: ${result.contextKey}';
- }
- // TODO(39284): should this exception be silent?
- AnalysisEngine.instance.instrumentationService.logException(
- SilentException.wrapInMessage(message, result.exception));
- });
+ analysisDriver.exceptions.listen(analysisServer.logExceptionResult);
analysisServer.driverMap[folder] = analysisDriver;
return analysisDriver;
}
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 18ab156..f77f312 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -9,6 +9,7 @@
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/services/correction/namespace.dart';
import 'package:analysis_server/src/services/search/element_visitors.dart';
@@ -39,6 +40,9 @@
/// The options of this server instance.
AnalysisServerOptions options;
+ /// The builder for attachments that should be included into crash reports.
+ final CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder;
+
/// The [ContextManager] that handles the mapping from analysis roots to
/// context directories.
ContextManager contextManager;
@@ -78,7 +82,6 @@
'**/*.${AnalysisEngine.SUFFIX_DART}',
'**/*.${AnalysisEngine.SUFFIX_HTML}',
'**/*.${AnalysisEngine.SUFFIX_HTM}',
- '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
'**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}',
'**/${AnalysisEngine.PUBSPEC_YAML_FILE}',
'**/${AnalysisEngine.ANDROID_MANIFEST_FILE}'
@@ -94,7 +97,10 @@
/// list is lazily created and should be accessed using [analyzedFilesGlobs].
List<Glob> _analyzedFilesGlobs;
- AbstractAnalysisServer(this.options, this.diagnosticServer,
+ AbstractAnalysisServer(
+ this.options,
+ this.diagnosticServer,
+ this.crashReportingAttachmentsBuilder,
ResourceProvider baseResourceProvider)
: resourceProvider = OverlayResourceProvider(baseResourceProvider) {
performance = performanceDuringStartup;
@@ -288,6 +294,23 @@
});
}
+ void logExceptionResult(nd.ExceptionResult result) {
+ String message = 'Analysis failed: ${result.filePath}';
+ if (result.contextKey != null) {
+ message += ' context: ${result.contextKey}';
+ }
+
+ var attachments =
+ crashReportingAttachmentsBuilder.forExceptionResult(result);
+
+ // TODO(39284): should this exception be silent?
+ AnalysisEngine.instance.instrumentationService.logException(
+ SilentException.wrapInMessage(message, result.exception),
+ null,
+ attachments,
+ );
+ }
+
/// Notify the declarations tracker that the file with the given [path] was
/// changed - added, updated, or removed. Schedule processing of the file.
void notifyDeclarationsTracker(String path) {
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/README.md b/pkg/analysis_server/lib/src/edit/nnbd_migration/README.md
index 57ad179..be03e90 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/README.md
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/README.md
@@ -38,7 +38,7 @@
Then, run the migration tool from the top-level of the package directory:
```
-<sdk-repo>/xcodebuild/ReleaseX64NNBD/dart <sdk-repo>/pkg/dartdev/bin/dartdev.dart migrate .
+<sdk-repo>/xcodebuild/ReleaseX64NNBD/dart migrate .
```
The migration tool will run, print the proposed changes to the console, and
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
index c800eab..6c2468b 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
@@ -173,16 +173,6 @@
return 'The value of the expression is nullable';
}
- // Text indicating the type of nullable value found.
- String nullableValue;
- if (node is NullLiteral) {
- nullableValue = "an explicit 'null'";
- } else if (origin.kind == EdgeOriginKind.dynamicAssignment) {
- nullableValue = 'a dynamic value, which is nullable';
- } else {
- nullableValue = 'a nullable value';
- }
-
if (origin.kind == EdgeOriginKind.listLengthConstructor) {
return 'A length is specified in the "List()" constructor and the list '
'items are initialized to null';
@@ -205,6 +195,16 @@
'$lineNumber, which implicitly returns null.';
}
+ // Text indicating the type of nullable value found.
+ String nullableValue;
+ if (node is NullLiteral) {
+ nullableValue = "an explicit 'null'";
+ } else if (origin.kind == EdgeOriginKind.dynamicAssignment) {
+ nullableValue = 'a dynamic value, which is nullable';
+ } else {
+ nullableValue = 'a nullable value';
+ }
+
/// If the [node] is inside the return expression for a function body,
/// return the function body. Otherwise return `null`.
FunctionBody findFunctionBody() {
@@ -263,16 +263,19 @@
return 'This field is initialized to $nullableValue';
}
return 'This variable is initialized to $nullableValue';
- } else if (node is ConstructorDeclaration &&
- origin.kind == EdgeOriginKind.fieldNotInitialized) {
- String constructorName =
- node.declaredElement.enclosingElement.displayName;
- if (node.declaredElement.displayName.isNotEmpty) {
- constructorName =
- '$constructorName.${node.declaredElement.displayName}';
+ } else if (origin.kind == EdgeOriginKind.fieldNotInitialized) {
+ if (node is ConstructorDeclaration) {
+ String constructorName =
+ node.declaredElement.enclosingElement.displayName;
+ if (node.declaredElement.displayName.isNotEmpty) {
+ constructorName =
+ '$constructorName.${node.declaredElement.displayName}';
+ }
+ return "The constructor '$constructorName' does not initialize this "
+ 'field in its initializer list';
+ } else {
+ return 'This field is not initialized';
}
- return "The constructor '$constructorName' does not initialize this "
- 'field in its initializer list';
}
String enclosingMemberDescription = buildEnclosingMemberDescription(node);
@@ -511,6 +514,48 @@
}).toList();
}
+ TraceEntryInfo _computeTraceEntry(PropagationStepInfo step) {
+ var codeReference = step.codeReference;
+ var length = 1; // TODO(paulberry): figure out the correct value.
+ var description = step.toString(); // TODO(paulberry): improve this message.
+ return TraceEntryInfo(
+ description,
+ codeReference?.function,
+ codeReference == null
+ ? null
+ : NavigationTarget(codeReference.path, codeReference.column,
+ codeReference.line, length));
+ }
+
+ TraceInfo _computeTraceInfo(NullabilityNodeInfo node) {
+ List<TraceEntryInfo> entries = [];
+ var step = node.whyNullable;
+ while (step != null) {
+ entries.add(_computeTraceEntry(step));
+ step = step.principalCause;
+ }
+ var description = node.toString(); // TODO(paulberry): improve this message.
+ return TraceInfo(description, entries);
+ }
+
+ List<TraceInfo> _computeTraces(List<FixReasonInfo> fixReasons) {
+ var nodes = <NullabilityNodeInfo>[];
+ for (var reason in fixReasons) {
+ if (reason is NullabilityNodeInfo) {
+ if (reason.isNullable) {
+ nodes.add(reason);
+ }
+ } else if (reason is EdgeInfo) {
+ assert(reason.sourceNode.isNullable);
+ assert(!reason.destinationNode.isNullable);
+ nodes.add(reason.sourceNode);
+ } else {
+ assert(false, 'Unrecognized reason type: ${reason.runtimeType}');
+ }
+ }
+ return [for (var node in nodes) _computeTraceInfo(node)];
+ }
+
/// Compute details about [edgeInfos] which are upstream triggered.
List<RegionDetail> _computeUpstreamTriggeredDetails(
Iterable<EdgeInfo> edgeInfos) {
@@ -636,15 +681,16 @@
}
}
var lineNumber = lineInfo.getLocation(sourceOffset).lineNumber;
+ var traces = info == null ? const [] : _computeTraces(info.fixReasons);
if (explanation != null) {
if (length > 0) {
regions.add(RegionInfo(RegionType.remove, offset, length,
lineNumber, explanation, details,
- edits: edits));
+ edits: edits, traces: traces));
} else {
regions.add(RegionInfo(RegionType.add, offset, replacement.length,
lineNumber, explanation, details,
- edits: edits));
+ edits: edits, traces: traces));
}
}
offset += replacement.length;
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
index 1e20583..af22d6b 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
@@ -17,12 +17,16 @@
/// other.
final MigrationInfo migrationInfo;
+ /// Whether the migration has been applied already or not.
+ final bool hasBeenApplied;
+
/// An object used to map the file paths of analyzed files to the file paths
/// of the HTML files used to view the content of those files.
final PathMapper pathMapper;
/// Creates an output object for the given library info.
- InstrumentationRenderer(this.migrationInfo, this.pathMapper);
+ InstrumentationRenderer(
+ this.migrationInfo, this.pathMapper, this.hasBeenApplied);
/// Returns the path context used to manipulate paths.
path.Context get pathContext => migrationInfo.pathContext;
@@ -36,6 +40,7 @@
'highlightJsPath': migrationInfo.highlightJsPath,
'highlightStylePath': migrationInfo.highlightStylePath,
'sdkVersion': _dartSdkVersion,
+ 'migrationAppliedStyle': hasBeenApplied ? 'applied' : 'proposed',
};
return substituteVariables(resources.index_html, variables);
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
index ec86d89..7a86ab0 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
@@ -163,10 +163,14 @@
/// A list of the edits that are related to this range.
List<EditDetail> edits;
+ /// A list of the nullability propagation traces that are related to this
+ /// range.
+ List<TraceInfo> traces;
+
/// Initialize a newly created region.
RegionInfo(this.regionType, this.offset, this.length, this.lineNumber,
this.explanation, this.details,
- {this.edits = const []});
+ {this.edits = const [], this.traces = const []});
}
/// Different types of regions that are called out.
@@ -182,6 +186,32 @@
unchanged,
}
+/// Information about a single entry in a nullability trace.
+class TraceEntryInfo {
+ /// Text description of the entry.
+ final String description;
+
+ /// Name of the enclosing function, or `null` if not known.
+ String function;
+
+ /// Source code location associated with the entry, or `null` if no source
+ /// code location is known.
+ final NavigationTarget target;
+
+ TraceEntryInfo(this.description, this.function, this.target);
+}
+
+/// Information about a nullability trace.
+class TraceInfo {
+ /// Text description of the trace.
+ final String description;
+
+ /// List of trace entries.
+ final List<TraceEntryInfo> entries;
+
+ TraceInfo(this.description, this.entries);
+}
+
/// The migration information associated with a single compilation unit.
class UnitInfo {
/// The absolute and normalized path of the unit.
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
index cb75e9f..fc06728 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
@@ -13,6 +13,11 @@
/// The state of an NNBD migration.
class MigrationState {
+ bool _hasBeenApplied = false;
+
+ /// If the migration has been applied to disk.
+ bool get hasBeenApplied => _hasBeenApplied;
+
/// The migration associated with the state.
final NullabilityMigration migration;
@@ -40,6 +45,7 @@
/// Refresh the state of the migration after the migration has been updated.
void refresh() async {
+ assert(!hasBeenApplied);
OverlayResourceProvider provider = listener.server.resourceProvider;
InfoBuilder infoBuilder = InfoBuilder(provider, includedRoot,
instrumentationListener.data, listener, adapter, migration);
@@ -49,4 +55,10 @@
unitInfos, infoBuilder.unitMap, pathContext, includedRoot);
pathMapper = PathMapper(provider);
}
+
+ /// Mark that the migration has been applied to disk.
+ void markApplied() {
+ assert(!hasBeenApplied);
+ _hasBeenApplied = true;
+ }
}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
index 15aef10..f2de90d 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
@@ -72,6 +72,17 @@
for (var edit in region.edits) linkForEdit(edit),
]
: null,
+ traces: [
+ for (var trace in region.traces)
+ Trace(description: trace.description, entries: [
+ for (var entry in trace.entries)
+ TraceEntry(
+ description: entry.description,
+ function: entry.function,
+ link:
+ entry.target == null ? null : linkForTarget(entry.target))
+ ])
+ ],
);
return response;
}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html
index 268790b..816c805 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/index.html
@@ -7,11 +7,14 @@
<link rel="stylesheet" href="{{ highlightStylePath }}">
<style>{{ dartPageStyle }}</style>
</head>
-<body>
+<body class="{{ migrationAppliedStyle }}">
<p class="root">{{ root }}</p>
<header class="elevation-z4">
- <h1>Proposed null safety changes</h1>
+ <h1 class="before-apply">Proposed null safety changes</h1>
+ <h1 class="after-apply">✓ Null safety migration applied</h1>
<h2 id="unit-name"> </h2>
+ <button class="apply-migration before-apply">✎ Apply Migration</button>
+ <button class="apply-migration after-apply" disabled>✎ Apply Migration</button>
</header>
<div class="panels horizontal">
<div class="nav-panel">
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css
index 1731668..f31c153 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/migration.css
@@ -19,6 +19,14 @@
overflow: hidden;
}
+.proposed .after-apply {
+ display: none;
+}
+
+.applied .before-apply {
+ display: none;
+}
+
header {
background-color: #1c2834;
height: 48px;
@@ -43,6 +51,12 @@
font-size: 1.2em;
}
+header .apply-migration {
+ right: 0px;
+ float: right;
+ margin: 10px;
+}
+
footer {
color: #ccc;
background-color: #27323a;
@@ -343,7 +357,9 @@
}
.elevation-z4 {
- box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, .12);
+ box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2),
+ 0px 4px 5px 0px rgba(0, 0, 0, 0.14),
+ 0px 1px 10px 0px rgba(0, 0, 0, .12);
}
a {
@@ -357,8 +373,40 @@
fill: #fff;
}
+button {
+ background-color: #33ccff;
+ border: 2px solid #37aedc;
+ border-radius: 3px;
+ padding: 6px 10px;
+ font-weight: bold;
+ color: #282828;
+}
+
+button:hover {
+ background-color: #80dfff;
+ border: 2px solid #52b8e0;
+ cursor: pointer;
+}
+
+button[disabled] {
+ background-color: #7aa8b8;
+ color: #507177;
+ border: 2px solid #507177;
+ cursor: not-allowed;
+}
+
.placeholder {
color: #777;
text-align: center;
margin-top: 3em !important;
}
+
+/**
+ * HLJS Overrides
+ */
+.hljs {
+ /**
+ * This allows the per-line highlights to show.
+ */
+ background: none;
+}
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
index b23d392..9f81bbc 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
@@ -270,7 +270,7 @@
''';
String _index_html;
-// index_html md5 is '4b7dce061ab7cce3c431e0ad8f642b6c'
+// index_html md5 is '4ba111f269b722a6918f949e993b1238'
String _index_html_base64 = '''
PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
@@ -278,39 +278,44 @@
dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1PcGVuK1NhbnM6NDAwLDYwMCZkaXNw
bGF5PXN3YXAiPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJ7eyBoaWdobGlnaHRTdHls
ZVBhdGggfX0iPgogICAgPHN0eWxlPnt7IGRhcnRQYWdlU3R5bGUgfX08L3N0eWxlPgo8L2hlYWQ+Cjxi
-b2R5Pgo8cCBjbGFzcz0icm9vdCI+e3sgcm9vdCB9fTwvcD4KPGhlYWRlciBjbGFzcz0iZWxldmF0aW9u
-LXo0Ij4KICAgIDxoMT5Qcm9wb3NlZCBudWxsIHNhZmV0eSBjaGFuZ2VzPC9oMT4KICAgIDxoMiBpZD0i
-dW5pdC1uYW1lIj4mbmJzcDs8L2gyPgo8L2hlYWRlcj4KPGRpdiBjbGFzcz0icGFuZWxzIGhvcml6b250
-YWwiPgogICAgPGRpdiBjbGFzcz0ibmF2LXBhbmVsIj4KICAgICAgICA8ZGl2IGNsYXNzPSJuYXYtaW5u
-ZXIiPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5Qcm9qZWN0IEZpbGVzPC9k
-aXY+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9Im5hdi10cmVlIj48L2Rpdj4KICAgICAgICA8L2Rpdj48
-IS0tIC9uYXYtaW5uZXIgLS0+CiAgICA8L2Rpdj48IS0tIC9uYXYgLS0+CiAgICA8ZGl2IGNsYXNzPSJj
-b250ZW50Ij4KICAgICAgICA8ZGl2IGNsYXNzPSJyZWdpb25zIj4KICAgICAgICAgICAgPCEtLSBUaGUg
-cmVnaW9ucyBvdmVybGF5IGNvZGUgY29weSBvZiB0aGUgY29udGVudCB0byBwcm92aWRlIC0tPgogICAg
-ICAgICAgICA8IS0tIHRvb2x0aXBzIGZvciBtb2RpZmllZCByZWdpb25zLiAtLT4KICAgICAgICA8L2Rp
-dj48IS0tIC9yZWdpb25zIC0tPgogICAgICAgIDxkaXYgY2xhc3M9ImNvZGUiPgogICAgICAgICAgICA8
-IS0tIENvbXBpbGF0aW9uIHVuaXQgY29udGVudCBpcyB3cml0dGVuIGhlcmUuIC0tPgogICAgICAgICAg
-ICA8cCBjbGFzcz0id2VsY29tZSI+CiAgICAgICAgICAgICAgICBTZWxlY3QgYSBzb3VyY2UgZmlsZSBv
-biB0aGUgbGVmdCB0byBwcmV2aWV3IHRoZSBwcm9wb3NlZCBlZGl0cy4KICAgICAgICAgICAgPC9wPgog
-ICAgICAgIDwvZGl2PgogICAgPC9kaXY+PCEtLSAvY29udGVudCAtLT4KICAgIDxkaXYgY2xhc3M9Imlu
-Zm8tcGFuZWwiPgogICAgICAgIDxkaXYgY2xhc3M9ImVkaXQtbGlzdCI+CiAgICAgICAgICAgIDxkaXYg
-Y2xhc3M9InBhbmVsLWhlYWRpbmciPlByb3Bvc2VkIEVkaXRzPC9kaXY+CiAgICAgICAgICAgIDxkaXYg
-Y2xhc3M9InBhbmVsLWNvbnRlbnQiPjwvZGl2PgogICAgICAgIDwvZGl2PjwhLS0gL2VkaXQtbGlzdCAt
-LT4KICAgICAgICA8ZGl2IGNsYXNzPSJlZGl0LXBhbmVsIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0i
-cGFuZWwtaGVhZGluZyI+RWRpdCBEZXRhaWxzPC9kaXY+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InBh
-bmVsLWNvbnRlbnQiPgogICAgICAgICAgICAgICAgPHAgY2xhc3M9InBsYWNlaG9sZGVyIj5TZWUgZGV0
-YWlscyBhYm91dCBhIHByb3Bvc2VkIGVkaXQuPC9wPgogICAgICAgICAgICA8L2Rpdj48IS0tIC9wYW5l
-bC1jb250ZW50IC0tPgogICAgICAgIDwvZGl2PjwhLS0gL2VkaXQtcGFuZWwgLS0+CiAgICA8L2Rpdj48
-IS0tIC9pbmZvLXBhbmVsIC0tPgo8L2Rpdj48IS0tIC9wYW5lbHMgLS0+Cjxmb290ZXI+CiAgICA8YSB0
-YXJnZXQ9Il9ibGFuayIKICAgICAgIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9kYXJ0LWxhbmcvc2Rr
-L2Jsb2IvbWFzdGVyL3BrZy9hbmFseXNpc19zZXJ2ZXIvbGliL3NyYy9lZGl0L25uYmRfbWlncmF0aW9u
-L1JFQURNRS5tZCI+TnVsbAogICAgICAgIHNhZmV0eSBtaWdyYXRpb24gaGVscDwvYT4KICAgIDxzcGFu
-IGNsYXNzPSJ3aWRlIj4gPC9zcGFuPgogICAgPGRpdj5CYXNlZCBvbiB7eyBzZGtWZXJzaW9uIH19PC9k
-aXY+CjwvZm9vdGVyPgo8L2JvZHk+CjwvaHRtbD4K
+b2R5IGNsYXNzPSJ7eyBtaWdyYXRpb25BcHBsaWVkU3R5bGUgfX0iPgo8cCBjbGFzcz0icm9vdCI+e3sg
+cm9vdCB9fTwvcD4KPGhlYWRlciBjbGFzcz0iZWxldmF0aW9uLXo0Ij4KICAgIDxoMSBjbGFzcz0iYmVm
+b3JlLWFwcGx5Ij5Qcm9wb3NlZCBudWxsIHNhZmV0eSBjaGFuZ2VzPC9oMT4KICAgIDxoMSBjbGFzcz0i
+YWZ0ZXItYXBwbHkiPiYjMTAwMDM7IE51bGwgc2FmZXR5IG1pZ3JhdGlvbiBhcHBsaWVkPC9oMT4KICAg
+IDxoMiBpZD0idW5pdC1uYW1lIj4mbmJzcDs8L2gyPgogICAgPGJ1dHRvbiBjbGFzcz0iYXBwbHktbWln
+cmF0aW9uIGJlZm9yZS1hcHBseSI+JiM5OTk4OyBBcHBseSBNaWdyYXRpb248L2J1dHRvbj4KICAgIDxi
+dXR0b24gY2xhc3M9ImFwcGx5LW1pZ3JhdGlvbiBhZnRlci1hcHBseSIgZGlzYWJsZWQ+JiM5OTk4OyBB
+cHBseSBNaWdyYXRpb248L2J1dHRvbj4KPC9oZWFkZXI+CjxkaXYgY2xhc3M9InBhbmVscyBob3Jpem9u
+dGFsIj4KICAgIDxkaXYgY2xhc3M9Im5hdi1wYW5lbCI+CiAgICAgICAgPGRpdiBjbGFzcz0ibmF2LWlu
+bmVyIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+UHJvamVjdCBGaWxlczwv
+ZGl2PgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJuYXYtdHJlZSI+PC9kaXY+CiAgICAgICAgPC9kaXY+
+PCEtLSAvbmF2LWlubmVyIC0tPgogICAgPC9kaXY+PCEtLSAvbmF2IC0tPgogICAgPGRpdiBjbGFzcz0i
+Y29udGVudCI+CiAgICAgICAgPGRpdiBjbGFzcz0icmVnaW9ucyI+CiAgICAgICAgICAgIDwhLS0gVGhl
+IHJlZ2lvbnMgb3ZlcmxheSBjb2RlIGNvcHkgb2YgdGhlIGNvbnRlbnQgdG8gcHJvdmlkZSAtLT4KICAg
+ICAgICAgICAgPCEtLSB0b29sdGlwcyBmb3IgbW9kaWZpZWQgcmVnaW9ucy4gLS0+CiAgICAgICAgPC9k
+aXY+PCEtLSAvcmVnaW9ucyAtLT4KICAgICAgICA8ZGl2IGNsYXNzPSJjb2RlIj4KICAgICAgICAgICAg
+PCEtLSBDb21waWxhdGlvbiB1bml0IGNvbnRlbnQgaXMgd3JpdHRlbiBoZXJlLiAtLT4KICAgICAgICAg
+ICAgPHAgY2xhc3M9IndlbGNvbWUiPgogICAgICAgICAgICAgICAgU2VsZWN0IGEgc291cmNlIGZpbGUg
+b24gdGhlIGxlZnQgdG8gcHJldmlldyB0aGUgcHJvcG9zZWQgZWRpdHMuCiAgICAgICAgICAgIDwvcD4K
+ICAgICAgICA8L2Rpdj4KICAgIDwvZGl2PjwhLS0gL2NvbnRlbnQgLS0+CiAgICA8ZGl2IGNsYXNzPSJp
+bmZvLXBhbmVsIj4KICAgICAgICA8ZGl2IGNsYXNzPSJlZGl0LWxpc3QiPgogICAgICAgICAgICA8ZGl2
+IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5Qcm9wb3NlZCBFZGl0czwvZGl2PgogICAgICAgICAgICA8ZGl2
+IGNsYXNzPSJwYW5lbC1jb250ZW50Ij48L2Rpdj4KICAgICAgICA8L2Rpdj48IS0tIC9lZGl0LWxpc3Qg
+LS0+CiAgICAgICAgPGRpdiBjbGFzcz0iZWRpdC1wYW5lbCI+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9
+InBhbmVsLWhlYWRpbmciPkVkaXQgRGV0YWlsczwvZGl2PgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJw
+YW5lbC1jb250ZW50Ij4KICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJwbGFjZWhvbGRlciI+U2VlIGRl
+dGFpbHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0LjwvcD4KICAgICAgICAgICAgPC9kaXY+PCEtLSAvcGFu
+ZWwtY29udGVudCAtLT4KICAgICAgICA8L2Rpdj48IS0tIC9lZGl0LXBhbmVsIC0tPgogICAgPC9kaXY+
+PCEtLSAvaW5mby1wYW5lbCAtLT4KPC9kaXY+PCEtLSAvcGFuZWxzIC0tPgo8Zm9vdGVyPgogICAgPGEg
+dGFyZ2V0PSJfYmxhbmsiCiAgICAgICBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vZGFydC1sYW5nL3Nk
+ay9ibG9iL21hc3Rlci9wa2cvYW5hbHlzaXNfc2VydmVyL2xpYi9zcmMvZWRpdC9ubmJkX21pZ3JhdGlv
+bi9SRUFETUUubWQiPk51bGwKICAgICAgICBzYWZldHkgbWlncmF0aW9uIGhlbHA8L2E+CiAgICA8c3Bh
+biBjbGFzcz0id2lkZSI+IDwvc3Bhbj4KICAgIDxkaXY+QmFzZWQgb24ge3sgc2RrVmVyc2lvbiB9fTwv
+ZGl2Pgo8L2Zvb3Rlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==
''';
String _migration_css;
-// migration_css md5 is '3dd01166e0d763c78218c1a36155bbfb'
+// migration_css md5 is '72c8740ee7c14a4d5de701dad4ed2f13'
String _migration_css_base64 = '''
LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
@@ -320,94 +325,105 @@
dC1mYW1pbHk6ICJSb2JvdG8iLCBzYW5zLXNlcmlmOwogIGZvbnQtc2l6ZTogMTRweDsKICBkaXNwbGF5
OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRv
cDogMDsKICByaWdodDogMDsKICBib3R0b206IDA7CiAgbGVmdDogMDsKICBtYXJnaW46IDA7CiAgcGFk
-ZGluZzogMDsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgpoZWFkZXIgewogIGJhY2tncm91bmQtY29sb3I6
-ICMxYzI4MzQ7CiAgaGVpZ2h0OiA0OHB4OwogIHBhZGRpbmctbGVmdDogMjRweDsKICBhbGlnbi1pdGVt
-czogY2VudGVyOwogIHotaW5kZXg6IDQ7Cn0KCmhlYWRlciBoMSwKaGVhZGVyIGgyIHsKICBkaXNwbGF5
-OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1mYW1pbHk6ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1z
-ZXJpZjsKICBmb250LXdlaWdodDogNDAwOwogIG1hcmdpbi1yaWdodDogMjRweDsKfQoKaDEgewogIGZv
-bnQtc2l6ZTogMS41ZW07Cn0KCmhlYWRlciBoMiB7CiAgZm9udC1zaXplOiAxLjJlbTsKfQoKZm9vdGVy
-IHsKICBjb2xvcjogI2NjYzsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjczMjNhOwogIGRpc3BsYXk6IGZs
-ZXg7CiAgZmxleC1kaXJlY3Rpb246IHJvdzsKICBhbGlnbi1pdGVtczogY2VudGVyOwogIHBhZGRpbmc6
-IDhweCAyNHB4Owp9Cgpmb290ZXIgLndpZGUgewogIGZsZXg6IDE7Cn0KCi5ob3Jpem9udGFsIHsKICBk
-aXNwbGF5OiBmbGV4Owp9CgoucGFuZWxzIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTIxYTI1OwogIGZs
-ZXg6IDE7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKfQoKLnBhbmVsLWhlYWRpbmcgewogIGNvbG9yOiBncmF5
-OwogIG1hcmdpbjogOHB4Owp9CgoubmF2LWxpbmssCi5yZWdpb24gewogIGN1cnNvcjogcG9pbnRlcjsK
-fQoKLm5hdi1wYW5lbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzI4MmIyZTsKICBmbGV4OiAxIDIwMHB4
-OwogIG1hcmdpbjogMDsKICBvdmVyZmxvdzogc2Nyb2xsOwp9CgoubmF2LWlubmVyIHsKICBwYWRkaW5n
-OiAwIDAgN3B4IDdweDsKfQoKLmZpeGVkIHsKICBwb3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAwOwp9Cgou
-cm9vdCB7CiAgbWFyZ2luOiAwOwogIGRpc3BsYXk6IG5vbmU7Cn0KCi5uYXYtdHJlZSA+IHVsIHsKICBw
-YWRkaW5nLWxlZnQ6IDZweDsKfQoKLm5hdi1pbm5lciB1bCB7CiAgcGFkZGluZy1sZWZ0OiAxMnB4Owog
-IG1hcmdpbjogMDsKfQoKLm5hdi1pbm5lciBsaSB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwp9Cgou
-bmF2LWlubmVyIGxpOm5vdCguZGlyKSB7CiAgbWFyZ2luLWxlZnQ6IDIwcHg7CiAgbWFyZ2luLWJvdHRv
-bTogM3B4Owp9CgoubmF2LWlubmVyIGxpLmRpciAuYXJyb3cgewogIGN1cnNvcjogcG9pbnRlcjsKICBk
-aXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1zaXplOiAxMHB4OwogIG1hcmdpbi1yaWdodDogNHB4
-OwogIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjVzIGVhc2Utb3V0Owp9CgoubmF2LWlubmVyIGxpLmRp
-ciAuYXJyb3cuY29sbGFwc2VkIHsKICB0cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpOwp9CgoubmF2LWlu
-bmVyIHVsIHsKICBtYXgtaGVpZ2h0OiAyMDAwcHg7CiAgdHJhbnNpdGlvbjogbWF4LWhlaWdodCAwLjVz
-IGVhc2Utb3V0Owp9CgoubmF2LWlubmVyIHVsLmNvbGxhcHNlZCB7CiAgbWF4LWhlaWdodDogMCAhaW1w
-b3J0YW50OwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5uYXYtaW5uZXIgLnNlbGVjdGVkLWZpbGUgewog
-IGNvbG9yOiB3aGl0ZTsKICBjdXJzb3I6IGluaGVyaXQ7CiAgZm9udC13ZWlnaHQ6IDYwMDsKICB0ZXh0
-LWRlY29yYXRpb246IG5vbmU7Cn0KCi5lZGl0LWNvdW50IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzdh
-ZWRjOwogIGJvcmRlci1yYWRpdXM6IDEwcHg7CiAgY29sb3I6ICMwMDAwMDA7CiAgZGlzcGxheTogaW5s
-aW5lLWJsb2NrOwogIGZvbnQtc2l6ZTogMTFweDsKICBmb250LXdlaWdodDogNjAwOwogIG1hcmdpbi1s
-ZWZ0OiA1cHg7CiAgbWluLXdpZHRoOiAyNXB4OwogIHBhZGRpbmc6IDRweCAwIDJweCAwOwogIHRleHQt
-YWxpZ246IGNlbnRlcjsKICBsaW5lLWhlaWdodDogMWVtOwp9CgouY29udGVudCB7CiAgZmxleDogNCAz
-MDBweDsKICBiYWNrZ3JvdW5kOiAjMjgyYjJlOwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAgbWFy
-Z2luOiAwIDZweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgd2hpdGUtc3BhY2U6IHByZTsKICBvdmVy
-Zmxvdzogc2Nyb2xsOwp9CgouY29kZSB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29s
-dXRlOwogIGxlZnQ6IDA7CiAgdG9wOiAwOwogIG1hcmdpbi1sZWZ0OiA1NnB4Owp9CgouaGxqcyB7CiAg
-YmFja2dyb3VuZC1jb2xvcjogIzI4MmIyZTsKICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14OiBh
-dXRvOwogIHBhZGRpbmc6IDAuNWVtOwp9CgouY29kZSAud2VsY29tZSB7CiAgZm9udC1mYW1pbHk6ICJH
-b29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXNpemU6IDE4cHg7CiAgbWFyZ2lu
-LXJpZ2h0OiA2MnB4OwogIGNvbG9yOiAjNzc3Owp9CgouY29kZSAubmF2LWxpbmsgewogIGNvbG9yOiBp
-bmhlcml0OwogIHRleHQtZGVjb3JhdGlvbi1saW5lOiBub25lOwp9CgouY29kZSAubmF2LWxpbms6dmlz
-aXRlZCB7CiAgY29sb3I6IGluaGVyaXQ7CiAgdGV4dC1kZWNvcmF0aW9uLWxpbmU6IG5vbmU7Cn0KCi5j
-b2RlIC5uYXYtbGluazpob3ZlciB7CiAgdGV4dC1kZWNvcmF0aW9uLWxpbmU6IHVuZGVybGluZTsKICBm
-b250LXdlaWdodDogNjAwOwp9CgoucmVnaW9ucyB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246
-IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9wOiAwOwp9CgoucmVnaW9ucyB0YWJsZSB7CiAgYm9yZGVy
-LXNwYWNpbmc6IDA7CiAgZm9udC1zaXplOiBpbmhlcml0Owp9CgoucmVnaW9ucyB0ZCB7CiAgYm9yZGVy
-OiBub25lOwogIC8qIFRoZSBjb250ZW50IG9mIHRoZSByZWdpb25zIGlzIG5vdCB2aXNpYmxlOyB0aGUg
-dXNlciBpbnN0ZWFkIHdpbGwgc2VlIHRoZQogICAqIGhpZ2hsaWdodGVkIGNvcHkgb2YgdGhlIGNvbnRl
-bnQuICovCiAgY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMCk7CiAgcGFkZGluZzogMDsKICB3aGl0
-ZS1zcGFjZTogcHJlOwp9CgoucmVnaW9ucyB0ZDplbXB0eTphZnRlciB7CiAgY29udGVudDogIlwwMGEw
-IjsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkOmxhc3QtY2hpbGQgewogIGJhY2tncm91bmQtY29s
-b3I6ICM0NDQ0NDQ7CiAgY29sb3I6IHdoaXRlOwp9CgoucmVnaW9ucyB0ZC5saW5lLW5vIHsKICBib3Jk
-ZXItcmlnaHQ6IHNvbGlkICMyODJiMmUgMnB4OwogIGNvbG9yOiAjOTk5OTk5OwogIHBhZGRpbmctcmln
-aHQ6IDRweDsKICB0ZXh0LWFsaWduOiByaWdodDsKICB2aXNpYmlsaXR5OiB2aXNpYmxlOwogIHdpZHRo
-OiA1MHB4OwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRk
-LmxpbmUtbm8gewogIGJvcmRlci1yaWdodDogc29saWQgI2NjYyAycHg7Cn0KCi5yZWdpb24gewogIGRp
-c3BsYXk6IGlubGluZS1ibG9jazsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlz
-aWJsZTsKICB6LWluZGV4OiAyMDA7Cn0KCi5yZWdpb24uYWRkZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5k
-LWNvbG9yOiAjY2NmZmNjOwogIGNvbG9yOiAjMDAzMzAwOwp9CgoucmVnaW9uLnJlbW92ZWQtcmVnaW9u
-IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmY2NjY2OwogIGNvbG9yOiAjMDAxMTAwOwp9CgoucmVnaW9u
-LnVuY2hhbmdlZC1yZWdpb24gewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC4zKTsK
-ICBib3JkZXItYm90dG9tOiBzb2xpZCAycHggI2NjYzsKICAvKiBJbnZpc2libGUgdGV4dDsgdXNlIHVu
-ZGVybHlpbmcgaGlnaGxpZ2h0aW5nLiAqLwogIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDApOwogIC8qIFJl
-ZHVjZSBsaW5lIGhlaWdodCB0byBtYWtlIHJvb20gZm9yIGJvcmRlci4gKi8KICBsaW5lLWhlaWdodDog
-MTsKfQoKLnRhcmdldCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzQ0NDsKICBwb3NpdGlvbjogcmVsYXRp
-dmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICBmb250LXdlaWdodDogNjAwOwp9CgouaW5mby1wYW5l
-bCB7CiAgZmxleDogMSAyMDBweDsKICBtYXJnaW46IDA7CiAgaGVpZ2h0OiAxMDAlOwogIGRpc3BsYXk6
-IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsKfQoKLmluZm8tcGFuZWwgLmVkaXQtcGFuZWwg
-ewogIGJhY2tncm91bmQtY29sb3I6ICMyODJiMmU7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5pbmZvLXBh
-bmVsIC5wYW5lbC1jb250ZW50IHsKICBwYWRkaW5nOiA3cHg7Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1j
-b250ZW50PiA6Zmlyc3QtY2hpbGQgewogIG1hcmdpbi10b3A6IDA7Cn0KCi5pbmZvLXBhbmVsIC5ub3dy
-YXAgewogIHdoaXRlLXNwYWNlOiBub3dyYXA7Cn0KCi5pbmZvLXBhbmVsIHVsLAouaW5mby1wYW5lbCBv
-bCB7CiAgcGFkZGluZy1sZWZ0OiAyMHB4Owp9CgouaW5mby1wYW5lbCBsaSB7CiAgbWFyZ2luOiAwIDAg
-NXB4IDA7Cn0KCi5pbmZvLXBhbmVsIGEgewogIGNvbG9yOiAjMzNjY2ZmOwp9CgouaW5mby1wYW5lbCAu
-ZWRpdC1saXN0IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjgyYjJlOwogIG92ZXJmbG93OiBhdXRvOwp9
-CgouZWRpdC1wYW5lbCB7CiAgbWFyZ2luLXRvcDogNnB4OwogIGZsZXg6IDEgMTAwcHg7Cn0KCi5lZGl0
-LWxpc3QgewogIGZsZXg6IDIgMTAwcHg7Cn0KCi5lZGl0LWxpc3QgLmVkaXQgewogIG1hcmdpbjogM3B4
-IDA7Cn0KCi5lZGl0LWxpc3QgLmVkaXQtbGluayB7CiAgY3Vyc29yOiBwb2ludGVyOwp9CgouZWxldmF0
-aW9uLXo0IHsKICBib3gtc2hhZG93OiAwcHggMnB4IDRweCAtMXB4IHJnYmEoMCwgMCwgMCwgMC4yKSwg
-MHB4IDRweCA1cHggMHB4IHJnYmEoMCwgMCwgMCwgMC4xNCksIDBweCAxcHggMTBweCAwcHggcmdiYSgw
-LCAwLCAwLCAuMTIpOwp9CgphIHsKICBjb2xvcjogI2NjYzsKICBmaWxsOiAjY2NjOwogIHRleHQtZGVj
-b3JhdGlvbjogbm9uZTsKfQoKYTpob3ZlciB7CiAgY29sb3I6ICNmZmY7CiAgZmlsbDogI2ZmZjsKfQoK
-LnBsYWNlaG9sZGVyIHsKICBjb2xvcjogIzc3NzsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbWFyZ2lu
-LXRvcDogM2VtICFpbXBvcnRhbnQ7Cn0K
+ZGluZzogMDsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoucHJvcG9zZWQgLmFmdGVyLWFwcGx5IHsKICBk
+aXNwbGF5OiBub25lOwp9CgouYXBwbGllZCAuYmVmb3JlLWFwcGx5IHsKICBkaXNwbGF5OiBub25lOwp9
+CgpoZWFkZXIgewogIGJhY2tncm91bmQtY29sb3I6ICMxYzI4MzQ7CiAgaGVpZ2h0OiA0OHB4OwogIHBh
+ZGRpbmctbGVmdDogMjRweDsKICBhbGlnbi1pdGVtczogY2VudGVyOwogIHotaW5kZXg6IDQ7Cn0KCmhl
+YWRlciBoMSwKaGVhZGVyIGgyIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1mYW1pbHk6
+ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXdlaWdodDogNDAwOwogIG1h
+cmdpbi1yaWdodDogMjRweDsKfQoKaDEgewogIGZvbnQtc2l6ZTogMS41ZW07Cn0KCmhlYWRlciBoMiB7
+CiAgZm9udC1zaXplOiAxLjJlbTsKfQoKaGVhZGVyIC5hcHBseS1taWdyYXRpb24gewogIHJpZ2h0OiAw
+cHg7CiAgZmxvYXQ6IHJpZ2h0OwogIG1hcmdpbjogMTBweDsKfQoKZm9vdGVyIHsKICBjb2xvcjogI2Nj
+YzsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjczMjNhOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJl
+Y3Rpb246IHJvdzsKICBhbGlnbi1pdGVtczogY2VudGVyOwogIHBhZGRpbmc6IDhweCAyNHB4Owp9Cgpm
+b290ZXIgLndpZGUgewogIGZsZXg6IDE7Cn0KCi5ob3Jpem9udGFsIHsKICBkaXNwbGF5OiBmbGV4Owp9
+CgoucGFuZWxzIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTIxYTI1OwogIGZsZXg6IDE7CiAgb3ZlcmZs
+b3c6IGhpZGRlbjsKfQoKLnBhbmVsLWhlYWRpbmcgewogIGNvbG9yOiBncmF5OwogIG1hcmdpbjogOHB4
+Owp9CgoubmF2LWxpbmssCi5yZWdpb24gewogIGN1cnNvcjogcG9pbnRlcjsKfQoKLm5hdi1wYW5lbCB7
+CiAgYmFja2dyb3VuZC1jb2xvcjogIzI4MmIyZTsKICBmbGV4OiAxIDIwMHB4OwogIG1hcmdpbjogMDsK
+ICBvdmVyZmxvdzogc2Nyb2xsOwp9CgoubmF2LWlubmVyIHsKICBwYWRkaW5nOiAwIDAgN3B4IDdweDsK
+fQoKLmZpeGVkIHsKICBwb3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAwOwp9Cgoucm9vdCB7CiAgbWFyZ2lu
+OiAwOwogIGRpc3BsYXk6IG5vbmU7Cn0KCi5uYXYtdHJlZSA+IHVsIHsKICBwYWRkaW5nLWxlZnQ6IDZw
+eDsKfQoKLm5hdi1pbm5lciB1bCB7CiAgcGFkZGluZy1sZWZ0OiAxMnB4OwogIG1hcmdpbjogMDsKfQoK
+Lm5hdi1pbm5lciBsaSB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwp9CgoubmF2LWlubmVyIGxpOm5v
+dCguZGlyKSB7CiAgbWFyZ2luLWxlZnQ6IDIwcHg7CiAgbWFyZ2luLWJvdHRvbTogM3B4Owp9CgoubmF2
+LWlubmVyIGxpLmRpciAuYXJyb3cgewogIGN1cnNvcjogcG9pbnRlcjsKICBkaXNwbGF5OiBpbmxpbmUt
+YmxvY2s7CiAgZm9udC1zaXplOiAxMHB4OwogIG1hcmdpbi1yaWdodDogNHB4OwogIHRyYW5zaXRpb246
+IHRyYW5zZm9ybSAwLjVzIGVhc2Utb3V0Owp9CgoubmF2LWlubmVyIGxpLmRpciAuYXJyb3cuY29sbGFw
+c2VkIHsKICB0cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpOwp9CgoubmF2LWlubmVyIHVsIHsKICBtYXgt
+aGVpZ2h0OiAyMDAwcHg7CiAgdHJhbnNpdGlvbjogbWF4LWhlaWdodCAwLjVzIGVhc2Utb3V0Owp9Cgou
+bmF2LWlubmVyIHVsLmNvbGxhcHNlZCB7CiAgbWF4LWhlaWdodDogMCAhaW1wb3J0YW50OwogIG92ZXJm
+bG93OiBoaWRkZW47Cn0KCi5uYXYtaW5uZXIgLnNlbGVjdGVkLWZpbGUgewogIGNvbG9yOiB3aGl0ZTsK
+ICBjdXJzb3I6IGluaGVyaXQ7CiAgZm9udC13ZWlnaHQ6IDYwMDsKICB0ZXh0LWRlY29yYXRpb246IG5v
+bmU7Cn0KCi5lZGl0LWNvdW50IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzdhZWRjOwogIGJvcmRlci1y
+YWRpdXM6IDEwcHg7CiAgY29sb3I6ICMwMDAwMDA7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIGZv
+bnQtc2l6ZTogMTFweDsKICBmb250LXdlaWdodDogNjAwOwogIG1hcmdpbi1sZWZ0OiA1cHg7CiAgbWlu
+LXdpZHRoOiAyNXB4OwogIHBhZGRpbmc6IDRweCAwIDJweCAwOwogIHRleHQtYWxpZ246IGNlbnRlcjsK
+ICBsaW5lLWhlaWdodDogMWVtOwp9CgouY29udGVudCB7CiAgZmxleDogNCAzMDBweDsKICBiYWNrZ3Jv
+dW5kOiAjMjgyYjJlOwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAgbWFyZ2luOiAwIDZweDsKICBw
+b3NpdGlvbjogcmVsYXRpdmU7CiAgd2hpdGUtc3BhY2U6IHByZTsKICBvdmVyZmxvdzogc2Nyb2xsOwp9
+CgouY29kZSB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7
+CiAgdG9wOiAwOwogIG1hcmdpbi1sZWZ0OiA1NnB4Owp9CgouaGxqcyB7CiAgYmFja2dyb3VuZC1jb2xv
+cjogIzI4MmIyZTsKICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14OiBhdXRvOwogIHBhZGRpbmc6
+IDAuNWVtOwp9CgouY29kZSAud2VsY29tZSB7CiAgZm9udC1mYW1pbHk6ICJHb29nbGUgU2FucyIsIlJv
+Ym90byIsc2Fucy1zZXJpZjsKICBmb250LXNpemU6IDE4cHg7CiAgbWFyZ2luLXJpZ2h0OiA2MnB4Owog
+IGNvbG9yOiAjNzc3Owp9CgouY29kZSAubmF2LWxpbmsgewogIGNvbG9yOiBpbmhlcml0OwogIHRleHQt
+ZGVjb3JhdGlvbi1saW5lOiBub25lOwp9CgouY29kZSAubmF2LWxpbms6dmlzaXRlZCB7CiAgY29sb3I6
+IGluaGVyaXQ7CiAgdGV4dC1kZWNvcmF0aW9uLWxpbmU6IG5vbmU7Cn0KCi5jb2RlIC5uYXYtbGluazpo
+b3ZlciB7CiAgdGV4dC1kZWNvcmF0aW9uLWxpbmU6IHVuZGVybGluZTsKICBmb250LXdlaWdodDogNjAw
+Owp9CgoucmVnaW9ucyB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxl
+ZnQ6IDA7CiAgdG9wOiAwOwp9CgoucmVnaW9ucyB0YWJsZSB7CiAgYm9yZGVyLXNwYWNpbmc6IDA7CiAg
+Zm9udC1zaXplOiBpbmhlcml0Owp9CgoucmVnaW9ucyB0ZCB7CiAgYm9yZGVyOiBub25lOwogIC8qIFRo
+ZSBjb250ZW50IG9mIHRoZSByZWdpb25zIGlzIG5vdCB2aXNpYmxlOyB0aGUgdXNlciBpbnN0ZWFkIHdp
+bGwgc2VlIHRoZQogICAqIGhpZ2hsaWdodGVkIGNvcHkgb2YgdGhlIGNvbnRlbnQuICovCiAgY29sb3I6
+IHJnYmEoMjU1LCAyNTUsIDI1NSwgMCk7CiAgcGFkZGluZzogMDsKICB3aGl0ZS1zcGFjZTogcHJlOwp9
+CgoucmVnaW9ucyB0ZDplbXB0eTphZnRlciB7CiAgY29udGVudDogIlwwMGEwIjsKfQoKLnJlZ2lvbnMg
+dHIuaGlnaGxpZ2h0IHRkOmxhc3QtY2hpbGQgewogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ0NDQ7CiAg
+Y29sb3I6IHdoaXRlOwp9CgoucmVnaW9ucyB0ZC5saW5lLW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlk
+ICMyODJiMmUgMnB4OwogIGNvbG9yOiAjOTk5OTk5OwogIHBhZGRpbmctcmlnaHQ6IDRweDsKICB0ZXh0
+LWFsaWduOiByaWdodDsKICB2aXNpYmlsaXR5OiB2aXNpYmxlOwogIHdpZHRoOiA1MHB4OwogIGRpc3Bs
+YXk6IGlubGluZS1ibG9jazsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkLmxpbmUtbm8gewogIGJv
+cmRlci1yaWdodDogc29saWQgI2NjYyAycHg7Cn0KCi5yZWdpb24gewogIGRpc3BsYXk6IGlubGluZS1i
+bG9jazsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICB6LWluZGV4
+OiAyMDA7Cn0KCi5yZWdpb24uYWRkZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjY2NmZmNj
+OwogIGNvbG9yOiAjMDAzMzAwOwp9CgoucmVnaW9uLnJlbW92ZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5k
+LWNvbG9yOiAjZmY2NjY2OwogIGNvbG9yOiAjMDAxMTAwOwp9CgoucmVnaW9uLnVuY2hhbmdlZC1yZWdp
+b24gewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC4zKTsKICBib3JkZXItYm90dG9t
+OiBzb2xpZCAycHggI2NjYzsKICAvKiBJbnZpc2libGUgdGV4dDsgdXNlIHVuZGVybHlpbmcgaGlnaGxp
+Z2h0aW5nLiAqLwogIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDApOwogIC8qIFJlZHVjZSBsaW5lIGhlaWdo
+dCB0byBtYWtlIHJvb20gZm9yIGJvcmRlci4gKi8KICBsaW5lLWhlaWdodDogMTsKfQoKLnRhcmdldCB7
+CiAgYmFja2dyb3VuZC1jb2xvcjogIzQ0NDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0
+eTogdmlzaWJsZTsKICBmb250LXdlaWdodDogNjAwOwp9CgouaW5mby1wYW5lbCB7CiAgZmxleDogMSAy
+MDBweDsKICBtYXJnaW46IDA7CiAgaGVpZ2h0OiAxMDAlOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1k
+aXJlY3Rpb246IGNvbHVtbjsKfQoKLmluZm8tcGFuZWwgLmVkaXQtcGFuZWwgewogIGJhY2tncm91bmQt
+Y29sb3I6ICMyODJiMmU7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250
+ZW50IHsKICBwYWRkaW5nOiA3cHg7Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50PiA6Zmlyc3Qt
+Y2hpbGQgewogIG1hcmdpbi10b3A6IDA7Cn0KCi5pbmZvLXBhbmVsIC5ub3dyYXAgewogIHdoaXRlLXNw
+YWNlOiBub3dyYXA7Cn0KCi5pbmZvLXBhbmVsIHVsLAouaW5mby1wYW5lbCBvbCB7CiAgcGFkZGluZy1s
+ZWZ0OiAyMHB4Owp9CgouaW5mby1wYW5lbCBsaSB7CiAgbWFyZ2luOiAwIDAgNXB4IDA7Cn0KCi5pbmZv
+LXBhbmVsIGEgewogIGNvbG9yOiAjMzNjY2ZmOwp9CgouaW5mby1wYW5lbCAuZWRpdC1saXN0IHsKICBi
+YWNrZ3JvdW5kLWNvbG9yOiAjMjgyYjJlOwogIG92ZXJmbG93OiBhdXRvOwp9CgouZWRpdC1wYW5lbCB7
+CiAgbWFyZ2luLXRvcDogNnB4OwogIGZsZXg6IDEgMTAwcHg7Cn0KCi5lZGl0LWxpc3QgewogIGZsZXg6
+IDIgMTAwcHg7Cn0KCi5lZGl0LWxpc3QgLmVkaXQgewogIG1hcmdpbjogM3B4IDA7Cn0KCi5lZGl0LWxp
+c3QgLmVkaXQtbGluayB7CiAgY3Vyc29yOiBwb2ludGVyOwp9CgouZWxldmF0aW9uLXo0IHsKICBib3gt
+c2hhZG93OiAwcHggMnB4IDRweCAtMXB4IHJnYmEoMCwgMCwgMCwgMC4yKSwKICAgICAgMHB4IDRweCA1
+cHggMHB4IHJnYmEoMCwgMCwgMCwgMC4xNCksCiAgICAgIDBweCAxcHggMTBweCAwcHggcmdiYSgwLCAw
+LCAwLCAuMTIpOwp9CgphIHsKICBjb2xvcjogI2NjYzsKICBmaWxsOiAjY2NjOwogIHRleHQtZGVjb3Jh
+dGlvbjogbm9uZTsKfQoKYTpob3ZlciB7CiAgY29sb3I6ICNmZmY7CiAgZmlsbDogI2ZmZjsKfQoKYnV0
+dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzNjY2ZmOwogIGJvcmRlcjogMnB4IHNvbGlkICMzN2Fl
+ZGM7CiAgYm9yZGVyLXJhZGl1czogM3B4OwogIHBhZGRpbmc6IDZweCAxMHB4OwogIGZvbnQtd2VpZ2h0
+OiBib2xkOwogIGNvbG9yOiAjMjgyODI4Owp9CgpidXR0b246aG92ZXIgewogIGJhY2tncm91bmQtY29s
+b3I6ICM4MGRmZmY7CiAgYm9yZGVyOiAycHggc29saWQgIzUyYjhlMDsKICBjdXJzb3I6IHBvaW50ZXI7
+Cn0KCmJ1dHRvbltkaXNhYmxlZF0gewogIGJhY2tncm91bmQtY29sb3I6ICM3YWE4Yjg7CiAgY29sb3I6
+ICM1MDcxNzc7CiAgYm9yZGVyOiAycHggc29saWQgIzUwNzE3NzsKICBjdXJzb3I6IG5vdC1hbGxvd2Vk
+Owp9CgoucGxhY2Vob2xkZXIgewogIGNvbG9yOiAjNzc3OwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBt
+YXJnaW4tdG9wOiAzZW0gIWltcG9ydGFudDsKfQoKLyoqCiAqIEhMSlMgT3ZlcnJpZGVzCiAqLwouaGxq
+cyB7CiAgLyoqCiAgICogVGhpcyBhbGxvd3MgdGhlIHBlci1saW5lIGhpZ2hsaWdodHMgdG8gc2hvdy4K
+ICAgKi8KICBiYWNrZ3JvdW5kOiBub25lOwp9
''';
String _migration_js;
-// migration_dart md5 is '92e41b045d06e490bbc16aff5920468f'
+// migration_dart md5 is 'fc62e2786d8e19ca0ecf5d3110278b11'
String _migration_js_base64 = '''
KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
@@ -1135,7 +1151,7 @@
PWMuYwpkLmE9Ywpjb250aW51ZX1lbHNlIFAuQTkoYyxrKQpyZXR1cm59fWY9Yi5iCmc9cy5iKGYuYykK
Zi5jPW51bGwKYj1mLk44KGcpCmM9cS5hCmw9cS5iCmlmKCFjKXtmLiR0aS5kLmIobCkKZi5hPTQKZi5j
PWx9ZWxzZXt0LmIobCkKZi5hPTgKZi5jPWx9ZC5hPWYKYz1mfX0sClZIOmZ1bmN0aW9uKGEsYil7dmFy
-IHQ9dS53CmlmKHQuYyhhKSlyZXR1cm4gdC5iKGEpCnQ9dS55CmlmKHQuYyhhKSlyZXR1cm4gdC5iKGEp
+IHQ9dS5XCmlmKHQuYyhhKSlyZXR1cm4gdC5iKGEpCnQ9dS55CmlmKHQuYyhhKSlyZXR1cm4gdC5iKGEp
CnRocm93IEguYihQLkwzKGEsIm9uRXJyb3IiLCJFcnJvciBoYW5kbGVyIG11c3QgYWNjZXB0IG9uZSBP
YmplY3Qgb3Igb25lIE9iamVjdCBhbmQgYSBTdGFja1RyYWNlIGFzIGFyZ3VtZW50cywgYW5kIHJldHVy
biBhIGEgdmFsaWQgcmVzdWx0IikpfSwKcHU6ZnVuY3Rpb24oKXt2YXIgdCxzCmZvcig7dD0kLlM2LHQh
@@ -1593,7 +1609,8 @@
dW5jdGlvbiBpSigpe30sCmxSOmZ1bmN0aW9uIGxSKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApqZzpm
dW5jdGlvbiBqZyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQmY6ZnVuY3Rpb24gQmYoYSxiKXt0aGlz
LmE9YQp0aGlzLmI9Yn0sCkFzOmZ1bmN0aW9uIEFzKCl7fSwKR0U6ZnVuY3Rpb24gR0UoYSl7dGhpcy5h
-PWF9LApoRjpmdW5jdGlvbiBoRigpe30sClI0OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgpILnhk
+PWF9LApONzpmdW5jdGlvbiBONyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdVE6ZnVuY3Rpb24gdVEo
+KXt9LApoRjpmdW5jdGlvbiBoRigpe30sClI0OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgpILnhk
KGIpCnUuai5iKGQpCmlmKEgub1QoYikpe3Q9W2NdCkMuTm0uRlYodCxkKQpkPXR9cz11LnoKcj1QLkNI
KEouTTEoZCxQLncwKCkscyksITAscykKdS5aLmIoYSkKcmV0dXJuIFAud1koSC5FayhhLHIsbnVsbCkp
fSwKRG06ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnRyeXtpZihPYmplY3QuaXNFeHRlbnNpYmxlKGEpJiYh
@@ -1602,14 +1619,14 @@
OmZ1bmN0aW9uKGEsYil7aWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYikp
cmV0dXJuIGFbYl0KcmV0dXJufSwKd1k6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbHx8dHlwZW9mIGE9PSJz
dHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8fEgubChhKSlyZXR1cm4gYQppZihhIGluc3RhbmNlb2Yg
-UC5FNClyZXR1cm4gYS5hCmlmKEguUjkoYSkpcmV0dXJuIGEKaWYodS51LmMoYSkpcmV0dXJuIGEKaWYo
+UC5FNClyZXR1cm4gYS5hCmlmKEguUjkoYSkpcmV0dXJuIGEKaWYodS52LmMoYSkpcmV0dXJuIGEKaWYo
YSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIEgubzIoYSkKaWYodS5aLmMoYSkpcmV0dXJuIFAuaEUoYSwi
JGRhcnRfanNGdW5jdGlvbiIsbmV3IFAuUEMoKSkKcmV0dXJuIFAuaEUoYSwiXyRkYXJ0X2pzT2JqZWN0
IixuZXcgUC5ZbSgkLmtJKCkpKX0sCmhFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1QLk9tKGEsYikKaWYo
dD09bnVsbCl7dD1jLiQxKGEpClAuRG0oYSxiLHQpfXJldHVybiB0fSwKTDc6ZnVuY3Rpb24oYSl7dmFy
IHQscwppZihhPT1udWxsfHx0eXBlb2YgYT09InN0cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8dHlw
ZW9mIGE9PSJib29sZWFuIilyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJkguUjko
-YSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZ1LnUuYyhhKSlyZXR1cm4gYQpl
+YSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZ1LnYuYyhhKSlyZXR1cm4gYQpl
bHNlIGlmKGEgaW5zdGFuY2VvZiBEYXRlKXt0PUguU2MoYS5nZXRUaW1lKCkpCmlmKE1hdGguYWJzKHQp
PD04NjRlMTMpcz0hMQplbHNlIHM9ITAKaWYocylILnZoKFAueFkoIkRhdGVUaW1lIGlzIG91dHNpZGUg
dmFsaWQgcmFuZ2U6ICIrdCkpCnJldHVybiBuZXcgUC5pUCh0LCExKX1lbHNlIGlmKGEuY29uc3RydWN0
@@ -1637,2177 +1654,2217 @@
NyZhKTw8MTApCnJldHVybiBhXmE+Pj42fSwKckU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9Vy5DMChX
LkMwKFcuQzAoVy5DMCgwLGEpLGIpLGMpLGQpLHM9NTM2ODcwOTExJnQrKCg2NzEwODg2MyZ0KTw8MykK
c149cz4+PjExCnJldHVybiA1MzY4NzA5MTEmcysoKDE2MzgzJnMpPDwxNSl9LApUTjpmdW5jdGlvbihh
-LGIpe3ZhciB0LHM9YS5jbGFzc0xpc3QKZm9yKHQ9MDt0PDE7Kyt0KXMuYWRkKGJbdF0pfSwKSkU6ZnVu
-Y3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1XLmFGKG5ldyBXLnZOKGMpLHUuQikKaWYodCE9bnVsbCYmITAp
-Si5kWihhLGIsdCwhMSkKcmV0dXJuIG5ldyBXLnhDKGEsYix0LCExLGUuQygieEM8MD4iKSl9LApUdzpm
-dW5jdGlvbihhKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIikscz1uZXcgVy5tayh0LHdp
-bmRvdy5sb2NhdGlvbikKcz1uZXcgVy5KUShzKQpzLkNZKGEpCnJldHVybiBzfSwKeVc6ZnVuY3Rpb24o
-YSxiLGMsZCl7dS5oLmIoYSkKSC55KGIpCkgueShjKQp1Lk8uYihkKQpyZXR1cm4hMH0sClFXOmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciB0LHMscgp1LmguYihhKQpILnkoYikKSC55KGMpCnQ9dS5PLmIoZCkuYQpz
-PXQuYQpzLmhyZWY9YwpyPXMuaG9zdG5hbWUKdD10LmIKaWYoIShyPT10Lmhvc3RuYW1lJiZzLnBvcnQ9
-PXQucG9ydCYmcy5wcm90b2NvbD09dC5wcm90b2NvbCkpaWYocj09PSIiKWlmKHMucG9ydD09PSIiKXt0
-PXMucHJvdG9jb2wKdD10PT09IjoifHx0PT09IiJ9ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITAK
-cmV0dXJuIHR9LApCbDpmdW5jdGlvbigpe3ZhciB0PXUuTixzPVAudE0oQy5ReCx0KSxyPXUuZEcuYihu
-ZXcgVy5JQSgpKSxxPUguVk0oWyJURU1QTEFURSJdLHUucykKdD1uZXcgVy5jdChzLFAuTHModCksUC5M
-cyh0KSxQLkxzKHQpLG51bGwpCnQuQ1kobnVsbCxuZXcgSC5BOChDLlF4LHIsdS5kdikscSxudWxsKQpy
-ZXR1cm4gdH0sCnFjOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuCmlmKCJwb3N0TWVz
-c2FnZSIgaW4gYSl7dD1XLlAxKGEpCnJldHVybiB0fWVsc2UgcmV0dXJuIHUuYVMuYihhKX0sClAxOmZ1
-bmN0aW9uKGEpe2lmKGE9PT13aW5kb3cpcmV0dXJuIHUuY2kuYihhKQplbHNlIHJldHVybiBuZXcgVy5k
-VygpfSwKYUY6ZnVuY3Rpb24oYSxiKXt2YXIgdD0kLlgzCmlmKHQ9PT1DLk5VKXJldHVybiBhCnJldHVy
-biB0LlB5KGEsYil9LApxRTpmdW5jdGlvbiBxRSgpe30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVu
-Y3Rpb24gZlkoKXt9LApuQjpmdW5jdGlvbiBuQigpe30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUVA6ZnVu
-Y3Rpb24gUVAoKXt9LApueDpmdW5jdGlvbiBueCgpe30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVu
-Y3Rpb24gaWQoKXt9LApRRjpmdW5jdGlvbiBRRigpe30sCk5oOmZ1bmN0aW9uIE5oKCl7fSwKSUI6ZnVu
-Y3Rpb24gSUIoKXt9LApuNzpmdW5jdGlvbiBuNygpe30sCnd6OmZ1bmN0aW9uIHd6KGEsYil7dGhpcy5h
-PWEKdGhpcy4kdGk9Yn0sCmN2OmZ1bmN0aW9uIGN2KCl7fSwKQ3Y6ZnVuY3Rpb24gQ3YoKXt9LAplYTpm
-dW5jdGlvbiBlYSgpe30sCkQwOmZ1bmN0aW9uIEQwKCl7fSwKVDU6ZnVuY3Rpb24gVDUoKXt9LApoNDpm
-dW5jdGlvbiBoNCgpe30sCmJyOmZ1bmN0aW9uIGJyKCl7fSwKVmI6ZnVuY3Rpb24gVmIoKXt9LApPNzpm
-dW5jdGlvbiBPNygpe30sCmJVOmZ1bmN0aW9uIGJVKGEpe3RoaXMuYT1hfSwKaEg6ZnVuY3Rpb24gaEgo
-YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCndhOmZ1bmN0aW9uIHdhKCl7fSwKU2c6ZnVuY3Rpb24gU2co
-KXt9LAp1ODpmdW5jdGlvbiB1OCgpe30sCkFqOmZ1bmN0aW9uIEFqKCl7fSwKZTc6ZnVuY3Rpb24gZTco
-YSl7dGhpcy5hPWF9LAp1SDpmdW5jdGlvbiB1SCgpe30sCkJIOmZ1bmN0aW9uIEJIKCl7fSwKU046ZnVu
-Y3Rpb24gU04oKXt9LApldzpmdW5jdGlvbiBldygpe30sCmxwOmZ1bmN0aW9uIGxwKCl7fSwKVGI6ZnVu
-Y3Rpb24gVGIoKXt9LApJdjpmdW5jdGlvbiBJdigpe30sCkJUOmZ1bmN0aW9uIEJUKCl7fSwKeVk6ZnVu
-Y3Rpb24geVkoKXt9LAp3NjpmdW5jdGlvbiB3Nigpe30sCks1OmZ1bmN0aW9uIEs1KCl7fSwKQ206ZnVu
-Y3Rpb24gQ20oKXt9LApDUTpmdW5jdGlvbiBDUSgpe30sCnc0OmZ1bmN0aW9uIHc0KCl7fSwKcmg6ZnVu
-Y3Rpb24gcmgoKXt9LApEOTpmdW5jdGlvbiBEOSgpe30sCmk3OmZ1bmN0aW9uIGk3KGEpe3RoaXMuYT1h
-fSwKU3k6ZnVuY3Rpb24gU3koYSl7dGhpcy5hPWF9LApLUzpmdW5jdGlvbiBLUyhhLGIpe3RoaXMuYT1h
-CnRoaXMuYj1ifSwKQTM6ZnVuY3Rpb24gQTMoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkk0OmZ1bmN0
-aW9uIEk0KGEpe3RoaXMuYT1hfSwKRms6ZnVuY3Rpb24gRmsoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1i
-fSwKUk86ZnVuY3Rpb24gUk8oYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0
-aT1kfSwKQ3E6ZnVuY3Rpb24gQ3EoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
-LiR0aT1kfSwKeEM6ZnVuY3Rpb24geEMoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYj1hCl8uYz1iCl8u
-ZD1jCl8uZT1kCl8uJHRpPWV9LAp2TjpmdW5jdGlvbiB2TihhKXt0aGlzLmE9YX0sCkpROmZ1bmN0aW9u
-IEpRKGEpe3RoaXMuYT1hfSwKR206ZnVuY3Rpb24gR20oKXt9LAp2RDpmdW5jdGlvbiB2RChhKXt0aGlz
-LmE9YX0sClV2OmZ1bmN0aW9uIFV2KGEpe3RoaXMuYT1hfSwKRWc6ZnVuY3Rpb24gRWcoYSxiLGMpe3Ro
-aXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKbTY6ZnVuY3Rpb24gbTYoKXt9LApFbzpmdW5jdGlvbiBF
-bygpe30sCldrOmZ1bmN0aW9uIFdrKCl7fSwKY3Q6ZnVuY3Rpb24gY3QoYSxiLGMsZCxlKXt2YXIgXz10
-aGlzCl8uZT1hCl8uYT1iCl8uYj1jCl8uYz1kCl8uZD1lfSwKSUE6ZnVuY3Rpb24gSUEoKXt9LApPdzpm
-dW5jdGlvbiBPdygpe30sClc5OmZ1bmN0aW9uIFc5KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
-Cl8uYz0tMQpfLmQ9bnVsbApfLiR0aT1jfSwKZFc6ZnVuY3Rpb24gZFcoKXt9LAprRjpmdW5jdGlvbiBr
-Rigpe30sCm1rOmZ1bmN0aW9uIG1rKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLbzpmdW5jdGlvbiBL
-byhhKXt0aGlzLmE9YX0sCmZtOmZ1bmN0aW9uIGZtKGEpe3RoaXMuYT1hfSwKTGU6ZnVuY3Rpb24gTGUo
-KXt9LApLNzpmdW5jdGlvbiBLNygpe30sCnJCOmZ1bmN0aW9uIHJCKCl7fSwKWFc6ZnVuY3Rpb24gWFco
-KXt9LApvYTpmdW5jdGlvbiBvYSgpe319LFU9ewp5dTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8s
-bj1ILlZNKFtdLHUuYlApCmZvcih0PUouVTYoYSkscz1KLklUKHUuUi5iKHQucShhLCJkZXRhaWxzIikp
-KTtzLkYoKTspe3I9cy5nbCgpCnE9Si5VNihyKQpwPUgueShxLnEociwiZGVzY3JpcHRpb24iKSkKcT1x
-LnEociwibGluayIpCmlmKHE9PW51bGwpcT1udWxsCmVsc2V7bz1KLlU2KHEpCnE9bmV3IFUuTWwoSC55
-KG8ucShxLCJocmVmIikpLEguU2Moby5xKHEsImxpbmUiKSksSC55KG8ucShxLCJwYXRoIikpKX1DLk5t
-LmkobixuZXcgVS51RihwLHEpKX1yZXR1cm4gbmV3IFUuZDIobixVLmpmKHQucShhLCJlZGl0cyIpKSxI
-LnkodC5xKGEsImV4cGxhbmF0aW9uIikpLEguU2ModC5xKGEsImxpbmUiKSksSC55KHQucShhLCJwYXRo
-IikpKX0sCmpmOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxCmlmKGE9PW51bGwpdD1udWxsCmVsc2V7dD1I
-LlZNKFtdLHUuZkEpCmZvcihzPUouSVQodS5SLmIoYSkpO3MuRigpOyl7cj1zLmdsKCkKcT1KLlU2KHIp
-CkMuTm0uaSh0LG5ldyBVLlNlKEgueShxLnEociwiZGVzY3JpcHRpb24iKSksSC55KHEucShyLCJocmVm
-IikpKSl9fXJldHVybiB0fSwKZDI6ZnVuY3Rpb24gZDIoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1h
-Cl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKU2U6ZnVuY3Rpb24gU2UoYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCnVGOmZ1bmN0aW9uIHVGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNbDpmdW5jdGlvbiBN
-bChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9fSxUPXtHVjpmdW5jdGlvbiBHVigpe319
-LEw9ewpJcTpmdW5jdGlvbigpe0MuQlouQihkb2N1bWVudCwiRE9NQ29udGVudExvYWRlZCIsbmV3IEwu
-ZSgpKQpDLm9sLkIod2luZG93LCJwb3BzdGF0ZSIsbmV3IEwuTCgpKX0sCmhPOmZ1bmN0aW9uKGEpe2lm
-KDA+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsMCkKaWYoYVswXSE9PSIvIilyZXR1cm4gSi5UMChkb2N1
-bWVudC5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSsiLyIrSC5kKGEpCmVsc2UgcmV0
-dXJuIGF9LAprejpmdW5jdGlvbihhKXt2YXIgdCxzPXUuaC5hKGEucGFyZW50Tm9kZSkucXVlcnlTZWxl
-Y3RvcigiOnNjb3BlID4gdWwiKSxyPXMuc3R5bGUscT0iIitDLkNELnpRKHMub2Zmc2V0SGVpZ2h0KSoy
-KyJweCIKci5tYXhIZWlnaHQ9cQpyPUoucUYoYSkKcT1yLiR0aQp0PXEuQygifigxKSIpLmIobmV3IEwu
-V3gocyxhKSkKdS5NLmIobnVsbCkKVy5KRShyLmEsci5iLHQsITEscS5kKX0sCnlYOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscixxLHAsbz0icXVlcnlTZWxlY3RvckFsbCIsbj1kb2N1bWVudC5xdWVyeVNlbGVjdG9y
-KGEpLG09dS5oCm4udG9TdHJpbmcKSC5EaChtLG0sIlQiLG8pCnQ9dS5TCnM9bmV3IFcud3oobi5xdWVy
-eVNlbGVjdG9yQWxsKCIubmF2LWxpbmsiKSx0KQpzLksocyxuZXcgTC5BTygpKQpILkRoKG0sbSwiVCIs
-bykKcj1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5yZWdpb24iKSx0KQppZihyLmdBKHIpIT09
-MCl7cT1uLnF1ZXJ5U2VsZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQpxLnRvU3RyaW5nCnIuSyhyLG5l
-dyBMLkhvKHEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcocSkpLk8oInBhdGgi
-KSkpKX1ILkRoKG0sbSwiVCIsbykKcD1uZXcgVy53eihuLnF1ZXJ5U2VsZWN0b3JBbGwoIi5wb3N0LWxp
-bmsiKSx0KQpwLksocCxuZXcgTC5JQygpKX0sCmFLOmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSkuZ2hZ
-KCkucSgwLCJsaW5lIikKcmV0dXJuIHQ9PW51bGw/bnVsbDpILkhwKHQsbnVsbCl9LApHNjpmdW5jdGlv
-bihhKXt2YXIgdD1QLmhLKGEpLmdoWSgpLnEoMCwib2Zmc2V0IikKcmV0dXJuIHQ9PW51bGw/bnVsbDpI
-LkhwKHQsbnVsbCl9LAp0MjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuPXt9CnUuVi5iKGEp
-CnQ9bi5hPXUuaC5iKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKaWYo
-Si56bCh0LCI/Iikpe3M9Qy54Qi5Oaih0LDAsQy54Qi5PWSh0LCI/IikpCm4uYT1zCnI9c31lbHNlIHI9
-dAppZihiIT1udWxsKXtxPSQublUoKQpyPW4uYT1xLm81KEQubnIocS50TShiKSxyKSl9cD1MLkc2KHQp
-Cm89TC5hSyh0KQppZihwIT1udWxsKUwuYWYocixwLG8sbmV3IEwublQobixwLG8pKQplbHNlIEwuYWYo
-cixudWxsLG51bGwsbmV3IEwuQloobikpCmEucHJldmVudERlZmF1bHQoKX0sCnVtOmZ1bmN0aW9uKGEp
-e3ZhciB0LHM9e30scj11LmguYShXLnFjKHUuVi5iKGEpLmN1cnJlbnRUYXJnZXQpKS5nZXRBdHRyaWJ1
-dGUoImhyZWYiKQpzLmE9cgpyPUwuaE8ocikKcy5hPXIKdD11Lk4KVy5xRChyLCJQT1NUIixQLkVGKFsi
-Q29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCJdLHQsdCkpLlc3KG5l
-dyBMLkZRKCksdS5QKS5PQShuZXcgTC50WShzKSl9LAp2VTpmdW5jdGlvbigpe3ZhciB0PWRvY3VtZW50
-LHM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnQ9bmV3IFcud3oodC5xdWVyeVNl
-bGVjdG9yQWxsKCIuY29kZSIpLHUuUykKdC5LKHQsbmV3IEwuR0goKSl9LApoWDpmdW5jdGlvbihhLGIp
-e3ZhciB0PXUuTgpXLnFEKEguZChhKSsiP3JlZ2lvbj1yZWdpb24mb2Zmc2V0PSIrSC5kKGIpLG51bGws
-UC5FRihbIkNvbnRlbnQtVHlwZSIsImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiXSx0LHQp
-KS5XNyhuZXcgTC5EVCgpLHUuUCkuT0EobmV3IEwuZUgoYSkpfSwKRzc6ZnVuY3Rpb24oYSxiLGMsZCl7
-dmFyIHQscwppZighSi5yWShhKS5UYyhhLCIuZGFydCIpKXtMLkJFKGEsUC5FRihbInJlZ2lvbnMiLCIi
-LCJuYXZpZ2F0aW9uQ29udGVudCIsIiIsImVkaXRzIixbXV0sdS5OLHUueikpCkwuQlgoYSxudWxsKQpp
-ZihkIT1udWxsKWQuJDAoKQpyZXR1cm59dD1DLnhCLnRnKGEsIj8iKT9hKyImaW5saW5lPXRydWUiOmEr
-Ij9pbmxpbmU9dHJ1ZSIKcz11Lk4KVy5xRCh0LG51bGwsUC5FRihbIkNvbnRlbnQtVHlwZSIsImFwcGxp
-Y2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiXSxzLHMpKS5XNyhuZXcgTC56RChhLGIsYyxkKSx1LlAp
-Lk9BKG5ldyBMLk9FKGEpKX0sCkdlOmZ1bmN0aW9uKCl7dmFyIHQ9Ii9fcHJldmlldy9uYXZpZ2F0aW9u
-VHJlZS5qc29uIixzPXUuTgpXLnFEKHQsbnVsbCxQLkVGKFsiQ29udGVudC1UeXBlIiwiYXBwbGljYXRp
-b24vanNvbjsgY2hhcnNldD1VVEYtOCJdLHMscykpLlc3KG5ldyBMLlRXKCksdS5QKS5PQShuZXcgTC54
-cih0KSl9LApxSjpmdW5jdGlvbihhLGIpe3ZhciB0CndpbmRvdwppZih0eXBlb2YgY29uc29sZSE9InVu
-ZGVmaW5lZCIpd2luZG93LmNvbnNvbGUuZXJyb3IoYSkKd2luZG93CnQ9SC5kKGIpCmlmKHR5cGVvZiBj
-b25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS5lcnJvcih0KX0sCnFPOmZ1bmN0aW9uKGEp
-e3ZhciB0PWEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkscz10LmJvdHRvbSxyPXdpbmRvdy5pbm5lckhl
-aWdodAppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiBILnBZKHIpCmlmKHM+cilKLmRoKGEpCmVs
-c2UgaWYodC50b3A8MClKLmRoKGEpfSwKZkc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKaWYoYSE9bnVs
-bCl7dD1kb2N1bWVudApzPXQuZ2V0RWxlbWVudEJ5SWQoIm8iK0guZChhKSkKcj10LnF1ZXJ5U2VsZWN0
-b3IoIi5saW5lLSIrSC5kKGIpKQppZihzIT1udWxsKXtMLnFPKHMpCkouZFIocykuaSgwLCJ0YXJnZXQi
-KX1lbHNlIGlmKHIhPW51bGwpTC5xTyhyLnBhcmVudEVsZW1lbnQpCmlmKHIhPW51bGwpSi5kUih1Lmgu
-YShyLnBhcmVudE5vZGUpKS5pKDAsImhpZ2hsaWdodCIpfWVsc2UgTC5xTyhkb2N1bWVudC5nZXRFbGVt
-ZW50QnlJZCgidW5pdC1uYW1lIikpfSwKYWY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyPUwuRzYo
-d2luZG93LmxvY2F0aW9uLmhyZWYpLHE9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYociE9bnVs
-bCl7dD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgibyIrSC5kKHIpKQppZih0IT1udWxsKUouZFIodCku
-UigwLCJ0YXJnZXQiKX1pZihxIT1udWxsKXtzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIr
-SC5kKHEpKQppZihzIT1udWxsKUouZFIocy5wYXJlbnRFbGVtZW50KS5SKDAsImhpZ2hsaWdodCIpfWlm
-KGE9PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSl7TC5mRyhiLGMpCmQuJDAoKX1lbHNlIEwuRzcoYSxi
-LGMsZCl9LApMeDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PT0xKXQ9YgplbHNlIHQ9YisicyIKcmV0
-dXJuIHR9LApUMTpmdW5jdGlvbihhNCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUs
-ZCxjLGIsYSxhMCxhMT1udWxsLGEyPWRvY3VtZW50LGEzPWEyLnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LXBh
-bmVsIC5wYW5lbC1jb250ZW50IikKSi5sNShhMywiIikKaWYoYTQ9PW51bGwpe2EyPWEyLmNyZWF0ZUVs
-ZW1lbnQoInAiKQphMi50ZXh0Q29udGVudD0iU2VlIGRldGFpbHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0
-LiIKdD11LlguYihILlZNKFsicGxhY2Vob2xkZXIiXSx1LnMpKQpzPUMuTHQuZ0QoYTIpCnMuVjEoMCkK
-cy5GVigwLHQpCmEzLmFwcGVuZENoaWxkKGEyKQpyZXR1cm59cj1hNC5lCnQ9JC5uVSgpCnE9dC50TShy
-KQpwPWE0LmMKbz10LkhQKHIsSi5UMChhMi5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50
-KSkKbj1hNC5kCnQ9YTIuY3JlYXRlRWxlbWVudCgicCIpCm09dS5oCm0uYihhMy5hcHBlbmRDaGlsZCh0
-KSkuYXBwZW5kQ2hpbGQoYTIuY3JlYXRlVGV4dE5vZGUoSC5kKHApKyIgYXQgIitILmQobykrIjoiK0gu
-ZChuKSsiLiIpKQp0PWE0LmEKaWYodC5sZW5ndGghPT0wKXtsPWEyLmNyZWF0ZUVsZW1lbnQoInAiKQps
-LnRleHRDb250ZW50PSJFZGl0IHJhdGlvbmFsZToiCmEzLmFwcGVuZENoaWxkKGwpCmw9YTIuY3JlYXRl
-RWxlbWVudCgidWwiKQprPW0uYihhMy5hcHBlbmRDaGlsZChsKSkKZm9yKGw9dC5sZW5ndGgsaj11Lmss
-aT0wO2k8dC5sZW5ndGg7dC5sZW5ndGg9PT1sfHwoMCxILmxrKSh0KSwrK2kpe2g9dFtpXQpnPWEyLmNy
-ZWF0ZUVsZW1lbnQoImxpIikKZj1rLmFwcGVuZENoaWxkKGcpCmYuYXBwZW5kQ2hpbGQoYTIuY3JlYXRl
-VGV4dE5vZGUoaC5hKSkKZz1oLmIKaWYoZyE9bnVsbCl7ZT1nLmIKZi5hcHBlbmRDaGlsZChhMi5jcmVh
-dGVUZXh0Tm9kZSgiICgiKSkKZD1hMi5jcmVhdGVFbGVtZW50KCJhIikKYz1qLmIoZi5hcHBlbmRDaGls
-ZChkKSkKYy5hcHBlbmRDaGlsZChhMi5jcmVhdGVUZXh0Tm9kZShILmQoZy5jKSsiOiIrSC5kKGUpKSkK
-Yj1nLmEKZz0kLm5VKCkKYy5zZXRBdHRyaWJ1dGUoImhyZWYiLGcubzUoZy5xNygwLHEsYixhMSxhMSxh
-MSxhMSxhMSxhMSkpKQpjLmNsYXNzTGlzdC5hZGQoIm5hdi1saW5rIikKZi5hcHBlbmRDaGlsZChhMi5j
-cmVhdGVUZXh0Tm9kZSgiKSIpKX19fXQ9YTQuYgppZih0IT1udWxsKWZvcihsPXQubGVuZ3RoLGk9MDtp
-PHQubGVuZ3RoO3QubGVuZ3RoPT09bHx8KDAsSC5saykodCksKytpKXthPXRbaV0Kaj1hMi5jcmVhdGVF
-bGVtZW50KCJwIikKYTA9bS5iKGEzLmFwcGVuZENoaWxkKGopKQpqPWEyLmNyZWF0ZUVsZW1lbnQoImEi
-KQpjPW0uYihhMC5hcHBlbmRDaGlsZChqKSkKYy5hcHBlbmRDaGlsZChhMi5jcmVhdGVUZXh0Tm9kZShh
-LmEpKQpjLnNldEF0dHJpYnV0ZSgiaHJlZiIsYS5iKQpKLmRSKGMpLmkoMCwicG9zdC1saW5rIil9fSwK
-TEg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPWRvY3Vt
-ZW50LGM9ZC5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0IC5wYW5lbC1jb250ZW50IikKSi5sNShjLCIi
-KQp0PWQuY3JlYXRlRWxlbWVudCgicCIpCnM9dS5oCnI9cy5iKGMuYXBwZW5kQ2hpbGQodCkpCnQ9Si5V
-NihiKQpxPXQuZ0EoYikKaWYocT09PTApci5hcHBlbmRDaGlsZChkLmNyZWF0ZVRleHROb2RlKCJObyBw
-cm9wb3NlZCBlZGl0cyIpKQplbHNlIHIuYXBwZW5kQ2hpbGQoZC5jcmVhdGVUZXh0Tm9kZSgiIitxKyIg
-cHJvcG9zZWQgIitMLkx4KHEsImVkaXQiKSsiOiIpKQpwPWQuY3JlYXRlRWxlbWVudCgidWwiKQpvPXMu
-YihjLmFwcGVuZENoaWxkKHApKQpmb3IodD10LmdreihiKSxwPXUuayxuPXUuQyxtPW4uQygifigxKSIp
-LGw9dS5NLG49bi5kLGs9dS5hO3QuRigpOyl7aj1rLmIodC5nbCgpKQppPWQuY3JlYXRlRWxlbWVudCgi
-bGkiKQpoPXMuYihvLmFwcGVuZENoaWxkKGkpKQpKLmRSKGgpLmkoMCwiZWRpdCIpCmk9ZC5jcmVhdGVF
-bGVtZW50KCJhIikKZz1wLmIoaC5hcHBlbmRDaGlsZChpKSkKZy5jbGFzc0xpc3QuYWRkKCJlZGl0LWxp
-bmsiKQpmPUguU2Moai5xKDAsIm9mZnNldCIpKQppPUguZChmKQpnLnNldEF0dHJpYnV0ZSgiZGF0YS0i
-K25ldyBXLlN5KG5ldyBXLmk3KGcpKS5PKCJvZmZzZXQiKSxpKQplPUguU2Moai5xKDAsImxpbmUiKSkK
-aT1ILmQoZSkKZy5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhnKSkuTygibGlu
-ZSIpLGkpCmcuYXBwZW5kQ2hpbGQoZC5jcmVhdGVUZXh0Tm9kZSgibGluZSAiK0guZChlKSkpCmk9bS5i
-KG5ldyBMLkVFKGYsZSxhKSkKbC5iKG51bGwpClcuSkUoZywiY2xpY2siLGksITEsbikKaC5hcHBlbmRD
-aGlsZChkLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5kKGoucSgwLCJleHBsYW5hdGlvbiIpKSkpfUwuVDEo
-bnVsbCl9LApGcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9d2luZG93LmxvY2F0aW9uLHA9UC5o
-SygocSYmQy5FeCkuZ0RyKHEpK0guZChhKSkKcT11LnoKdD1QLkZsKHUuTixxKQppZihiIT1udWxsKXQu
-WSgwLCJvZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbCl0LlkoMCwibGluZSIsSC5kKGMpKQpwPXAubm0o
-MCx0LmE9PT0wP251bGw6dCkKcz13aW5kb3cuaGlzdG9yeQpyPXAudygwKQpzLnRvU3RyaW5nCnMucHVz
-aFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHEscSkpLCIiLHIpfSwKRW46ZnVuY3Rpb24oYSl7
-dmFyIHQ9Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50LCIvIikK
-aWYoQy54Qi5uKGEsdCkpcmV0dXJuIEMueEIuRyhhLHQubGVuZ3RoKQplbHNlIHJldHVybiBhfSwKQlg6
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9e30Kci5hPWEKYT1MLkVuKGEpCnIuYT1hCnQ9ZG9jdW1lbnQK
-dC5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1lIikudGV4dENvbnRlbnQ9YQpzPXUuaApILkRoKHMscywi
-VCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQp0PW5ldyBXLnd6KHQucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1w
-YW5lbCAubmF2LWxpbmsiKSx1LlMpCnQuSyh0LG5ldyBMLlZTKHIpKX0sCkJFOmZ1bmN0aW9uKGEsYil7
-dmFyIHQ9Ii5yZWdpb25zIixzPWRvY3VtZW50LHI9cy5xdWVyeVNlbGVjdG9yKHQpLHE9cy5xdWVyeVNl
-bGVjdG9yKCIuY29kZSIpCkoudEgocixILnkoYi5xKDAsInJlZ2lvbnMiKSksJC5LRygpKQpKLnRIKHEs
-SC55KGIucSgwLCJuYXZpZ2F0aW9uQ29udGVudCIpKSwkLktHKCkpCkwuTEgoYSx1LmouYihiLnEoMCwi
-ZWRpdHMiKSkpCkwudlUoKQpMLnlYKCIuY29kZSIpCkwueVgodCl9LAp0WDpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscixxLHAsbyxuLG0sbCxrLGo9Im5hbWUiLGk9ZG9jdW1lbnQsaD1pLmNyZWF0ZUVsZW1lbnQo
-InVsIiksZz11LmgsZj1nLmIoYS5hcHBlbmRDaGlsZChoKSkKZm9yKGg9Si5JVCh1LlIuYihiKSksdD11
-Lk07aC5GKCk7KXtzPWguZ2woKQpyPWkuY3JlYXRlRWxlbWVudCgibGkiKQpxPWcuYihmLmFwcGVuZENo
-aWxkKHIpKQpyPUouVTYocykKcD1KLlJFKHEpCmlmKEouUk0oci5xKHMsInR5cGUiKSwiZGlyZWN0b3J5
-Iikpe3AuZ0QocSkuaSgwLCJkaXIiKQpwPWkuY3JlYXRlRWxlbWVudCgic3BhbiIpCm89Zy5iKHEuYXBw
-ZW5kQ2hpbGQocCkpCnA9Si5SRShvKQpwLmdEKG8pLmkoMCwiYXJyb3ciKQpwLnNoZihvLCImI3gyNUJD
-OyIpCnA9aS5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5sNShnLmIocS5hcHBlbmRDaGlsZChwKSksIiYj
-eDFGNEMxOyIpCnEuYXBwZW5kQ2hpbGQoaS5jcmVhdGVUZXh0Tm9kZShILnkoci5xKHMsaikpKSkKTC50
-WChxLHIucShzLCJzdWJ0cmVlIikpCkwua3oobyl9ZWxzZXtwLnNoZihxLCImI3gxRjRDNDsiKQpwPWku
-Y3JlYXRlRWxlbWVudCgiYSIpCm49Zy5iKHEuYXBwZW5kQ2hpbGQocCkpCnA9Si5SRShuKQpwLmdEKG4p
-LmkoMCwibmF2LWxpbmsiKQptPUgueShyLnEocywicGF0aCIpKQpuLnNldEF0dHJpYnV0ZSgiZGF0YS0i
-K25ldyBXLlN5KG5ldyBXLmk3KG4pKS5PKGopLG0pCm4uc2V0QXR0cmlidXRlKCJocmVmIixILnkoci5x
-KHMsImhyZWYiKSkpCm4uYXBwZW5kQ2hpbGQoaS5jcmVhdGVUZXh0Tm9kZShILnkoci5xKHMsaikpKSkK
-cD1wLmdWbChuKQptPXAuJHRpCm0uQygifigxKSIpLmIoTC5YTigpKQp0LmIobnVsbCkKVy5KRShwLmEs
-cC5iLEwuWE4oKSwhMSxtLmQpCmw9SC5TYyhyLnEocywiZWRpdENvdW50IikpCmlmKHR5cGVvZiBsIT09
-Im51bWJlciIpcmV0dXJuIGwub3MoKQppZihsPjApe3I9aS5jcmVhdGVFbGVtZW50KCJzcGFuIikKaz1n
-LmIocS5hcHBlbmRDaGlsZChyKSkKSi5kUihrKS5pKDAsImVkaXQtY291bnQiKQpyPSIiK2wrIiAiCmlm
-KGw9PT0xKXA9ImVkaXQiCmVsc2UgcD0iZWRpdHMiCmsuc2V0QXR0cmlidXRlKCJ0aXRsZSIscitwKQpr
-LmFwcGVuZENoaWxkKGkuY3JlYXRlVGV4dE5vZGUoQy5qbi53KGwpKSl9fX19LAplOmZ1bmN0aW9uIGUo
-KXt9LApWVzpmdW5jdGlvbiBWVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApMOmZ1
-bmN0aW9uIEwoKXt9LApXeDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQU86ZnVu
-Y3Rpb24gQU8oKXt9LApkTjpmdW5jdGlvbiBkTigpe30sCkhvOmZ1bmN0aW9uIEhvKGEpe3RoaXMuYT1h
-fSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9uIElDKCl7
-fSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKQlo6ZnVu
-Y3Rpb24gQlooYSl7dGhpcy5hPWF9LApGUTpmdW5jdGlvbiBGUSgpe30sCnRZOmZ1bmN0aW9uIHRZKGEp
-e3RoaXMuYT1hfSwKR0g6ZnVuY3Rpb24gR0goKXt9LApEVDpmdW5jdGlvbiBEVCgpe30sCmVIOmZ1bmN0
-aW9uIGVIKGEpe3RoaXMuYT1hfSwKekQ6ZnVuY3Rpb24gekQoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9
-YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCk9FOmZ1bmN0aW9uIE9FKGEpe3RoaXMuYT1hfSwKVFc6ZnVuY3Rp
-b24gVFcoKXt9LAp4cjpmdW5jdGlvbiB4cihhKXt0aGlzLmE9YX0sCkVFOmZ1bmN0aW9uIEVFKGEsYixj
-KXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClFMOmZ1bmN0aW9uIFFMKGEsYil7dGhpcy5hPWEK
-dGhpcy5iPWJ9LApWUzpmdW5jdGlvbiBWUyhhKXt0aGlzLmE9YX0sClhBOmZ1bmN0aW9uIFhBKCl7fSwK
-SVY6ZnVuY3Rpb24gSVYoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19
-LE09ewpZRjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuCmZvcih0PWIubGVuZ3RoLHM9MTtz
-PHQ7KytzKXtpZihiW3NdPT1udWxsfHxiW3MtMV0hPW51bGwpY29udGludWUKZm9yKDt0Pj0xO3Q9cil7
-cj10LTEKaWYoYltyXSE9bnVsbClicmVha31xPW5ldyBQLlJuKCIiKQpwPWErIigiCnEuYT1wCm89SC5x
-QyhiLDAsdCxILnQ2KGIpLmQpCm49by4kdGkKbj1wK25ldyBILkE4KG8sbi5DKCJxVShhTC5FKSIpLmIo
-bmV3IE0uTm8oKSksbi5DKCJBODxhTC5FLHFVPiIpKS5IKDAsIiwgIikKcS5hPW4KcS5hPW4rKCIpOiBw
-YXJ0ICIrKHMtMSkrIiB3YXMgbnVsbCwgYnV0IHBhcnQgIitzKyIgd2FzIG5vdC4iKQp0aHJvdyBILmIo
-UC54WShxLncoMCkpKX19LApsSTpmdW5jdGlvbiBsSShhKXt0aGlzLmE9YX0sCk1pOmZ1bmN0aW9uIE1p
-KCl7fSwKcTc6ZnVuY3Rpb24gcTcoKXt9LApObzpmdW5jdGlvbiBObygpe319LEI9e0x1OmZ1bmN0aW9u
-IEx1KCl7fSwKT1M6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoIShhPj02NSYmYTw9OTApKXQ9YT49OTcmJmE8
-PTEyMgplbHNlIHQ9ITAKcmV0dXJuIHR9LApZdTpmdW5jdGlvbihhLGIpe3ZhciB0PWEubGVuZ3RoLHM9
-YisyCmlmKHQ8cylyZXR1cm4hMQppZighQi5PUyhDLnhCLm0oYSxiKSkpcmV0dXJuITEKaWYoQy54Qi5t
-KGEsYisxKSE9PTU4KXJldHVybiExCmlmKHQ9PT1zKXJldHVybiEwCnJldHVybiBDLnhCLm0oYSxzKT09
-PTQ3fX0sWD17CkNMOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPWIueFooYSkKYi5oSyhhKQpp
-ZihvIT1udWxsKWE9Si5LVihhLG8ubGVuZ3RoKQp0PXUucwpzPUguVk0oW10sdCkKcj1ILlZNKFtdLHQp
-CnQ9YS5sZW5ndGgKaWYodCE9PTAmJmIucjQoQy54Qi5XKGEsMCkpKXtpZigwPj10KXJldHVybiBILk9I
-KGEsMCkKQy5ObS5pKHIsYVswXSkKcT0xfWVsc2V7Qy5ObS5pKHIsIiIpCnE9MH1mb3IocD1xO3A8dDsr
-K3ApaWYoYi5yNChDLnhCLlcoYSxwKSkpe0MuTm0uaShzLEMueEIuTmooYSxxLHApKQpDLk5tLmkocixh
-W3BdKQpxPXArMX1pZihxPHQpe0MuTm0uaShzLEMueEIuRyhhLHEpKQpDLk5tLmkociwiIil9cmV0dXJu
-IG5ldyBYLldEKGIsbyxzLHIpfSwKV0Q6ZnVuY3Rpb24gV0QoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9
-YQpfLmI9YgpfLmQ9YwpfLmU9ZH0sCnFSOmZ1bmN0aW9uIHFSKGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rp
-b24oYSl7cmV0dXJuIG5ldyBYLmR2KGEpfSwKZHY6ZnVuY3Rpb24gZHYoYSl7dGhpcy5hPWF9fSxPPXsK
-Umg6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGk9bnVsbAppZihQLnVvKCkuZ0Zp
-KCkhPT0iZmlsZSIpcmV0dXJuICQuRWIoKQp0PVAudW8oKQppZighQy54Qi5UYyh0LmdJaSh0KSwiLyIp
-KXJldHVybiAkLkViKCkKcz1QLlBpKGksMCwwKQpyPVAuelIoaSwwLDApCnE9UC5PZShpLDAsMCwhMSkK
-cD1QLmxlKGksMCwwLGkpCm89UC50RyhpLDAsMCkKbj1QLndCKGkscykKbT1zPT09ImZpbGUiCmlmKHE9
-PW51bGwpdD1yLmxlbmd0aCE9PTB8fG4hPW51bGx8fG0KZWxzZSB0PSExCmlmKHQpcT0iIgp0PXE9PW51
-bGwKbD0hdAprPVAua2EoImEvYiIsMCwzLGkscyxsKQpqPXMubGVuZ3RoPT09MAppZihqJiZ0JiYhQy54
-Qi5uKGssIi8iKSlrPVAud0Yoaywhanx8bCkKZWxzZSBrPVAueGUoaykKaWYobmV3IFAuRG4ocyxyLHQm
-JkMueEIubihrLCIvLyIpPyIiOnEsbixrLHAsbykudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJl
-dHVybiAkLmJEKCl9LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0
-aGlzLmQ9YQp0aGlzLmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBf
-PXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsKUlg6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9
-UC51bygpCmlmKEouUk0ociwkLkk2KSlyZXR1cm4gJC5GZgokLkk2PXIKaWYoJC5IaygpPT0kLkViKCkp
-cmV0dXJuICQuRmY9ci5aSSgiLiIpLncoMCkKZWxzZXt0PXIudDQoKQpzPXQubGVuZ3RoLTEKcmV0dXJu
-ICQuRmY9cz09PTA/dDpDLnhCLk5qKHQsMCxzKX19LApucjpmdW5jdGlvbihhLGIpe3ZhciB0PW51bGwK
-cmV0dXJuICQublUoKS5xNygwLGEsYix0LHQsdCx0LHQsdCl9fQp2YXIgdz1bQyxILEosUCxXLFUsVCxM
-LE0sQixYLE8sRSxGLERdCmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2
-YXIgJD17fQpILmVvLnByb3RvdHlwZT17fQpKLnZCLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIGE9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihh
-KXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTShhKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1
-Lm8uYihiKQp0aHJvdyBILmIoUC5scihhLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9fQpKLnlFLnBy
-b3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCmdpTzpmdW5jdGlvbihhKXty
-ZXR1cm4gYT81MTkwMTg6MjE4MTU5fSwKJGlhMjoxfQpKLllFLnByb3RvdHlwZT17CkROOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIG51bGw9PWJ9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJudWxsIn0sCmdpTzpmdW5j
-dGlvbihhKXtyZXR1cm4gMH0sCmU3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU2ooYSx1Lm8uYihi
-KSl9LAokaWM4OjF9CkouTUYucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfSwKdzpm
-dW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl2bToxfQpKLmlDLnByb3RvdHlwZT17fQpKLmtk
-LnByb3RvdHlwZT17fQpKLmM1LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9YVskLncoKV0K
-aWYodD09bnVsbClyZXR1cm4gdGhpcy50KGEpCnJldHVybiJKYXZhU2NyaXB0IGZ1bmN0aW9uIGZvciAi
-K0guZChKLmoodCkpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm57ZnVuYzoxLG9wdDpbLCwsLCwsLCwsLCws
-LCwsLF19fSwKJGlFSDoxfQpKLmpkLnByb3RvdHlwZT17Cmk6ZnVuY3Rpb24oYSxiKXtILnQ2KGEpLmQu
-YihiKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiYWRkIikpCmEucHVzaChiKX0sClc0OmZ1
-bmN0aW9uKGEsYil7dmFyIHQKaWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoInJlbW92ZUF0Iikp
-CnQ9YS5sZW5ndGgKaWYoYj49dCl0aHJvdyBILmIoUC54KGIsbnVsbCkpCnJldHVybiBhLnNwbGljZShi
-LDEpWzBdfSwKVUc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpILnQ2KGEpLkMoImNYPDE+IikuYihj
-KQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53
-QShiLDAsdCwiaW5kZXgiKQpzPWMubGVuZ3RoCnRoaXMuc0EoYSx0K3MpCnI9YitzCnRoaXMuWVcoYSxy
-LGEubGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0sCm12OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhl
-ZCRsZW5ndGgpSC52aChQLkw0KCJyZW1vdmVMYXN0IikpCmlmKGEubGVuZ3RoPT09MCl0aHJvdyBILmIo
-SC5IWShhLC0xKSkKcmV0dXJuIGEucG9wKCl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0CkgudDYoYSku
-QygiY1g8MT4iKS5iKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGRBbGwiKSkKZm9y
-KHQ9Si5JVChiKTt0LkYoKTspYS5wdXNoKHQuZ2woKSl9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpI
-LnQ2KGEpLkMoIn4oMSkiKS5iKGIpCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKXtiLiQxKGFbc10p
-CmlmKGEubGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChhKSl9fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciB0PUgudDYoYSkKcmV0dXJuIG5ldyBILkE4KGEsdC5LcShjKS5DKCIxKDIpIikuYihiKSx0LkMoIkA8
-MT4iKS5LcShjKS5DKCJBODwxLDI+IikpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9bmV3IEFycmF5
-KGEubGVuZ3RoKQpzLmZpeGVkJGxlbmd0aD1BcnJheQpmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0KXRoaXMu
-WShzLHQsSC5kKGFbdF0pKQpyZXR1cm4gcy5qb2luKGIpfSwKTjA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
-IHQscyxyCmQuYihiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmIoYykKdD1hLmxlbmd0aApmb3Io
-cz1iLHI9MDtyPHQ7KytyKXtzPWMuJDIocyxhW3JdKQppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAu
-YTQoYSkpfXJldHVybiBzfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJu
-IEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCmFNOmZ1bmN0aW9uKGEsYixjKXtpZihiPDB8fGI+YS5sZW5n
-dGgpdGhyb3cgSC5iKFAuVEUoYiwwLGEubGVuZ3RoLCJzdGFydCIsbnVsbCkpCmlmKGM8Ynx8Yz5hLmxl
-bmd0aCl0aHJvdyBILmIoUC5URShjLGIsYS5sZW5ndGgsImVuZCIsbnVsbCkpCmlmKGI9PT1jKXJldHVy
-biBILlZNKFtdLEgudDYoYSkpCnJldHVybiBILlZNKGEuc2xpY2UoYixjKSxILnQ2KGEpKX0sCmdyWjpm
-dW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PjApcmV0dXJuIGFbdC0xXQp0aHJvdyBILmIoSC5X
-cCgpKX0sCllXOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyPUgudDYoYSkKci5DKCJjWDwxPiIp
-LmIoZCkKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgudmgoUC5MNCgic2V0UmFuZ2UiKSkKUC5qQihiLGMs
-YS5sZW5ndGgpCnQ9Yy1iCmlmKHQ9PT0wKXJldHVybgpQLmsxKGUsInNraXBDb3VudCIpCnIuQygiek08
-MT4iKS5iKGQpCnI9Si5VNihkKQppZihlK3Q+ci5nQShkKSl0aHJvdyBILmIoSC5hcigpKQppZihlPGIp
-Zm9yKHM9dC0xO3M+PTA7LS1zKWFbYitzXT1yLnEoZCxlK3MpCmVsc2UgZm9yKHM9MDtzPHQ7KytzKWFb
-YitzXT1yLnEoZCxlK3MpfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMs
-ZCwwKX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoImEyKDEpIikuYihiKQp0PWEu
-bGVuZ3RoCmZvcihzPTA7czx0Oysrcyl7aWYoSC5vVChiLiQxKGFbc10pKSlyZXR1cm4hMAppZihhLmxl
-bmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIg
-dApmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0KWlmKEouUk0oYVt0XSxiKSlyZXR1cm4hMApyZXR1cm4hMX0s
-Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0sCmdrejpmdW5jdGlvbihhKXtyZXR1
-cm4gbmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEp
-e3JldHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rp
-b24oYSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgic2V0IGxlbmd0aCIpKQppZihiPDAp
-dGhyb3cgSC5iKFAuVEUoYiwwLG51bGwsIm5ld0xlbmd0aCIsbnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1
-bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikp
-CnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC50NihhKS5kLmIoYykKaWYoISFhLmltbXV0
-YWJsZSRsaXN0KUgudmgoUC5MNCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJv
-dyBILmIoSC5IWShhLGIpKQphW2JdPWN9LAokaWNYOjEsCiRpek06MX0KSi5Qby5wcm90b3R5cGU9e30K
-Si5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7
-dmFyIHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJvdyBILmIoSC5sayhyKSkK
-dD1zLmMKaWYodD49cSl7cy5zTShudWxsKQpyZXR1cm4hMX1zLnNNKHJbdF0pOysrcy5jCnJldHVybiEw
-fSwKc006ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSi5xSS5wcm90
-b3R5cGU9ewp5dTpmdW5jdGlvbihhKXt2YXIgdAppZihhPj0tMjE0NzQ4MzY0OCYmYTw9MjE0NzQ4MzY0
-NylyZXR1cm4gYXwwCmlmKGlzRmluaXRlKGEpKXt0PWE8MD9NYXRoLmNlaWwoYSk6TWF0aC5mbG9vcihh
-KQpyZXR1cm4gdCswfXRocm93IEguYihQLkw0KCIiK2ErIi50b0ludCgpIikpfSwKelE6ZnVuY3Rpb24o
-YSl7aWYoYT4wKXtpZihhIT09MS8wKXJldHVybiBNYXRoLnJvdW5kKGEpfWVsc2UgaWYoYT4tMS8wKXJl
-dHVybiAwLU1hdGgucm91bmQoMC1hKQp0aHJvdyBILmIoUC5MNCgiIithKyIucm91bmQoKSIpKX0sClda
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYoYjwyfHxiPjM2KXRocm93IEguYihQLlRFKGIsMiwz
-NiwicmFkaXgiLG51bGwpKQp0PWEudG9TdHJpbmcoYikKaWYoQy54Qi5tKHQsdC5sZW5ndGgtMSkhPT00
-MSlyZXR1cm4gdApzPS9eKFtcZGEtel0rKSg/OlwuKFtcZGEtel0rKSk/XChlXCsoXGQrKVwpJC8uZXhl
-Yyh0KQppZihzPT1udWxsKUgudmgoUC5MNCgiVW5leHBlY3RlZCB0b1N0cmluZyByZXN1bHQ6ICIrdCkp
-CnI9cy5sZW5ndGgKaWYoMT49cilyZXR1cm4gSC5PSChzLDEpCnQ9c1sxXQppZigzPj1yKXJldHVybiBI
-Lk9IKHMsMykKcT0rc1szXQpyPXNbMl0KaWYociE9bnVsbCl7dCs9cgpxLT1yLmxlbmd0aH1yZXR1cm4g
-dCtDLnhCLkl4KCIwIixxKX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVybiItMC4w
-IgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1hfDAKaWYoYT09
-PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0aC5hYnMoYSkKcz1NYXRoLmxvZyh0KS8wLjY5MzE0NzE4
-MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykKcT10PDE/dC9yOnIvdApyZXR1cm4gNTM2ODcwOTExJigo
-cSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5NytzKjEyNTl9
-LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWElYgppZih0PT09MClyZXR1cm4gMAppZih0PjApcmV0dXJu
-IHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSByZXR1cm4gdCtifSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIg
-dAppZihhPjApdD10aGlzLnAzKGEsYikKZWxzZXt0PWI+MzE/MzE6Ygp0PWE+PnQ+Pj4wfXJldHVybiB0
-fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgudEwoYikpCnJldHVybiB0aGlzLnAz
-KGEsYil9LApwMzpmdW5jdGlvbihhLGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9LAokaUNQOjEsCiRpRks6
-MX0KSi51ci5wcm90b3R5cGU9eyRpS046MX0KSi5WQS5wcm90b3R5cGU9e30KSi5Eci5wcm90b3R5cGU9
-ewptOmZ1bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEsYikpCmlmKGI+PWEubGVuZ3Ro
-KUgudmgoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKVzpmdW5jdGlvbihhLGIpe2lm
-KGI+PWEubGVuZ3RoKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQoYil9LApk
-ZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC51bihiLGEsMCl9LApoOmZ1bmN0aW9uKGEsYil7aWYo
-dHlwZW9mIGIhPSJzdHJpbmciKXRocm93IEguYihQLkwzKGIsbnVsbCxudWxsKSkKcmV0dXJuIGErYn0s
-ClRjOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5sZW5ndGgscz1hLmxlbmd0aAppZih0PnMpcmV0dXJuITEK
-cmV0dXJuIGI9PT10aGlzLkcoYSxzLXQpfSwKaTc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwpjPVAu
-akIoYixjLGEubGVuZ3RoKQp0PWEuc3Vic3RyaW5nKDAsYikKcz1hLnN1YnN0cmluZyhjKQpyZXR1cm4g
-dCtkK3N9LApRaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIUgub2soYykpSC52aChILnRMKGMpKQpp
-Zih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBjLkooKQppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cg
-SC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVsbCkpCnQ9YytiLmxlbmd0aAppZih0PmEubGVuZ3Ro
-KXJldHVybiExCnJldHVybiBiPT09YS5zdWJzdHJpbmcoYyx0KX0sCm46ZnVuY3Rpb24oYSxiKXtyZXR1
-cm4gdGhpcy5RaShhLGIsMCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYoIUgub2soYikpSC52aChILnRM
-KGIpKQppZihjPT1udWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIhPT0ibnVtYmVyIilyZXR1cm4gYi5K
-KCkKaWYoYjwwKXRocm93IEguYihQLngoYixudWxsKSkKaWYoYj5jKXRocm93IEguYihQLngoYixudWxs
-KSkKaWYoYz5hLmxlbmd0aCl0aHJvdyBILmIoUC54KGMsbnVsbCkpCnJldHVybiBhLnN1YnN0cmluZyhi
-LGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLk5qKGEsYixudWxsKX0sCmhjOmZ1bmN0aW9u
-KGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLnRy
-aW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBxCmlmKHRoaXMuVyhxLDApPT09MTMzKXt0PUou
-bW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9MApzPXAtMQpyPXRoaXMubShxLHMpPT09MTMz
-P0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4gcQpyZXR1cm4gcS5zdWJzdHJpbmcodCxy
-KX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1iKXJldHVybiIiCmlmKGI9PT0xfHxhLmxl
-bmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihDLkVxKQpmb3IodD1hLHM9IiI7
-ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihiPT09MClicmVhawp0Kz10fXJldHVybiBz
-fSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5U
-RShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4T2YoYixjKQpyZXR1cm4gdH0sCk9ZOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQ
-LlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVuZ3RoCnM9YS5sZW5ndGgKaWYoYyt0PnMp
-Yz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
-aXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWEubGVuZ3RoCmlmKGM+dCl0
-aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1cm4gSC5tMihhLGIsYyl9LAp0ZzpmdW5j
-dGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApn
-aU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVuZ3RoLHM9MCxyPTA7cjx0Oysrcil7cz01
-MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4NzA5MTEmcysoKDUyNDI4NyZzKTw8MTApCnNe
-PXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwzKQpzXj1zPj4xMQpyZXR1cm4gNTM2ODcw
-OTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpm
-dW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fCExKXRocm93IEguYihILkhZKGEsYikp
-CnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIubSh0aGlz
-LmEsSC5TYyhiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlwZT17CmdrejpmdW5jdGlv
-bihhKXt2YXIgdD10aGlzCnJldHVybiBuZXcgSC5hNyh0LHQuZ0EodCksSC5MaCh0KS5DKCJhNzxhTC5F
-PiIpKX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT10aGlzLHA9cS5nQShxKQppZihiLmxlbmd0
-aCE9PTApe2lmKHA9PT0wKXJldHVybiIiCnQ9SC5kKHEuRSgwLDApKQppZihwIT09cS5nQShxKSl0aHJv
-dyBILmIoUC5hNChxKSkKZm9yKHM9dCxyPTE7cjxwOysrcil7cz1zK2IrSC5kKHEuRSgwLHIpKQppZihw
-IT09cS5nQShxKSl0aHJvdyBILmIoUC5hNChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9
-ZWxzZXtmb3Iocj0wLHM9IiI7cjxwOysrcil7cys9SC5kKHEuRSgwLHIpKQppZihwIT09cS5nQShxKSl0
-aHJvdyBILmIoUC5hNChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fSwKZXY6ZnVuY3Rp
-b24oYSxiKXtyZXR1cm4gdGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5iKGIpKX19Ckgu
-bkgucHJvdG90eXBlPXsKZ1VEOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IbSh0aGlzLmEpLHM9dGhpcy5jCmlm
-KHM9PW51bGx8fHM+dClyZXR1cm4gdApyZXR1cm4gc30sCmdBczpmdW5jdGlvbigpe3ZhciB0PUouSG0o
-dGhpcy5hKSxzPXRoaXMuYgppZihzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXt2
-YXIgdCxzPUouSG0odGhpcy5hKSxyPXRoaXMuYgppZihyPj1zKXJldHVybiAwCnQ9dGhpcy5jCmlmKHQ9
-PW51bGx8fHQ+PXMpcmV0dXJuIHMtcgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkhOKCkK
-cmV0dXJuIHQtcn0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMscj1zLmdBcygpK2IKaWYoYj49
-MCl7dD1zLmdVRCgpCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIEgucFkodCkKdD1yPj10fWVs
-c2UgdD0hMAppZih0KXRocm93IEguYihQLkNmKGIscywiaW5kZXgiLG51bGwsbnVsbCkpCnJldHVybiBK
-LkFNKHMuYSxyKX19CkguYTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwK
-RjpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYocikscD1xLmdBKHIpCmlmKHMuYiE9
-PXApdGhyb3cgSC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Muc0kobnVsbCkKcmV0dXJuITF9cy5z
-SShxLkUocix0KSk7KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGku
-ZC5iKGEpfSwKJGlBbjoxfQpILkE4LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkht
-KHRoaXMuYSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYi4kMShKLkFNKHRoaXMuYSxiKSl9
-fQpILlU1LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU08oSi5JVCh0aGlz
-LmEpLHRoaXMuYix0aGlzLiR0aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90eXBlPXsKRjpmdW5jdGlv
-bigpe3ZhciB0LHMKZm9yKHQ9dGhpcy5hLHM9dGhpcy5iO3QuRigpOylpZihILm9UKHMuJDEodC5nbCgp
-KSkpcmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19Ckgu
-U1UucHJvdG90eXBlPXt9CkguUmUucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5MaCh0aGlz
-KS5DKCJSZS5FIikuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBhbiB1bm1vZGlmaWFi
-bGUgbGlzdCIpKX19CkguWEMucHJvdG90eXBlPXt9Ckgud3YucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9u
-KGEpe3ZhciB0PXRoaXMuX2hhc2hDb2RlCmlmKHQhPW51bGwpcmV0dXJuIHQKdD01MzY4NzA5MTEmNjY0
-NTk3KkouaGYodGhpcy5hKQp0aGlzLl9oYXNoQ29kZT10CnJldHVybiB0fSwKdzpmdW5jdGlvbihhKXty
-ZXR1cm4nU3ltYm9sKCInK0guZCh0aGlzLmEpKyciKSd9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51
-bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0aGlzLmE9PWIuYX0sCiRpR0Q6MX0K
-SC5QRC5wcm90b3R5cGU9e30KSC5XVS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5P
-KHRoaXMpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmQuYihiKQp0LmNoWzFd
-LmIoYykKcmV0dXJuIEguZGMoKX0sCiRpWjA6MX0KSC5MUC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5hfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGEhPSJzdHJpbmciKXJldHVy
-biExCmlmKCJfX3Byb3RvX18iPT09YSlyZXR1cm4hMQpyZXR1cm4gdGhpcy5iLmhhc093blByb3BlcnR5
-KGEpfSwKcTpmdW5jdGlvbihhLGIpe2lmKCF0aGlzLng0KGIpKXJldHVybgpyZXR1cm4gdGhpcy5xUChi
-KX0sCnFQOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC55KGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHIscSxwPUguTGgodGhpcykKcC5DKCJ+KDEsMikiKS5iKGIpCnQ9dGhpcy5jCmZvcihzPXQu
-bGVuZ3RoLHA9cC5jaFsxXSxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxwLmIodGhpcy5xUChxKSkp
-fX19CkguTEkucHJvdG90eXBlPXsKZ1dhOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5hCnJldHVybiB0fSwK
-Z25kOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzCmlmKHAuYz09PTEpcmV0dXJuIEMuZG4KdD1w
-LmQKcz10Lmxlbmd0aC1wLmUubGVuZ3RoLXAuZgppZihzPT09MClyZXR1cm4gQy5kbgpyPVtdCmZvcihx
-PTA7cTxzOysrcSl7aWYocT49dC5sZW5ndGgpcmV0dXJuIEguT0godCxxKQpyLnB1c2godFtxXSl9cmV0
-dXJuIEouekMocil9LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwppZihs
-LmMhPT0wKXJldHVybiBDLkNNCnQ9bC5lCnM9dC5sZW5ndGgKcj1sLmQKcT1yLmxlbmd0aC1zLWwuZgpp
-ZihzPT09MClyZXR1cm4gQy5DTQpwPW5ldyBILk41KHUuZW8pCmZvcihvPTA7bzxzOysrbyl7aWYobz49
-dC5sZW5ndGgpcmV0dXJuIEguT0godCxvKQpuPXRbb10KbT1xK28KaWYobTwwfHxtPj1yLmxlbmd0aCly
-ZXR1cm4gSC5PSChyLG0pCnAuWSgwLG5ldyBILnd2KG4pLHJbbV0pfXJldHVybiBuZXcgSC5QRChwLHUu
-Z0YpfSwKJGl2UToxfQpILkNqLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQKSC55KGEp
-CnQ9dGhpcy5hCnQuYj10LmIrIiQiK0guZChhKQpDLk5tLmkodGhpcy5iLGEpCkMuTm0uaSh0aGlzLmMs
-Yik7Kyt0LmF9LAokUzoxNX0KSC5aci5wcm90b3R5cGU9ewpxUzpmdW5jdGlvbihhKXt2YXIgdCxzLHI9
-dGhpcyxxPW5ldyBSZWdFeHAoci5hKS5leGVjKGEpCmlmKHE9PW51bGwpcmV0dXJuCnQ9T2JqZWN0LmNy
-ZWF0ZShudWxsKQpzPXIuYgppZihzIT09LTEpdC5hcmd1bWVudHM9cVtzKzFdCnM9ci5jCmlmKHMhPT0t
-MSl0LmFyZ3VtZW50c0V4cHI9cVtzKzFdCnM9ci5kCmlmKHMhPT0tMSl0LmV4cHI9cVtzKzFdCnM9ci5l
-CmlmKHMhPT0tMSl0Lm1ldGhvZD1xW3MrMV0Kcz1yLmYKaWYocyE9PS0xKXQucmVjZWl2ZXI9cVtzKzFd
-CnJldHVybiB0fX0KSC5XMC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYgppZih0
-PT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILmQodGhpcy5hKQpyZXR1cm4iTm9TdWNo
-TWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3QrIicgb24gbnVsbCJ9fQpILmF6LnByb3Rv
-dHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9Ik5vU3VjaE1ldGhvZEVycm9yOiBtZXRo
-b2Qgbm90IGZvdW5kOiAnIixxPXMuYgppZihxPT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjog
-IitILmQocy5hKQp0PXMuYwppZih0PT1udWxsKXJldHVybiByK3ErIicgKCIrSC5kKHMuYSkrIikiCnJl
-dHVybiByK3ErIicgb24gJyIrdCsiJyAoIitILmQocy5hKSsiKSJ9fQpILnZWLnByb3RvdHlwZT17Cnc6
-ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0Lmxlbmd0aD09PTA/IkVycm9yIjoiRXJyb3I6
-ICIrdH19CkguQW0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7aWYodS5iVS5jKGEpKWlmKGEuJHRo
-cm93bkpzRXJyb3I9PW51bGwpYS4kdGhyb3duSnNFcnJvcj10aGlzLmEKcmV0dXJuIGF9LAokUzo0fQpI
-LlhPLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYocyE9bnVsbClyZXR1
-cm4gcwpzPXRoaXMuYQp0PXMhPT1udWxsJiZ0eXBlb2Ygcz09PSJvYmplY3QiP3Muc3RhY2s6bnVsbApy
-ZXR1cm4gdGhpcy5iPXQ9PW51bGw/IiI6dH0sCiRpR3o6MX0KSC5UcC5wcm90b3R5cGU9ewp3OmZ1bmN0
-aW9uKGEpe3ZhciB0PXRoaXMuY29uc3RydWN0b3Iscz10PT1udWxsP251bGw6dC5uYW1lCnJldHVybiJD
-bG9zdXJlICciK0guTlEocz09bnVsbD8idW5rbm93biI6cykrIicifSwKJGlFSDoxLApnUWw6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpc30sCiRDOiIkMSIsCiRSOjEsCiREOm51bGx9CkgubGMucHJvdG90eXBlPXt9
-CkguengucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLiRzdGF0aWNfbmFtZQppZih0
-PT1udWxsKXJldHVybiJDbG9zdXJlIG9mIHVua25vd24gc3RhdGljIG1ldGhvZCIKcmV0dXJuIkNsb3N1
-cmUgJyIrSC5OUSh0KSsiJyJ9fQpILnJULnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7dmFyIHQ9
-dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHQ9PT1iKXJldHVybiEwCmlmKCEoYiBpbnN0YW5jZW9m
-IEguclQpKXJldHVybiExCnJldHVybiB0LmE9PT1iLmEmJnQuYj09PWIuYiYmdC5jPT09Yi5jfSwKZ2lP
-OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5jCmlmKHM9PW51bGwpdD1ILmVRKHRoaXMuYSkKZWxzZSB0
-PXR5cGVvZiBzIT09Im9iamVjdCI/Si5oZihzKTpILmVRKHMpCnJldHVybih0XkguZVEodGhpcy5iKSk+
-Pj4wfSwKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmMKaWYodD09bnVsbCl0PXRoaXMuYQpyZXR1cm4i
-Q2xvc3VyZSAnIitILmQodGhpcy5kKSsiJyBvZiAiKygiSW5zdGFuY2Ugb2YgJyIrSC5kKEguTSh0KSkr
-IiciKX19CkguRXEucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAi
-K0guZCh0aGlzLmEpfX0KSC5rWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRp
-b24gZmFpbGVkOiAiK1AucCh0aGlzLmEpfX0KSC5ONS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5hfSwKZ1Y6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguaTUodGhpcyxILkxoKHRoaXMp
-LkMoImk1PDE+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7dmFyIHQscwppZih0eXBlb2YgYT09InN0cmluZyIp
-e3Q9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuWHUodCxhKX1lbHNle3M9dGhp
-cy5DWChhKQpyZXR1cm4gc319LApDWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQKaWYodD09bnVsbCly
-ZXR1cm4hMQpyZXR1cm4gdGhpcy5GaCh0aGlzLkJ0KHQsSi5oZihhKSYweDNmZmZmZmYpLGEpPj0wfSwK
-cTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhpcwppZih0eXBlb2YgYj09InN0cmluZyIpe3Q9
-cC5iCmlmKHQ9PW51bGwpcmV0dXJuCnM9cC5qMih0LGIpCnI9cz09bnVsbD9udWxsOnMuYgpyZXR1cm4g
-cn1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3E9cC5jCmlmKHE9
-PW51bGwpcmV0dXJuCnM9cC5qMihxLGIpCnI9cz09bnVsbD9udWxsOnMuYgpyZXR1cm4gcn1lbHNlIHJl
-dHVybiBwLmFhKGIpfSwKYWE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMuZAppZihyPT1udWxsKXJl
-dHVybgp0PXRoaXMuQnQocixKLmhmKGEpJjB4M2ZmZmZmZikKcz10aGlzLkZoKHQsYSkKaWYoczwwKXJl
-dHVybgpyZXR1cm4gdFtzXS5ifSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG49dGhp
-cyxtPUguTGgobikKbS5kLmIoYikKbS5jaFsxXS5iKGMpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7dD1u
-LmIKbi5FSCh0PT1udWxsP24uYj1uLnpLKCk6dCxiLGMpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIi
-JiYoYiYweDNmZmZmZmYpPT09Yil7cz1uLmMKbi5FSChzPT1udWxsP24uYz1uLnpLKCk6cyxiLGMpfWVs
-c2V7cj1uLmQKaWYocj09bnVsbClyPW4uZD1uLnpLKCkKcT1KLmhmKGIpJjB4M2ZmZmZmZgpwPW4uQnQo
-cixxKQppZihwPT1udWxsKW4uRUkocixxLFtuLkhuKGIsYyldKQplbHNle289bi5GaChwLGIpCmlmKG8+
-PTApcFtvXS5iPWMKZWxzZSBwLnB1c2gobi5IbihiLGMpKX19fSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscj10aGlzCkguTGgocikuQygifigxLDIpIikuYihiKQp0PXIuZQpzPXIucgpmb3IoO3QhPW51bGw7
-KXtiLiQyKHQuYSx0LmIpCmlmKHMhPT1yLnIpdGhyb3cgSC5iKFAuYTQocikpCnQ9dC5jfX0sCkVIOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdCxzPXRoaXMscj1ILkxoKHMpCnIuZC5iKGIpCnIuY2hbMV0uYihjKQp0
-PXMuajIoYSxiKQppZih0PT1udWxsKXMuRUkoYSxiLHMuSG4oYixjKSkKZWxzZSB0LmI9Y30sCmtzOmZ1
-bmN0aW9uKCl7dGhpcy5yPXRoaXMucisxJjY3MTA4ODYzfSwKSG46ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-PXRoaXMscj1ILkxoKHMpLHE9bmV3IEguZGIoci5kLmIoYSksci5jaFsxXS5iKGIpKQppZihzLmU9PW51
-bGwpcy5lPXMuZj1xCmVsc2V7dD1zLmYKcS5kPXQKcy5mPXQuYz1xfSsrcy5hCnMua3MoKQpyZXR1cm4g
-cX0sCkZoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJldHVybi0xCnQ9YS5sZW5ndGgK
-Zm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBzCnJldHVybi0xfSwKdzpmdW5j
-dGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCmoyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19LApC
-dDpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKRUk6ZnVuY3Rpb24oYSxiLGMpe2FbYl09Y30sCnJu
-OmZ1bmN0aW9uKGEsYil7ZGVsZXRlIGFbYl19LApYdTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmoy
-KGEsYikhPW51bGx9LAp6SzpmdW5jdGlvbigpe3ZhciB0PSI8bm9uLWlkZW50aWZpZXIta2V5PiIscz1P
-YmplY3QuY3JlYXRlKG51bGwpCnRoaXMuRUkocyx0LHMpCnRoaXMucm4ocyx0KQpyZXR1cm4gc30sCiRp
-Rm86MX0KSC5kYi5wcm90b3R5cGU9e30KSC5pNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5hLmF9LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLHM9bmV3IEguTjYodCx0LnIs
-dGhpcy4kdGkuQygiTjY8MT4iKSkKcy5jPXQuZQpyZXR1cm4gc319CkguTjYucHJvdG90eXBlPXsKZ2w6
-ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmEKaWYo
-dC5iIT09cy5yKXRocm93IEguYihQLmE0KHMpKQplbHNle3M9dC5jCmlmKHM9PW51bGwpe3Quc3FZKG51
-bGwpCnJldHVybiExfWVsc2V7dC5zcVkocy5hKQp0LmM9dC5jLmMKcmV0dXJuITB9fX0sCnNxWTpmdW5j
-dGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlBbjoxfQpILmRDLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoYSl9LAokUzo0fQpILndOLnByb3RvdHlwZT17CiQyOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYShhLGIpfSwKJFM6Mzh9CkguVlgucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYShILnkoYSkpfSwKJFM6Mjd9CkguVlIucHJvdG90eXBlPXsK
-dzpmdW5jdGlvbihhKXtyZXR1cm4iUmVnRXhwLyIrdGhpcy5hKyIvIit0aGlzLmIuZmxhZ3N9LApnSGM6
-ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5jCmlmKHMhPW51bGwpcmV0dXJuIHMKcz10LmIKcmV0dXJu
-IHQuYz1ILnY0KHQuYSxzLm11bHRpbGluZSwhcy5pZ25vcmVDYXNlLHMudW5pY29kZSxzLmRvdEFsbCwh
-MCl9LApkZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5LVyh0aGlzLGIsMCl9LApVWjpmdW5jdGlv
-bihhLGIpe3ZhciB0LHM9dGhpcy5nSGMoKQpzLmxhc3RJbmRleD1iCnQ9cy5leGVjKGEpCmlmKHQ9PW51
-bGwpcmV0dXJuCnJldHVybiBuZXcgSC5FSyh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3RvdHlw
-ZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILlNjKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3RoKXJl
-dHVybiBILk9IKHQsYikKcmV0dXJuIHRbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5cGU9
-ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19Ckgu
-UGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3Zh
-ciB0LHMscixxLHA9dGhpcyxvPXAuYgppZihvPT1udWxsKXJldHVybiExCnQ9cC5jCmlmKHQ8PW8ubGVu
-Z3RoKXtzPXAuYQpyPXMuVVoobyx0KQppZihyIT1udWxsKXtwLmQ9cgpvPXIuYgp0PW8uaW5kZXgKcT10
-K29bMF0ubGVuZ3RoCmlmKHQ9PT1xKXtpZihzLmIudW5pY29kZSl7bz1wLmMKdD1vKzEKcz1wLmIKaWYo
-dDxzLmxlbmd0aCl7bz1KLnJZKHMpLm0ocyxvKQppZihvPj01NTI5NiYmbzw9NTYzMTkpe289Qy54Qi5t
-KHMsdCkKbz1vPj01NjMyMCYmbzw9NTczNDN9ZWxzZSBvPSExfWVsc2Ugbz0hMX1lbHNlIG89ITEKcT0o
-bz9xKzE6cSkrMX1wLmM9cQpyZXR1cm4hMH19cC5iPXAuZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpI
-LnRRLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGIhPT0wKUgudmgoUC54KGIs
-bnVsbCkpCnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9u
-KGEpe3JldHVybiBuZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17
-CkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5hLG09
-bi5sZW5ndGgKaWYocStvPm0pe3IuZD1udWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYodDww
-KXtyLmM9bSsxCnIuZD1udWxsCnJldHVybiExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1zPT09
-ci5jP3MrMTpzCnJldHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjoxfQpI
-LkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5iMC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihh
-KXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIp
-e0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7
-SC5JZyhjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGljWDoxLAokaXpNOjF9CkguUGcucHJv
-dG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1j
-fSwKJGljWDoxLAokaXpNOjF9CkgueGoucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikK
-SC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5kRS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9u
-KGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlpBLnByb3RvdHlw
-ZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19
-Ckgud2YucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgp
-CnJldHVybiBhW2JdfX0KSC5QcS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9k
-KGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILmVFLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEp
-e3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3Ro
-KQpyZXR1cm4gYVtiXX19CkguVjYucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVu
-Z3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2Jd
-fSwKJGlWNjoxLAokaW42OjF9CkguUkcucHJvdG90eXBlPXt9CkguVlAucHJvdG90eXBlPXt9CkguV0Iu
-cHJvdG90eXBlPXt9CkguWkcucHJvdG90eXBlPXt9CkguSmMucHJvdG90eXBlPXsKQzpmdW5jdGlvbihh
-KXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSx0aGlzLGEpfSwKS3E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEgudjUodi50eXBlVW5pdmVyc2UsdGhpcyxhKX19CkguRy5wcm90b3R5cGU9e30KSC51OS5wcm90b3R5
-cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9fQpILmh6LnByb3RvdHlwZT17fQpILmlNLnBy
-b3RvdHlwZT17fQpQLnRoLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQu
-YQp0LmE9bnVsbApzLiQwKCl9LAokUzoxMn0KUC5oYS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
-YXIgdCxzCnRoaXMuYS5hPXUuTS5iKGEpCnQ9dGhpcy5iCnM9dGhpcy5jCnQuZmlyc3RDaGlsZD90LnJl
-bW92ZUNoaWxkKHMpOnQuYXBwZW5kQ2hpbGQocyl9LAokUzozOX0KUC5Wcy5wcm90b3R5cGU9ewokMDpm
-dW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5GdC5wcm90b3R5cGU9
-ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5XMy5wcm90
-b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIpe2lmKHNlbGYuc2V0VGltZW91dCE9bnVsbClzZWxmLnNldFRp
-bWVvdXQoSC50UihuZXcgUC55SCh0aGlzLGIpLDApLGEpCmVsc2UgdGhyb3cgSC5iKFAuTDQoImBzZXRU
-aW1lb3V0KClgIG5vdCBmb3VuZC4iKSl9fQpQLnlILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhp
-cy5iLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzoyfQpQLlBmLnByb3RvdHlwZT17CncwOmZ1bmN0aW9u
-KGEsYil7dmFyIHQKaWYoYT09bnVsbClhPW5ldyBQLm4oKQp0PXRoaXMuYQppZih0LmEhPT0wKXRocm93
-IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5OayhhLGIpfSwKcG06ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMudzAoYSxudWxsKX19ClAuWmYucHJvdG90eXBlPXt9ClAuRmUucHJvdG90
-eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYxNSkhPT02KXJldHVybiEwCnJldHVybiB0aGlz
-LmIuYi5idih1LmFsLmIodGhpcy5kKSxhLmEsdS5jSix1LkspfSwKS3c6ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcy5lLHM9dS56LHI9dS5LLHE9dGhpcy4kdGkuQygiMi8iKSxwPXRoaXMuYi5iCmlmKHUudy5jKHQp
-KXJldHVybiBxLmIocC5ycCh0LGEuYSxhLmIscyxyLHUubCkpCmVsc2UgcmV0dXJuIHEuYihwLmJ2KHUu
-eS5iKHQpLGEuYSxzLHIpKX19ClAudnMucHJvdG90eXBlPXsKU3E6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHMscixxPXRoaXMuJHRpCnEuS3EoYykuQygiMS8oMikiKS5iKGEpCnQ9JC5YMwppZih0IT09Qy5OVSl7
-Yy5DKCJAPDAvPiIpLktxKHEuZCkuQygiMSgyKSIpLmIoYSkKaWYoYiE9bnVsbCliPVAuVkgoYix0KX1z
-PW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpyPWI9PW51bGw/MTozCnRoaXMueGYobmV3IFAuRmUo
-cyxyLGEsYixxLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gc30sClc3OmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxsLGIpfSwKT0E6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-CnUuYmYuYihudWxsKQp0PXRoaXMuJHRpCnM9JC5YMwpyPW5ldyBQLnZzKHMsdCkKaWYocyE9PUMuTlUp
-YT1QLlZIKGEscykKdGhpcy54ZihuZXcgUC5GZShyLDIsbnVsbCxhLHQuQygiQDwxPiIpLktxKHQuZCku
-QygiRmU8MSwyPiIpKSkKcmV0dXJuIHJ9LAp4ZjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMscj1zLmEK
-aWYocjw9MSl7YS5hPXUueC5iKHMuYykKcy5jPWF9ZWxzZXtpZihyPT09Mil7dD11Ll8uYihzLmMpCnI9
-dC5hCmlmKHI8NCl7dC54ZihhKQpyZXR1cm59cy5hPXIKcy5jPXQuY31QLlRrKG51bGwsbnVsbCxzLmIs
-dS5NLmIobmV3IFAuZGEocyxhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbz10aGlz
-LG49e30Kbi5hPWEKaWYoYT09bnVsbClyZXR1cm4KdD1vLmEKaWYodDw9MSl7cz11LnguYihvLmMpCnI9
-by5jPWEKaWYocyE9bnVsbCl7Zm9yKDtxPXIuYSxxIT1udWxsO3I9cSk7ci5hPXN9fWVsc2V7aWYodD09
-PTIpe3A9dS5fLmIoby5jKQp0PXAuYQppZih0PDQpe3AualEoYSkKcmV0dXJufW8uYT10Cm8uYz1wLmN9
-bi5hPW8uTjgoYSkKUC5UayhudWxsLG51bGwsby5iLHUuTS5iKG5ldyBQLm9RKG4sbykpKX19LAphaDpm
-dW5jdGlvbigpe3ZhciB0PXUueC5iKHRoaXMuYykKdGhpcy5jPW51bGwKcmV0dXJuIHRoaXMuTjgodCl9
-LApOODpmdW5jdGlvbihhKXt2YXIgdCxzLHIKZm9yKHQ9YSxzPW51bGw7dCE9bnVsbDtzPXQsdD1yKXty
-PXQuYQp0LmE9c31yZXR1cm4gc30sCkhIOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPXMuJHRpCnIu
-QygiMS8iKS5iKGEpCmlmKHIuQygiYjg8MT4iKS5jKGEpKWlmKHIuYyhhKSlQLkE5KGEscykKZWxzZSBQ
-LmszKGEscykKZWxzZXt0PXMuYWgoKQpyLmQuYihhKQpzLmE9NApzLmM9YQpQLkhaKHMsdCl9fSwKWkw6
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMKdS5sLmIoYikKdD1zLmFoKCkKcy5hPTgKcy5jPW5ldyBQ
-LkN3KGEsYikKUC5IWihzLHQpfSwKWGY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPXQuJHRpCnMuQygi
-MS8iKS5iKGEpCmlmKHMuQygiYjg8MT4iKS5jKGEpKXt0LmNVKGEpCnJldHVybn10LmE9MQpQLlRrKG51
-bGwsbnVsbCx0LmIsdS5NLmIobmV3IFAuckgodCxhKSkpfSwKY1U6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
-cyxzPXQuJHRpCnMuQygiYjg8MT4iKS5iKGEpCmlmKHMuYyhhKSl7aWYoYS5nQVQoKSl7dC5hPTEKUC5U
-ayhudWxsLG51bGwsdC5iLHUuTS5iKG5ldyBQLktGKHQsYSkpKX1lbHNlIFAuQTkoYSx0KQpyZXR1cm59
-UC5rMyhhLHQpfSwKTms6ZnVuY3Rpb24oYSxiKXt0aGlzLmE9MQpQLlRrKG51bGwsbnVsbCx0aGlzLmIs
-dS5NLmIobmV3IFAuWkwodGhpcyxhLGIpKSl9LAokaWI4OjF9ClAuZGEucHJvdG90eXBlPXsKJDA6ZnVu
-Y3Rpb24oKXtQLkhaKHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KUC5vUS5wcm90b3R5cGU9ewokMDpmdW5j
-dGlvbigpe1AuSFoodGhpcy5iLHRoaXMuYS5hKX0sCiRTOjB9ClAucFYucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnQuYT0wCnQuSEgoYSl9LAokUzoxMn0KUC5VNy5wcm90b3R5cGU9
-ewokMjpmdW5jdGlvbihhLGIpe3UubC5iKGIpCnRoaXMuYS5aTChhLGIpfSwKJDE6ZnVuY3Rpb24oYSl7
-cmV0dXJuIHRoaXMuJDIoYSxudWxsKX0sCiRDOiIkMiIsCiREOmZ1bmN0aW9uKCl7cmV0dXJuW251bGxd
-fSwKJFM6MzR9ClAudnIucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRo
-aXMuYyl9LAokUzowfQpQLnJILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5hLHM9
-dC4kdGkuZC5iKHRoaXMuYikscj10LmFoKCkKdC5hPTQKdC5jPXMKUC5IWih0LHIpfSwKJFM6MH0KUC5L
-Ri5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuQTkodGhpcy5iLHRoaXMuYSl9LAokUzowfQpQLlpM
-LnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwKJFM6MH0K
-UC5SVC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMsbT1udWxs
-CnRyeXtyPW4uYwptPXIuYi5iLnp6KHUuZk8uYihyLmQpLHUueil9Y2F0Y2gocSl7dD1ILlJ1KHEpCnM9
-SC50cyhxKQppZihuLmQpe3I9dS5uLmIobi5hLmEuYykuYQpwPXQKcD1yPT1udWxsP3A9PW51bGw6cj09
-PXAKcj1wfWVsc2Ugcj0hMQpwPW4uYgppZihyKXAuYj11Lm4uYihuLmEuYS5jKQplbHNlIHAuYj1uZXcg
-UC5Ddyh0LHMpCnAuYT0hMApyZXR1cm59aWYodS5jLmMobSkpe2lmKG0gaW5zdGFuY2VvZiBQLnZzJiZt
-LmE+PTQpe2lmKG0uYT09PTgpe3I9bi5iCnIuYj11Lm4uYihtLmMpCnIuYT0hMH1yZXR1cm59bz1uLmEu
-YQpyPW4uYgpyLmI9bS5XNyhuZXcgUC5qWihvKSx1LnopCnIuYT0hMX19LAokUzoyfQpQLmpaLnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokUzozM30KUC5ycS5wcm90b3R5cGU9
-ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG09dGhpcwp0cnl7cj1tLmIKcT1yLiR0aQpw
-PXEuZApvPXAuYihtLmMpCm0uYS5iPXIuYi5iLmJ2KHEuQygiMi8oMSkiKS5iKHIuZCksbyxxLkMoIjIv
-IikscCl9Y2F0Y2gobil7dD1ILlJ1KG4pCnM9SC50cyhuKQpyPW0uYQpyLmI9bmV3IFAuQ3codCxzKQpy
-LmE9ITB9fSwKJFM6Mn0KUC5SVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAs
-byxuLG0sbD10aGlzCnRyeXt0PXUubi5iKGwuYS5hLmMpCnE9bC5jCmlmKEgub1QocS5IUih0KSkmJnEu
-ZSE9bnVsbCl7cD1sLmIKcC5iPXEuS3codCkKcC5hPSExfX1jYXRjaChvKXtzPUguUnUobykKcj1ILnRz
-KG8pCnE9dS5uLmIobC5hLmEuYykKcD1xLmEKbj1zCm09bC5iCmlmKHA9PW51bGw/bj09bnVsbDpwPT09
-biltLmI9cQplbHNlIG0uYj1uZXcgUC5DdyhzLHIpCm0uYT0hMH19LAokUzoyfQpQLk9NLnByb3RvdHlw
-ZT17fQpQLnFoLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9e30scD1u
-ZXcgUC52cygkLlgzLHUuZkopCnEuYT0wCnQ9SC5MaChyKQpzPXQuQygifigxKSIpLmIobmV3IFAuQjUo
-cSxyKSkKdS5NLmIobmV3IFAuUEkocSxwKSkKVy5KRShyLmEsci5iLHMsITEsdC5kKQpyZXR1cm4gcH19
-ClAuQjUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC5MaCh0aGlzLmIpLmQuYihhKTsrK3RoaXMu
-YS5hfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmIpLkMoImM4KDEpIil9fQpQLlBJLnBy
-b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJv
-dG90eXBlPXt9ClAua1QucHJvdG90eXBlPXt9ClAuQ3cucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXty
-ZXR1cm4gSC5kKHRoaXMuYSl9LAokaVhTOjF9ClAubTAucHJvdG90eXBlPXskaUpCOjF9ClAucEsucHJv
-dG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMuYSxyPXMuYQpzPXI9PW51bGw/cy5hPW5l
-dyBQLm4oKTpyCnI9dGhpcy5iCmlmKHI9PW51bGwpdGhyb3cgSC5iKHMpCnQ9SC5iKHMpCnQuc3RhY2s9
-ci53KDApCnRocm93IHR9LAokUzowfQpQLkppLnByb3RvdHlwZT17CmJIOmZ1bmN0aW9uKGEpe3ZhciB0
-LHMscixxPW51bGwKdS5NLmIoYSkKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQwKCkKcmV0dXJufVAuVDgo
-cSxxLHRoaXMsYSx1LkgpfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5MMihxLHEsdGhpcyx0
-LHUubC5iKHMpKX19LApEbDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9bnVsbApjLkMoIn4oMCki
-KS5iKGEpCmMuYihiKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDEoYikKcmV0dXJufVAueXYocSxxLHRo
-aXMsYSxiLHUuSCxjKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIocSxxLHRoaXMsdCx1
-LmwuYihzKSl9fSwKUlQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuaGoodGhpcyxiLkMoIjAoKSIp
-LmIoYSksYil9LApHWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVnAodGhpcyx1Lk0uYihhKSl9LApQ
-eTpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5PUih0aGlzLGIuQygifigwKSIpLmIoYSksYil9LApx
-OmZ1bmN0aW9uKGEsYil7cmV0dXJufSwKeno6ZnVuY3Rpb24oYSxiKXtiLkMoIjAoKSIpLmIoYSkKaWYo
-JC5YMz09PUMuTlUpcmV0dXJuIGEuJDAoKQpyZXR1cm4gUC5UOChudWxsLG51bGwsdGhpcyxhLGIpfSwK
-YnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5DKCJAPDA+IikuS3EoZCkuQygiMSgyKSIpLmIoYSkKZC5iKGIp
-CmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQxKGIpCnJldHVybiBQLnl2KG51bGwsbnVsbCx0aGlzLGEs
-YixjLGQpfSwKcnA6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2QuQygiQDwwPiIpLktxKGUpLktxKGYpLkMo
-IjEoMiwzKSIpLmIoYSkKZS5iKGIpCmYuYihjKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMihiLGMp
-CnJldHVybiBQLlF4KG51bGwsbnVsbCx0aGlzLGEsYixjLGQsZSxmKX19ClAuaGoucHJvdG90eXBlPXsK
-JDA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLnp6KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24o
-KXtyZXR1cm4gdGhpcy5jLkMoIjAoKSIpfX0KUC5WcC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3Jl
-dHVybiB0aGlzLmEuYkgodGhpcy5iKX0sCiRTOjJ9ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0aGlzLmEuRGwodGhpcy5iLHQuYihhKSx0KX0sCiRTOmZ1bmN0
-aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCJ+KDApIil9fQpQLmI2LnByb3RvdHlwZT17CmdrejpmdW5jdGlv
-bihhKXt2YXIgdD10aGlzLHM9bmV3IFAubG0odCx0LnIsSC5MaCh0KS5DKCJsbTwxPiIpKQpzLmM9dC5l
-CnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCnRnOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscwppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19wcm90b19fIil7dD10aGlzLmIKaWYo
-dD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5KLmIodFtiXSkhPW51bGx9ZWxzZXtzPXRoaXMuUFIoYikK
-cmV0dXJuIHN9fSwKUFI6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuITEK
-cmV0dXJuIHRoaXMuREYodFt0aGlzLk4oYSldLGEpPj0wfSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cj10aGlzCkguTGgocikuZC5iKGIpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18i
-KXt0PXIuYgpyZXR1cm4gci5iUSh0PT1udWxsP3IuYj1QLlQyKCk6dCxiKX1lbHNlIGlmKHR5cGVvZiBi
-PT0ibnVtYmVyIiYmKGImMTA3Mzc0MTgyMyk9PT1iKXtzPXIuYwpyZXR1cm4gci5iUShzPT1udWxsP3Iu
-Yz1QLlQyKCk6cyxiKX1lbHNlIHJldHVybiByLkI3KGIpfSwKQjc6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHE9dGhpcwpILkxoKHEpLmQuYihhKQp0PXEuZAppZih0PT1udWxsKXQ9cS5kPVAuVDIoKQpzPXEuTihh
-KQpyPXRbc10KaWYocj09bnVsbCl0W3NdPVtxLnlvKGEpXQplbHNle2lmKHEuREYocixhKT49MClyZXR1
-cm4hMQpyLnB1c2gocS55byhhKSl9cmV0dXJuITB9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwpp
-Zih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19wcm90b19fIilyZXR1cm4gdC5MKHQuYixiKQplbHNl
-IGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMTA3Mzc0MTgyMyk9PT1iKXJldHVybiB0LkwodC5jLGIp
-CmVsc2UgcmV0dXJuIHQucWcoYil9LApxZzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1w
-LmQKaWYobz09bnVsbClyZXR1cm4hMQp0PXAuTihhKQpzPW9bdF0Kcj1wLkRGKHMsYSkKaWYocjwwKXJl
-dHVybiExCnE9cy5zcGxpY2UociwxKVswXQppZigwPT09cy5sZW5ndGgpZGVsZXRlIG9bdF0KcC5HUyhx
-KQpyZXR1cm4hMH0sCmJROmZ1bmN0aW9uKGEsYil7SC5MaCh0aGlzKS5kLmIoYikKaWYodS5KLmIoYVti
-XSkhPW51bGwpcmV0dXJuITEKYVtiXT10aGlzLnlvKGIpCnJldHVybiEwfSwKTDpmdW5jdGlvbihhLGIp
-e3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuITEKdD11LkouYihhW2JdKQppZih0PT1udWxsKXJldHVybiEx
-CnRoaXMuR1ModCkKZGVsZXRlIGFbYl0KcmV0dXJuITB9LApTOmZ1bmN0aW9uKCl7dGhpcy5yPTEwNzM3
-NDE4MjMmdGhpcy5yKzF9LAp5bzpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMscj1uZXcgUC5ibihILkxo
-KHMpLmQuYihhKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9cgplbHNle3Q9cy5mCnIuYz10CnMuZj10LmI9
-cn0rK3MuYQpzLlMoKQpyZXR1cm4gcn0sCkdTOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hLmMscj1h
-LmIKaWYocz09bnVsbCl0LmU9cgplbHNlIHMuYj1yCmlmKHI9PW51bGwpdC5mPXMKZWxzZSByLmM9czst
-LXQuYQp0LlMoKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJuIEouaGYoYSkmMTA3Mzc0MTgyM30sCkRGOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJldHVybi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtz
-PHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBzCnJldHVybi0xfX0KUC5ibi5wcm90b3R5cGU9
-e30KUC5sbS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9u
-KCl7dmFyIHQ9dGhpcyxzPXQuYQppZih0LmIhPT1zLnIpdGhyb3cgSC5iKFAuYTQocykpCmVsc2V7cz10
-LmMKaWYocz09bnVsbCl7dC5zaihudWxsKQpyZXR1cm4hMX1lbHNle3Quc2oodC4kdGkuZC5iKHMuYSkp
-CnQuYz10LmMuYgpyZXR1cm4hMH19fSwKc2o6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihh
-KX0sCiRpQW46MX0KUC5tVy5wcm90b3R5cGU9e30KUC5MVS5wcm90b3R5cGU9eyRpY1g6MSwkaXpNOjF9
-ClAubEQucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5hNyhhLHRoaXMuZ0Eo
-YSksSC56SyhhKS5DKCJhNzxsRC5FPiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5xKGEs
-Yil9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnpLKGEpLkMoIn4obEQuRSkiKS5iKGIpCnQ9dGhp
-cy5nQShhKQpmb3Iocz0wO3M8dDsrK3Mpe2IuJDEodGhpcy5xKGEscykpCmlmKHQhPT10aGlzLmdBKGEp
-KXRocm93IEguYihQLmE0KGEpKX19LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC56SyhhKQpyZXR1
-cm4gbmV3IEguQTgoYSx0LktxKGMpLkMoIjEobEQuRSkiKS5iKGIpLHQuQygiQDxsRC5FPiIpLktxKGMp
-LkMoIkE4PDEsMj4iKSl9LApkdTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdApILnpLKGEpLkMoImxELkUi
-KS5iKGQpClAuakIoYixjLHRoaXMuZ0EoYSkpCmZvcih0PWI7dDxjOysrdCl0aGlzLlkoYSx0LGQpfSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gUC5XRShhLCJbIiwiXSIpfX0KUC5pbC5wcm90b3R5cGU9e30KUC5H
-QS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5hCmlmKCFzLmEpdGhpcy5i
-LmErPSIsICIKcy5hPSExCnM9dGhpcy5iCnQ9cy5hKz1ILmQoYSkKcy5hPXQrIjogIgpzLmErPUguZChi
-KX0sCiRTOjF9ClAuWWsucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC5MaCh0aGlz
-KS5DKCJ+KFlrLkssWWsuVikiKS5iKGIpCmZvcih0PUouSVQodGhpcy5nVigpKTt0LkYoKTspe3M9dC5n
-bCgpCmIuJDIocyx0aGlzLnEoMCxzKSl9fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5n
-VigpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LAokaVowOjF9ClAuS1AucHJvdG90
-eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmQuYihiKQp0LmNoWzFdLmIo
-YykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIG1hcCIpKX19ClAuUG4u
-cHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEucSgwLGIpfSwKWTpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0aGlzLmEuWSgwLHQuZC5iKGIpLHQuY2hbMV0uYihjKSl9
-LApLOmZ1bmN0aW9uKGEsYil7dGhpcy5hLksoMCxILkxoKHRoaXMpLkMoIn4oMSwyKSIpLmIoYikpfSwK
-Z0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdBKHQpfSwKdzpmdW5jdGlvbihhKXty
-ZXR1cm4gSi5qKHRoaXMuYSl9LAokaVowOjF9ClAuR2oucHJvdG90eXBlPXt9ClAubGYucHJvdG90eXBl
-PXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5XRSh0aGlzLCJ7IiwifSIpfX0KUC5Wai5wcm90b3R5cGU9
-eyRpY1g6MSwkaXh1OjF9ClAuWHYucHJvdG90eXBlPXsKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3Io
-dD1KLklUKEguTGgodGhpcykuQygiY1g8MT4iKS5iKGIpKTt0LkYoKTspdGhpcy5pKDAsdC5nbCgpKX0s
-Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0iKX0sCkg6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzPVAucmoodGhpcyx0aGlzLnIsSC5MaCh0aGlzKS5kKQppZighcy5GKCkpcmV0dXJuIiIKaWYo
-Yj09PSIiKXt0PSIiCmRvIHQrPUguZChzLmQpCndoaWxlKHMuRigpKX1lbHNle3Q9SC5kKHMuZCkKZm9y
-KDtzLkYoKTspdD10K2IrSC5kKHMuZCl9cmV0dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaWNY
-OjEsCiRpeHU6MX0KUC5uWS5wcm90b3R5cGU9e30KUC5XWS5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5
-cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09
-bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4K
-ZWxzZXt0PXNbYl0KcmV0dXJuIHR5cGVvZiB0PT0idW5kZWZpbmVkIj90aGlzLmZiKGIpOnR9fSwKZ0E6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYj09bnVsbD90aGlzLmMuYTp0aGlzLkNmKCkubGVuZ3RofSwK
-Z1Y6ZnVuY3Rpb24oKXtpZih0aGlzLmI9PW51bGwpe3ZhciB0PXRoaXMuYwpyZXR1cm4gbmV3IEguaTUo
-dCxILkxoKHQpLkMoImk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0aGlzKX0sClk6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciB0LHMscj10aGlzCmlmKHIuYj09bnVsbClyLmMuWSgwLGIsYykKZWxzZSBpZihyLng0KGIp
-KXt0PXIuYgp0W2JdPWMKcz1yLmEKaWYocz09bnVsbD90IT1udWxsOnMhPT10KXNbYl09bnVsbH1lbHNl
-IHIuWEsoKS5ZKDAsYixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhp
-cy5jLng0KGEpCnJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5h
-LGEpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhpcwp1LmNBLmIoYikKaWYocC5iPT1u
-dWxsKXJldHVybiBwLmMuSygwLGIpCnQ9cC5DZigpCmZvcihzPTA7czx0Lmxlbmd0aDsrK3Mpe3I9dFtz
-XQpxPXAuYltyXQppZih0eXBlb2YgcT09InVuZGVmaW5lZCIpe3E9UC5RZShwLmFbcl0pCnAuYltyXT1x
-fWIuJDIocixxKQppZih0IT09cC5jKXRocm93IEguYihQLmE0KHApKX19LApDZjpmdW5jdGlvbigpe3Zh
-ciB0PXUuai5iKHRoaXMuYykKaWYodD09bnVsbCl0PXRoaXMuYz1ILlZNKE9iamVjdC5rZXlzKHRoaXMu
-YSksdS5zKQpyZXR1cm4gdH0sClhLOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvPXRoaXMKaWYoby5i
-PT1udWxsKXJldHVybiBvLmMKdD1QLkZsKHUuTix1LnopCnM9by5DZigpCmZvcihyPTA7cT1zLmxlbmd0
-aCxyPHE7KytyKXtwPXNbcl0KdC5ZKDAscCxvLnEoMCxwKSl9aWYocT09PTApQy5ObS5pKHMsbnVsbCkK
-ZWxzZSBDLk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBvLmM9dH0sCmZiOmZ1bmN0aW9uKGEp
-e3ZhciB0CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpKXJl
-dHVybgp0PVAuUWUodGhpcy5hW2FdKQpyZXR1cm4gdGhpcy5iW2FdPXR9fQpQLmk4LnByb3RvdHlwZT17
-CmdBOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nQSh0KX0sCkU6ZnVuY3Rpb24oYSxi
-KXt2YXIgdD10aGlzLmEKaWYodC5iPT1udWxsKXQ9dC5nVigpLkUoMCxiKQplbHNle3Q9dC5DZigpCmlm
-KGI8MHx8Yj49dC5sZW5ndGgpcmV0dXJuIEguT0godCxiKQp0PXRbYl19cmV0dXJuIHR9LApna3o6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQuYj09bnVsbCl7dD10LmdWKCkKdD10Lmdreih0KX1lbHNl
-e3Q9dC5DZigpCnQ9bmV3IEoubTEodCx0Lmxlbmd0aCxILnQ2KHQpLkMoIm0xPDE+IikpfXJldHVybiB0
-fX0KUC5DVi5wcm90b3R5cGU9ewp5cjpmdW5jdGlvbihhLGEwLGExKXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsayxqLGksaCxnLGYsZSxkLGMsYj0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3RoICIKYTE9
-UC5qQihhMCxhMSxhLmxlbmd0aCkKdD0kLlY3KCkKZm9yKHM9YTAscj1zLHE9bnVsbCxwPS0xLG89LTEs
-bj0wO3M8YTE7cz1tKXttPXMrMQpsPUMueEIuVyhhLHMpCmlmKGw9PT0zNyl7az1tKzIKaWYoazw9YTEp
-e2o9SC5vbyhDLnhCLlcoYSxtKSkKaT1ILm9vKEMueEIuVyhhLG0rMSkpCmg9aioxNitpLShpJjI1NikK
-aWYoaD09PTM3KWg9LTEKbT1rfWVsc2UgaD0tMX1lbHNlIGg9bAppZigwPD1oJiZoPD0xMjcpe2lmKGg8
-MHx8aD49dC5sZW5ndGgpcmV0dXJuIEguT0godCxoKQpnPXRbaF0KaWYoZz49MCl7aD1DLnhCLm0oIkFC
-Q0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5
-Ky8iLGcpCmlmKGg9PT1sKWNvbnRpbnVlCmw9aH1lbHNle2lmKGc9PT0tMSl7aWYocDwwKXtmPXE9PW51
-bGw/bnVsbDpxLmEubGVuZ3RoCmlmKGY9PW51bGwpZj0wCnA9Zisocy1yKQpvPXN9KytuCmlmKGw9PT02
-MSljb250aW51ZX1sPWh9aWYoZyE9PS0yKXtpZihxPT1udWxsKXE9bmV3IFAuUm4oIiIpCnEuYSs9Qy54
-Qi5OaihhLHIscykKcS5hKz1ILkx3KGwpCnI9bQpjb250aW51ZX19dGhyb3cgSC5iKFAucnIoIkludmFs
-aWQgYmFzZTY0IGRhdGEiLGEscykpfWlmKHEhPW51bGwpe2Y9cS5hKz1DLnhCLk5qKGEscixhMSkKZT1m
-Lmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAsbixlKQplbHNle2Q9Qy5qbi56WShlLTEsNCkrMQpp
-ZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEpKQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9ZjsrK2R9
-fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEsZi5jaGFyQ29kZUF0KDApPT0wP2Y6Zil9Yz1hMS1h
-MAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQplbHNle2Q9Qy5qbi56WShjLDQpCmlmKGQ9PT0xKXRo
-cm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlhPUMueEIuaTcoYSxhMSxhMSxkPT09Mj8iPT0iOiI9
-Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17fQpQLndJLnByb3Rv
-dHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLmJ5LnByb3RvdHlwZT17CnBXOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdAp1LmVwLmIoYykKdD1QLkJTKGIsdGhpcy5nSGUoKS5hKQpyZXR1cm4gdH0sCmdIZTpmdW5j
-dGlvbigpe3JldHVybiBDLkEzfX0KUC5NeC5wcm90b3R5cGU9e30KUC51NS5wcm90b3R5cGU9ewpnWkU6
-ZnVuY3Rpb24oKXtyZXR1cm4gQy5Ra319ClAuRTMucHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFy
-IHQscyxyPVAuakIoMCxudWxsLGEubGVuZ3RoKSxxPXItMAppZihxPT09MClyZXR1cm4gbmV3IFVpbnQ4
-QXJyYXkoMCkKdD1uZXcgVWludDhBcnJheShxKjMpCnM9bmV3IFAuUncodCkKaWYocy5HeChhLDAscikh
-PT1yKXMuTzYoSi5hNihhLHItMSksMCkKcmV0dXJuIG5ldyBVaW50OEFycmF5KHQuc3ViYXJyYXkoMCxI
-LnJNKDAscy5iLHQubGVuZ3RoKSkpfX0KUC5Sdy5wcm90b3R5cGU9ewpPNjpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHM9dGhpcyxyPXMuYyxxPXMuYixwPXErMSxvPXIubGVuZ3RoCmlmKChiJjY0NTEyKT09PTU2MzIw
-KXt0PTY1NTM2KygoYSYxMDIzKTw8MTApfGImMTAyMwpzLmI9cAppZihxPj1vKXJldHVybiBILk9IKHIs
-cSkKcltxXT0yNDB8dD4+PjE4CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT0x
-Mjh8dD4+PjEyJjYzCnA9cy5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0xMjh8dD4+
-PjYmNjMKcy5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT0xMjh8dCY2MwpyZXR1cm4h
-MH1lbHNle3MuYj1wCmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTIyNHxhPj4+MTIKcT1zLmI9
-cCsxCmlmKHA+PW8pcmV0dXJuIEguT0gocixwKQpyW3BdPTEyOHxhPj4+NiY2MwpzLmI9cSsxCmlmKHE+
-PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTEyOHxhJjYzCnJldHVybiExfX0sCkd4OmZ1bmN0aW9uKGEs
-YixjKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMKaWYoYiE9PWMmJihDLnhCLm0oYSxjLTEpJjY0NTEy
-KT09PTU1Mjk2KS0tYwpmb3IodD1tLmMscz10Lmxlbmd0aCxyPWI7cjxjOysrcil7cT1DLnhCLlcoYSxy
-KQppZihxPD0xMjcpe3A9bS5iCmlmKHA+PXMpYnJlYWsKbS5iPXArMQp0W3BdPXF9ZWxzZSBpZigocSY2
-NDUxMik9PT01NTI5Nil7aWYobS5iKzM+PXMpYnJlYWsKbz1yKzEKaWYobS5PNihxLEMueEIuVyhhLG8p
-KSlyPW99ZWxzZSBpZihxPD0yMDQ3KXtwPW0uYgpuPXArMQppZihuPj1zKWJyZWFrCm0uYj1uCmlmKHA+
-PXMpcmV0dXJuIEguT0godCxwKQp0W3BdPTE5MnxxPj4+NgptLmI9bisxCnRbbl09MTI4fHEmNjN9ZWxz
-ZXtwPW0uYgppZihwKzI+PXMpYnJlYWsKbj1tLmI9cCsxCmlmKHA+PXMpcmV0dXJuIEguT0godCxwKQp0
-W3BdPTIyNHxxPj4+MTIKcD1tLmI9bisxCmlmKG4+PXMpcmV0dXJuIEguT0godCxuKQp0W25dPTEyOHxx
-Pj4+NiY2MwptLmI9cCsxCmlmKHA+PXMpcmV0dXJuIEguT0godCxwKQp0W3BdPTEyOHxxJjYzfX1yZXR1
-cm4gcn19ClAuR1kucHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxs
-CnUuTC5iKGEpCnQ9UC5reSghMSxhLDAsbnVsbCkKaWYodCE9bnVsbClyZXR1cm4gdApzPVAuakIoMCxu
-dWxsLEouSG0oYSkpCnI9UC53RyhhLDAscykKaWYocj4wKXtxPVAuSE0oYSwwLHIpCmlmKHI9PT1zKXJl
-dHVybiBxCnA9bmV3IFAuUm4ocSkKbz1yCm49ITF9ZWxzZXtvPTAKcD1udWxsCm49ITB9aWYocD09bnVs
-bClwPW5ldyBQLlJuKCIiKQptPW5ldyBQLmJ6KCExLHApCm0uYz1uCm0uTUUoYSxvLHMpCmlmKG0uZT4w
-KXtILnZoKFAucnIoIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQgc2VxdWVuY2UiLGEscykpCnAuYSs9SC5M
-dyg2NTUzMykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpyZXR1cm4gbC5jaGFyQ29kZUF0KDApPT0wP2w6bH19
-ClAuYnoucHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxr
-LGosaSxoPXRoaXMsZz0iQmFkIFVURi04IGVuY29kaW5nIDB4Igp1LkwuYihhKQp0PWguZApzPWguZQpy
-PWguZgpoLmY9aC5lPWguZD0wCiRsYWJlbDAkMDpmb3IocT1KLlU2KGEpLHA9aC5iLG89YjshMDtvPWop
-eyRsYWJlbDEkMTppZihzPjApe2Rve2lmKG89PT1jKWJyZWFrICRsYWJlbDAkMApuPXEucShhLG8pCmlm
-KHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4uek0oKQppZigobiYxOTIpIT09MTI4KXttPVAucnIo
-ZytDLmpuLldaKG4sMTYpLGEsbykKdGhyb3cgSC5iKG0pfWVsc2V7dD0odDw8NnxuJjYzKT4+PjA7LS1z
-Oysrb319d2hpbGUocz4wKQptPXItMQppZihtPDB8fG0+PTQpcmV0dXJuIEguT0goQy5HYixtKQppZih0
-PD1DLkdiW21dKXttPVAucnIoIk92ZXJsb25nIGVuY29kaW5nIG9mIDB4IitDLmpuLldaKHQsMTYpLGEs
-by1yLTEpCnRocm93IEguYihtKX1pZih0PjExMTQxMTEpe209UC5ycigiQ2hhcmFjdGVyIG91dHNpZGUg
-dmFsaWQgVW5pY29kZSByYW5nZTogMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0p
-fWlmKCFoLmN8fHQhPT02NTI3OSlwLmErPUguTHcodCkKaC5jPSExfWZvcihtPW88YzttOyl7bD1QLndH
-KGEsbyxjKQppZihsPjApe2guYz0hMQprPW8rbApwLmErPVAuSE0oYSxvLGspCmlmKGs9PT1jKWJyZWFr
-fWVsc2Ugaz1vCmo9aysxCm49cS5xKGEsaykKaWYodHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5K
-KCkKaWYobjwwKXtpPVAucnIoIk5lZ2F0aXZlIFVURi04IGNvZGUgdW5pdDogLTB4IitDLmpuLldaKC1u
-LDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfWVsc2V7aWYoKG4mMjI0KT09PTE5Mil7dD1uJjMxCnM9MQpy
-PTEKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0MCk9PT0yMjQpe3Q9biYxNQpzPTIKcj0yCmNvbnRp
-bnVlICRsYWJlbDAkMH1pZigobiYyNDgpPT09MjQwJiZuPDI0NSl7dD1uJjcKcz0zCnI9Mwpjb250aW51
-ZSAkbGFiZWwwJDB9aT1QLnJyKGcrQy5qbi5XWihuLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfX1icmVh
-ayAkbGFiZWwwJDB9aWYocz4wKXtoLmQ9dApoLmU9cwpoLmY9cn19fQpQLldGLnByb3RvdHlwZT17CiQy
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCnUuZm8uYihhKQp0PXRoaXMuYgpzPXRoaXMuYQp0LmErPXMu
-YQpyPXQuYSs9SC5kKGEuYSkKdC5hPXIrIjogIgp0LmErPVAucChiKQpzLmE9IiwgIn0sCiRTOjI2fQpQ
-LmEyLnByb3RvdHlwZT17fQpQLmlQLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVs
-bClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAuaVAmJnRoaXMuYT09PWIuYSYmITB9LApnaU86
-ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybih0XkMuam4ud0codCwzMCkpJjEwNzM3NDE4MjN9
-LAp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1QLkdxKEgudEoodCkpLHI9UC5oMChILk5TKHQpKSxx
-PVAuaDAoSC5qQSh0KSkscD1QLmgwKEguS0wodCkpLG89UC5oMChILmNoKHQpKSxuPVAuaDAoSC5KZCh0
-KSksbT1QLlZ4KEgubzEodCkpLGw9cysiLSIrcisiLSIrcSsiICIrcCsiOiIrbysiOiIrbisiLiIrbQpy
-ZXR1cm4gbH19ClAuQ1AucHJvdG90eXBlPXt9ClAuWFMucHJvdG90eXBlPXt9ClAuQzYucHJvdG90eXBl
-PXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKaWYodCE9bnVsbClyZXR1cm4iQXNzZXJ0aW9uIGZh
-aWxlZDogIitQLnAodCkKcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQifX0KUC5uLnByb3RvdHlwZT17Cnc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIlRocm93IG9mIG51bGwuIn19ClAudS5wcm90b3R5cGU9ewpnWjpmdW5j
-dGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3VtZW50IisoIXRoaXMuYT8iKHMpIjoiIil9LApndTpmdW5j
-dGlvbigpe3JldHVybiIifSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1wLmMsbj1v
-IT1udWxsPyIgKCIrbysiKSI6IiIKbz1wLmQKdD1vPT1udWxsPyIiOiI6ICIrSC5kKG8pCnM9cC5nWigp
-K24rdAppZighcC5hKXJldHVybiBzCnI9cC5ndSgpCnE9UC5wKHAuYikKcmV0dXJuIHMrcisiOiAiK3F9
-fQpQLmJKLnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVu
-Y3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5lCmlmKHI9PW51bGwpe3I9dGhpcy5mCnQ9ciE9bnVsbD8iOiBO
-b3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICIrSC5kKHIpOiIifWVsc2V7cz10aGlzLmYKaWYocz09bnVs
-bCl0PSI6IE5vdCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gIitILmQocikKZWxzZSBpZihzPnIpdD0i
-OiBOb3QgaW4gcmFuZ2UgIitILmQocikrIi4uIitILmQocykrIiwgaW5jbHVzaXZlIgplbHNlIHQ9czxy
-PyI6IFZhbGlkIHZhbHVlIHJhbmdlIGlzIGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5k
-KHIpfXJldHVybiB0fX0KUC5lWS5wcm90b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVy
-cm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQscz1ILlNjKHRoaXMuYikKaWYodHlwZW9mIHMhPT0ibnVt
-YmVyIilyZXR1cm4gcy5KKCkKaWYoczwwKXJldHVybiI6IGluZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZl
-Igp0PXRoaXMuZgppZih0PT09MClyZXR1cm4iOiBubyBpbmRpY2VzIGFyZSB2YWxpZCIKcmV0dXJuIjog
-aW5kZXggc2hvdWxkIGJlIGxlc3MgdGhhbiAiK0guZCh0KX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0
-aGlzLmZ9fQpQLm1wLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxs
-PXRoaXMsaz17fSxqPW5ldyBQLlJuKCIiKQprLmE9IiIKZm9yKHQ9bC5jLHM9dC5sZW5ndGgscj0wLHE9
-IiIscD0iIjtyPHM7KytyLHA9IiwgIil7bz10W3JdCmouYT1xK3AKcT1qLmErPVAucChvKQprLmE9Iiwg
-In1sLmQuSygwLG5ldyBQLldGKGssaikpCm49UC5wKGwuYSkKbT1qLncoMCkKdD0iTm9TdWNoTWV0aG9k
-RXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK0guZChsLmIuYSkrIidcblJlY2VpdmVyOiAiK24rIlxu
-QXJndW1lbnRzOiBbIittKyJdIgpyZXR1cm4gdH19ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
-KXtyZXR1cm4iVW5zdXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsK
-dzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJv
-cjogIit0OiJVbmltcGxlbWVudGVkRXJyb3IifX0KUC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEp
-e3JldHVybiJCYWQgc3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEp
-e3ZhciB0PXRoaXMuYQppZih0PT1udWxsKXJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJp
-bmcgaXRlcmF0aW9uLiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRp
-b246ICIrUC5wKHQpKyIuIn19ClAuazUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0
-IG9mIE1lbW9yeSJ9LAokaVhTOjF9ClAuS1kucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4i
-U3RhY2sgT3ZlcmZsb3cifSwKJGlYUzoxfQpQLmMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIg
-dD10aGlzLmEKcmV0dXJuIHQ9PW51bGw/IlJlYWRpbmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBpdHMg
-aW5pdGlhbGl6YXRpb24iOiJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSAnIit0KyInIGR1cmluZyBpdHMg
-aW5pdGlhbGl6YXRpb24ifX0KUC5DRC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJFeGNl
-cHRpb246ICIrdGhpcy5hfX0KUC5hRS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
-LHAsbyxuLG0sbCxrLGosaSxoPXRoaXMuYSxnPWghPW51bGwmJiIiIT09aD8iRm9ybWF0RXhjZXB0aW9u
-OiAiK0guZChoKToiRm9ybWF0RXhjZXB0aW9uIixmPXRoaXMuYyxlPXRoaXMuYgppZih0eXBlb2YgZT09
-InN0cmluZyIpe2lmKGYhPW51bGwpaD1mPDB8fGY+ZS5sZW5ndGgKZWxzZSBoPSExCmlmKGgpZj1udWxs
-CmlmKGY9PW51bGwpe3Q9ZS5sZW5ndGg+Nzg/Qy54Qi5OaihlLDAsNzUpKyIuLi4iOmUKcmV0dXJuIGcr
-IlxuIit0fWZvcihzPTEscj0wLHE9ITEscD0wO3A8ZjsrK3Ape289Qy54Qi5XKGUscCkKaWYobz09PTEw
-KXtpZihyIT09cHx8IXEpKytzCnI9cCsxCnE9ITF9ZWxzZSBpZihvPT09MTMpeysrcwpyPXArMQpxPSEw
-fX1nPXM+MT9nKygiIChhdCBsaW5lICIrcysiLCBjaGFyYWN0ZXIgIisoZi1yKzEpKyIpXG4iKTpnKygi
-IChhdCBjaGFyYWN0ZXIgIisoZisxKSsiKVxuIikKbj1lLmxlbmd0aApmb3IocD1mO3A8bjsrK3Ape289
-Qy54Qi5tKGUscCkKaWYobz09PTEwfHxvPT09MTMpe249cApicmVha319aWYobi1yPjc4KWlmKGYtcjw3
-NSl7bT1yKzc1Cmw9cgprPSIiCmo9Ii4uLiJ9ZWxzZXtpZihuLWY8NzUpe2w9bi03NQptPW4Kaj0iIn1l
-bHNle2w9Zi0zNgptPWYrMzYKaj0iLi4uIn1rPSIuLi4ifWVsc2V7bT1uCmw9cgprPSIiCmo9IiJ9aT1D
-LnhCLk5qKGUsbCxtKQpyZXR1cm4gZytrK2kraisiXG4iK0MueEIuSXgoIiAiLGYtbCtrLmxlbmd0aCkr
-Il5cbiJ9ZWxzZSByZXR1cm4gZiE9bnVsbD9nKygiIChhdCBvZmZzZXQgIitILmQoZikrIikiKTpnfX0K
-UC5FSC5wcm90b3R5cGU9e30KUC5LTi5wcm90b3R5cGU9e30KUC5jWC5wcm90b3R5cGU9ewpldjpmdW5j
-dGlvbihhLGIpe3ZhciB0PUguTGgodGhpcykKcmV0dXJuIG5ldyBILlU1KHRoaXMsdC5DKCJhMihjWC5F
-KSIpLmIoYiksdC5DKCJVNTxjWC5FPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5na3oo
-dGhpcykKZm9yKHQ9MDtzLkYoKTspKyt0CnJldHVybiB0fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0
-aGlzLmdreih0aGlzKS5GKCl9LApncjg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmdreih0aGlzKQpp
-Zighcy5GKCkpdGhyb3cgSC5iKEguV3AoKSkKdD1zLmdsKCkKaWYocy5GKCkpdGhyb3cgSC5iKEguZFUo
-KSkKcmV0dXJuIHR9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyClAuazEoYiwiaW5kZXgiKQpmb3Io
-dD10aGlzLmdreih0aGlzKSxzPTA7dC5GKCk7KXtyPXQuZ2woKQppZihiPT09cylyZXR1cm4gcjsrK3N9
-dGhyb3cgSC5iKFAuQ2YoYix0aGlzLCJpbmRleCIsbnVsbCxzKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVy
-biBQLkVQKHRoaXMsIigiLCIpIil9fQpQLkFuLnByb3RvdHlwZT17fQpQLnpNLnByb3RvdHlwZT17JGlj
-WDoxfQpQLlowLnByb3RvdHlwZT17fQpQLmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1
-cm4gUC5rLnByb3RvdHlwZS5naU8uY2FsbCh0aGlzLHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4i
-bnVsbCJ9fQpQLkZLLnByb3RvdHlwZT17fQpQLmsucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLmssJGlr
-OjEsCkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVy
-biBILmVRKHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTSh0
-aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8uYihiKQp0aHJvdyBILmIoUC5scih0aGlzLGIu
-Z1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLnco
-dGhpcyl9fQpQLk9kLnByb3RvdHlwZT17fQpQLmliLnByb3RvdHlwZT17JGlPZDoxfQpQLnh1LnByb3Rv
-dHlwZT17fQpQLkd6LnByb3RvdHlwZT17fQpQLnFVLnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnByb3Rv
-dHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlvbihhKXt2
-YXIgdD10aGlzLmEKcmV0dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0QucHJv
-dG90eXBlPXt9ClAubjEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmYu
-YihhKQpILnkoYikKdD1KLnJZKGIpLk9ZKGIsIj0iKQppZih0PT09LTEpe2lmKGIhPT0iIilhLlkoMCxQ
-Lmt1KGIsMCxiLmxlbmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmooYiww
-LHQpCnI9Qy54Qi5HKGIsdCsxKQpxPXRoaXMuYQphLlkoMCxQLmt1KHMsMCxzLmxlbmd0aCxxLCEwKSxQ
-Lmt1KHIsMCxyLmxlbmd0aCxxLCEwKSl9cmV0dXJuIGF9LAokUzoyM30KUC5jUy5wcm90b3R5cGU9ewok
-MjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIithLHRo
-aXMuYSxiKSl9LAokUzoyMX0KUC5WQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEgu
-YihQLnJyKCJJbGxlZ2FsIElQdjYgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJFM6MTh9ClAudHAucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
-b24oYSxiKXt2YXIgdAppZihiLWE+NCl0aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBjb250
-YWluIGEgbWF4aW11bSBvZiA0IGhleCBkaWdpdHMiLGEpCnQ9UC5RQShDLnhCLk5qKHRoaXMuYixhLGIp
-LG51bGwsMTYpCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ8MHx8dD42NTUz
-NSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBgMHgwLi4weEZGRkZg
-IixhKQpyZXR1cm4gdH0sCiRTOjE3fQpQLkRuLnByb3RvdHlwZT17CmdrdTpmdW5jdGlvbigpe3JldHVy
-biB0aGlzLmJ9LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJuIiIK
-aWYoQy54Qi5uKHQsIlsiKSlyZXR1cm4gQy54Qi5Oaih0LDEsdC5sZW5ndGgtMSkKcmV0dXJuIHR9LApn
-dHA6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuIFAud0sodGhpcy5hKQpy
-ZXR1cm4gdH0sCmd0UDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwK
-Z0thOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlv
-bihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzCnUuWC5iKG51bGwpCnUuYS5iKGIpCnQ9bC5h
-CnM9dD09PSJmaWxlIgpyPWwuYgpxPWwuZApwPWwuYwppZighKHAhPW51bGwpKXA9ci5sZW5ndGghPT0w
-fHxxIT1udWxsfHxzPyIiOm51bGwKbz1sLmUKaWYoIXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAKZWxz
-ZSBuPSEwCmlmKG4mJiFDLnhCLm4obywiLyIpKW89Ii8iK28KaWYoYiE9bnVsbCltPVAubGUobnVsbCww
-LDAsYikKZWxzZSBtPWwuZgpyZXR1cm4gbmV3IFAuRG4odCxyLHAscSxvLG0sbC5yKX0sCmdGajpmdW5j
-dGlvbigpe3ZhciB0LHM9dGhpcy54CmlmKHMhPW51bGwpcmV0dXJuIHMKdD10aGlzLmUKaWYodC5sZW5n
-dGghPT0wJiZDLnhCLlcodCwwKT09PTQ3KXQ9Qy54Qi5HKHQsMSkKcz10PT09IiI/Qy54RDpQLkFGKG5l
-dyBILkE4KEguVk0odC5zcGxpdCgiLyIpLHUucyksdS5kTy5iKFAuUEgoKSksdS5kbyksdS5OKQp0aGlz
-LnNvNihzKQpyZXR1cm4gc30sCmdoWTpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcwppZihzLlE9PW51bGwp
-e3Q9cy5mCnMuc1JIKG5ldyBQLkdqKFAuV1godD09bnVsbD8iIjp0KSx1LlcpKX1yZXR1cm4gcy5RfSwK
-Smg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8KZm9yKHQ9MCxzPTA7Qy54Qi5RaShiLCIuLi8i
-LHMpOyl7cys9MzsrK3R9cj1DLnhCLmNuKGEsIi8iKQp3aGlsZSghMCl7aWYoIShyPjAmJnQ+MCkpYnJl
-YWsKcT1DLnhCLlBrKGEsIi8iLHItMSkKaWYocTwwKWJyZWFrCnA9ci1xCm89cCE9PTIKaWYoIW98fHA9
-PT0zKWlmKEMueEIubShhLHErMSk9PT00NilvPSFvfHxDLnhCLm0oYSxxKzIpPT09NDYKZWxzZSBvPSEx
-CmVsc2Ugbz0hMQppZihvKWJyZWFrOy0tdApyPXF9cmV0dXJuIEMueEIuaTcoYSxyKzEsbnVsbCxDLnhC
-LkcoYixzLTMqdCkpfSwKWkk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpm
-dW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsaz10aGlzLGo9bnVsbAppZihhLmdGaSgpLmxl
-bmd0aCE9PTApe3Q9YS5nRmkoKQppZihhLmdjaigpKXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPWEuZ3hB
-KCk/YS5ndHAoYSk6an1lbHNle3E9agpyPXEKcz0iIn1wPVAueGUoYS5nSWkoYSkpCm89YS5nUUQoKT9h
-Lmd0UCgpOmp9ZWxzZXt0PWsuYQppZihhLmdjaigpKXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPVAud0Io
-YS5neEEoKT9hLmd0cChhKTpqLHQpCnA9UC54ZShhLmdJaShhKSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1l
-bHNle3M9ay5iCnI9ay5jCnE9ay5kCmlmKGEuZ0lpKGEpPT09IiIpe3A9ay5lCm89YS5nUUQoKT9hLmd0
-UCgpOmsuZn1lbHNle2lmKGEuZ3RUKCkpcD1QLnhlKGEuZ0lpKGEpKQplbHNle249ay5lCmlmKG4ubGVu
-Z3RoPT09MClpZihyPT1udWxsKXA9dC5sZW5ndGg9PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVs
-c2UgcD1QLnhlKCIvIithLmdJaShhKSkKZWxzZXttPWsuSmgobixhLmdJaShhKSkKbD10Lmxlbmd0aD09
-PTAKaWYoIWx8fHIhPW51bGx8fEMueEIubihuLCIvIikpcD1QLnhlKG0pCmVsc2UgcD1QLndGKG0sIWx8
-fHIhPW51bGwpfX1vPWEuZ1FEKCk/YS5ndFAoKTpqfX19cmV0dXJuIG5ldyBQLkRuKHQscyxyLHEscCxv
-LGEuZ1o4KCk/YS5nS2EoKTpqKX0sCmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMhPW51bGx9LApn
-eEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kIT1udWxsfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuZiE9bnVsbH0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnIhPW51bGx9LApndFQ6ZnVuY3Rp
-b24oKXtyZXR1cm4gQy54Qi5uKHRoaXMuZSwiLyIpfSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhp
-cyxxPXIuYQppZihxIT09IiImJnEhPT0iZmlsZSIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0
-IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChxKSsiIFVSSSIpKQpxPXIuZgppZigocT09bnVsbD8iIjpx
-KSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJ
-IHdpdGggYSBxdWVyeSBjb21wb25lbnQiKSkKcT1yLnIKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0aHJv
-dyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJh
-Z21lbnQgY29tcG9uZW50IikpCnQ9JC53USgpCmlmKEgub1QodCkpcT1QLm1uKHIpCmVsc2V7aWYoci5j
-IT1udWxsJiZyLmdKZihyKSE9PSIiKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93
-cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnM9ci5nRmooKQpQ
-LmtFKHMsITEpCnE9UC52ZyhDLnhCLm4oci5lLCIvIik/Ii8iOiIiLHMsIi8iKQpxPXEuY2hhckNvZGVB
-dCgwKT09MD9xOnF9cmV0dXJuIHF9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD1xLnkK
-aWYocD09bnVsbCl7cD1xLmEKdD1wLmxlbmd0aCE9PTA/cCsiOiI6IiIKcz1xLmMKcj1zPT1udWxsCmlm
-KCFyfHxwPT09ImZpbGUiKXtwPXQrIi8vIgp0PXEuYgppZih0Lmxlbmd0aCE9PTApcD1wK3QrIkAiCmlm
-KCFyKXArPXMKdD1xLmQKaWYodCE9bnVsbClwPXArIjoiK0guZCh0KX1lbHNlIHA9dApwKz1xLmUKdD1x
-LmYKaWYodCE9bnVsbClwPXArIj8iK3QKdD1xLnIKaWYodCE9bnVsbClwPXArIiMiK3QKcD1xLnk9cC5j
-aGFyQ29kZUF0KDApPT0wP3A6cH1yZXR1cm4gcH0sCkROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRo
-aXMKaWYoYj09bnVsbClyZXR1cm4hMQppZihyPT09YilyZXR1cm4hMAppZih1LnYuYyhiKSlpZihyLmE9
-PWIuZ0ZpKCkpaWYoci5jIT1udWxsPT09Yi5nY2ooKSlpZihyLmI9PWIuZ2t1KCkpaWYoci5nSmYocik9
-PWIuZ0pmKGIpKWlmKHIuZ3RwKHIpPT1iLmd0cChiKSlpZihyLmU9PT1iLmdJaShiKSl7dD1yLmYKcz10
-PT1udWxsCmlmKCFzPT09Yi5nUUQoKSl7aWYocyl0PSIiCmlmKHQ9PT1iLmd0UCgpKXt0PXIucgpzPXQ9
-PW51bGwKaWYoIXM9PT1iLmdaOCgpKXtpZihzKXQ9IiIKdD10PT09Yi5nS2EoKX1lbHNlIHQ9ITF9ZWxz
-ZSB0PSExfWVsc2UgdD0hMX1lbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxz
-ZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKcmV0dXJuIHR9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcy56CnJldHVybiB0PT1udWxsP3RoaXMuej1DLnhCLmdpTyh0aGlzLncoMCkpOnR9LApzbzY6ZnVu
-Y3Rpb24oYSl7dGhpcy54PXUuaS5iKGEpfSwKc1JIOmZ1bmN0aW9uKGEpe3RoaXMuUT11LmYuYihhKX0s
-CiRpaUQ6MSwKZ0ZpOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX0sCmdJaTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5lfX0KUC5lMS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5ycigi
-SW52YWxpZCBwb3J0Iix0aGlzLmEsdGhpcy5iKzEpKX0sCiRTOjE2fQpQLk5ZLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3ZhciB0PSJJbGxlZ2FsIHBhdGggY2hhcmFjdGVyICIKSC55KGEpCmlmKEouemwo
-YSwiLyIpKWlmKHRoaXMuYSl0aHJvdyBILmIoUC54WSh0K2EpKQplbHNlIHRocm93IEguYihQLkw0KHQr
-YSkpfSwKJFM6MTZ9ClAuUloucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5a
-SixhLEMueE0sITEpfSwKJFM6OH0KUC5NRS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0
-PXRoaXMuYixzPXRoaXMuYQp0LmErPXMuYQpzLmE9IiYiCnM9dC5hKz1ILmQoUC5lUChDLkYzLGEsQy54
-TSwhMCkpCmlmKGIhPW51bGwmJmIubGVuZ3RoIT09MCl7dC5hPXMrIj0iCnQuYSs9SC5kKFAuZVAoQy5G
-MyxiLEMueE0sITApKX19LAokUzoxOX0KUC55NS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMKSC55KGEpCmlmKGI9PW51bGx8fHR5cGVvZiBiPT0ic3RyaW5nIil0aGlzLmEuJDIoYSxILnko
-YikpCmVsc2UgZm9yKHQ9Si5JVCh1LlIuYihiKSkscz10aGlzLmE7dC5GKCk7KXMuJDIoYSxILnkodC5n
-bCgpKSl9LAokUzoxNX0KUC5QRS5wcm90b3R5cGU9ewpnbFI6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxw
-PXRoaXMsbz1udWxsLG49cC5jCmlmKG4hPW51bGwpcmV0dXJuIG4Kbj1wLmIKaWYoMD49bi5sZW5ndGgp
-cmV0dXJuIEguT0gobiwwKQp0PXAuYQpuPW5bMF0rMQpzPUMueEIuWFUodCwiPyIsbikKcj10Lmxlbmd0
-aAppZihzPj0wKXtxPVAudU8odCxzKzEscixDLlZDLCExKQpyPXN9ZWxzZSBxPW8KcmV0dXJuIHAuYz1u
-ZXcgUC5xZSgiZGF0YSIsbyxvLG8sUC51Tyh0LG4scixDLldkLCExKSxxLG8pfSwKdzpmdW5jdGlvbihh
-KXt2YXIgdCxzPXRoaXMuYgppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLDApCnQ9dGhpcy5hCnJl
-dHVybiBzWzBdPT09LTE/ImRhdGE6Iit0OnR9fQpQLnEzLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3JldHVybiBuZXcgVWludDhBcnJheSg5Nil9LAokUzoyMH0KUC55SS5wcm90b3R5cGU9ewokMjpmdW5j
-dGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZihhPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGEpCnQ9dFth
-XQpKLkNNKHQsMCw5NixiKQpyZXR1cm4gdH0sCiRTOjQyfQpQLmM2LnByb3RvdHlwZT17CiQzOmZ1bmN0
-aW9uKGEsYixjKXt2YXIgdCxzLHIscQpmb3IodD1iLmxlbmd0aCxzPWEubGVuZ3RoLHI9MDtyPHQ7Kyty
-KXtxPUMueEIuVyhiLHIpXjk2CmlmKHE+PXMpcmV0dXJuIEguT0goYSxxKQphW3FdPWN9fX0KUC5xZC5w
-cm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKZm9yKHQ9Qy54Qi5XKGIsMCks
-cz1DLnhCLlcoYiwxKSxyPWEubGVuZ3RoO3Q8PXM7Kyt0KXtxPSh0Xjk2KT4+PjAKaWYocT49cilyZXR1
-cm4gSC5PSChhLHEpCmFbcV09Y319fQpQLlVmLnByb3RvdHlwZT17CmdjajpmdW5jdGlvbigpe3JldHVy
-biB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3ZhciB0LHMKaWYodGhpcy5jPjApe3Q9dGhpcy5kCmlm
-KHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCnM9dGhpcy5lCmlmKHR5cGVvZiBzIT09Im51
-bWJlciIpcmV0dXJuIEgucFkocykKcz10KzE8cwp0PXN9ZWxzZSB0PSExCnJldHVybiB0fSwKZ1FEOmZ1
-bmN0aW9uKCl7dmFyIHQ9dGhpcy5mCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCnJl
-dHVybiB0PHRoaXMucn0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0s
-CmdOdzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT00JiZDLnhCLm4odGhpcy5hLCJmaWxlIil9LApn
-dmg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiaHR0cCIpfSwKZ3FC
-OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTUmJkMueEIubih0aGlzLmEsImh0dHBzIil9LApndFQ6
-ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24o
-KXt2YXIgdCxzPXRoaXMscj0icGFja2FnZSIscT1zLmIKaWYocTw9MClyZXR1cm4iIgp0PXMueAppZih0
-IT1udWxsKXJldHVybiB0CmlmKHMuZ3ZoKCkpcT1zLng9Imh0dHAiCmVsc2UgaWYocy5ncUIoKSl7cy54
-PSJodHRwcyIKcT0iaHR0cHMifWVsc2UgaWYocy5nTncoKSl7cy54PSJmaWxlIgpxPSJmaWxlIn1lbHNl
-IGlmKHE9PT03JiZDLnhCLm4ocy5hLHIpKXtzLng9cgpxPXJ9ZWxzZXtxPUMueEIuTmoocy5hLDAscSkK
-cy54PXF9cmV0dXJuIHF9LApna3U6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmMscz10aGlzLmIrMwpyZXR1
-cm4gdD5zP0MueEIuTmoodGhpcy5hLHMsdC0xKToiIn0sCmdKZjpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-LmMKcmV0dXJuIHQ+MD9DLnhCLk5qKHRoaXMuYSx0LHRoaXMuZCk6IiJ9LApndHA6ZnVuY3Rpb24oYSl7
-dmFyIHQscz10aGlzCmlmKHMuZ3hBKCkpe3Q9cy5kCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJu
-IHQuaCgpCnJldHVybiBQLlFBKEMueEIuTmoocy5hLHQrMSxzLmUpLG51bGwsbnVsbCl9aWYocy5ndmgo
-KSlyZXR1cm4gODAKaWYocy5ncUIoKSlyZXR1cm4gNDQzCnJldHVybiAwfSwKZ0lpOmZ1bmN0aW9uKGEp
-e3JldHVybiBDLnhCLk5qKHRoaXMuYSx0aGlzLmUsdGhpcy5mKX0sCmd0UDpmdW5jdGlvbigpe3ZhciB0
-PXRoaXMuZixzPXRoaXMucgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4g
-dDxzP0MueEIuTmoodGhpcy5hLHQrMSxzKToiIn0sCmdLYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMucixz
-PXRoaXMuYQpyZXR1cm4gdDxzLmxlbmd0aD9DLnhCLkcocyx0KzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7
-dmFyIHQscyxyPXRoaXMuZSxxPXRoaXMuZixwPXRoaXMuYQppZihDLnhCLlFpKHAsIi8iLHIpKXtpZih0
-eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLmgoKTsrK3J9aWYocj09cSlyZXR1cm4gQy54RAp0PUgu
-Vk0oW10sdS5zKQpzPXIKd2hpbGUoITApe2lmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSigp
-CmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIEgucFkocSkKaWYoIShzPHEpKWJyZWFrCmlmKEMu
-eEIubShwLHMpPT09NDcpe0MuTm0uaSh0LEMueEIuTmoocCxyLHMpKQpyPXMrMX0rK3N9Qy5ObS5pKHQs
-Qy54Qi5OaihwLHIscSkpCnJldHVybiBQLkFGKHQsdS5OKX0sCmdoWTpmdW5jdGlvbigpe3ZhciB0PXRo
-aXMuZgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0Pj10aGlzLnIpcmV0dXJu
-IEMuV08KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhpcy5ndFAoKSksdS5XKX0sCmtYOmZ1bmN0aW9uKGEp
-e3ZhciB0LHM9dGhpcy5kCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuaCgpCnQ9cysxCnJl
-dHVybiB0K2EubGVuZ3RoPT09dGhpcy5lJiZDLnhCLlFpKHRoaXMuYSxhLHQpfSwKTjk6ZnVuY3Rpb24o
-KXt2YXIgdD10aGlzLHM9dC5yLHI9dC5hCmlmKHM+PXIubGVuZ3RoKXJldHVybiB0CnJldHVybiBuZXcg
-UC5VZihDLnhCLk5qKHIsMCxzKSx0LmIsdC5jLHQuZCx0LmUsdC5mLHMsdC54KX0sCm5tOmZ1bmN0aW9u
-KGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPXRoaXMsaD1udWxsCnUuWC5iKG51bGwpCnUu
-YS5iKGIpCnQ9aS5nRmkoKQpzPXQ9PT0iZmlsZSIKcj1pLmMKcT1yPjA/Qy54Qi5OaihpLmEsaS5iKzMs
-cik6IiIKcD1pLmd4QSgpP2kuZ3RwKGkpOmgKcj1pLmMKaWYocj4wKW89Qy54Qi5OaihpLmEscixpLmQp
-CmVsc2Ugbz1xLmxlbmd0aCE9PTB8fHAhPW51bGx8fHM/IiI6aApyPWkuYQpuPWkuZgptPUMueEIuTmoo
-cixpLmUsbikKaWYoIXMpbD1vIT1udWxsJiZtLmxlbmd0aCE9PTAKZWxzZSBsPSEwCmlmKGwmJiFDLnhC
-Lm4obSwiLyIpKW09Ii8iK20KaWYoYiE9bnVsbClrPVAubGUoaCwwLDAsYikKZWxzZXtsPWkucgppZih0
-eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQprPW48bD9DLnhCLk5qKHIsbisxLGwpOmh9bj1p
-LnIKaj1uPHIubGVuZ3RoP0MueEIuRyhyLG4rMSk6aApyZXR1cm4gbmV3IFAuRG4odCxxLG8scCxtLGss
-ail9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEp
-e2lmKGEgaW5zdGFuY2VvZiBQLlVmKXJldHVybiB0aGlzLnUxKHRoaXMsYSkKcmV0dXJuIHRoaXMuUmUo
-KS5tUyhhKX0sCnUxOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
-LGU9Yi5iCmlmKGU+MClyZXR1cm4gYgp0PWIuYwppZih0PjApe3M9YS5iCmlmKHM8PTApcmV0dXJuIGIK
-aWYoYS5nTncoKSlyPWIuZSE9Yi5mCmVsc2UgaWYoYS5ndmgoKSlyPSFiLmtYKCI4MCIpCmVsc2Ugcj0h
-YS5ncUIoKXx8IWIua1goIjQ0MyIpCmlmKHIpe3E9cysxCnA9Qy54Qi5OaihhLmEsMCxxKStDLnhCLkco
-Yi5hLGUrMSkKZT1iLmQKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5oKCkKbz1iLmUKaWYo
-dHlwZW9mIG8hPT0ibnVtYmVyIilyZXR1cm4gby5oKCkKbj1iLmYKaWYodHlwZW9mIG4hPT0ibnVtYmVy
-IilyZXR1cm4gbi5oKCkKcmV0dXJuIG5ldyBQLlVmKHAscyx0K3EsZStxLG8rcSxuK3EsYi5yK3EsYS54
-KX1lbHNlIHJldHVybiB0aGlzLlJlKCkubVMoYil9bT1iLmUKZT1iLmYKaWYobT09ZSl7dD1iLnIKaWYo
-dHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5KKCkKaWYoZTx0KXtzPWEuZgppZih0eXBlb2YgcyE9
-PSJudW1iZXIiKXJldHVybiBzLkhOKCkKcT1zLWUKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAs
-cykrQy54Qi5HKGIuYSxlKSxhLmIsYS5jLGEuZCxhLmUsZStxLHQrcSxhLngpfWU9Yi5hCmlmKHQ8ZS5s
-ZW5ndGgpe3M9YS5yCnJldHVybiBuZXcgUC5VZihDLnhCLk5qKGEuYSwwLHMpK0MueEIuRyhlLHQpLGEu
-YixhLmMsYS5kLGEuZSxhLmYsdCsocy10KSxhLngpfXJldHVybiBhLk45KCl9dD1iLmEKaWYoQy54Qi5R
-aSh0LCIvIixtKSl7cz1hLmUKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5ITigpCmlmKHR5
-cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIEgucFkobSkKcT1zLW0KcD1DLnhCLk5qKGEuYSwwLHMpK0Mu
-eEIuRyh0LG0pCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCnJldHVybiBuZXcgUC5V
-ZihwLGEuYixhLmMsYS5kLHMsZStxLGIucitxLGEueCl9bD1hLmUKaz1hLmYKaWYobD09ayYmYS5jPjAp
-e2Zvcig7Qy54Qi5RaSh0LCIuLi8iLG0pOyl7aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5o
-KCkKbSs9M31pZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkhOKCkKaWYodHlwZW9mIG0hPT0i
-bnVtYmVyIilyZXR1cm4gSC5wWShtKQpxPWwtbSsxCnA9Qy54Qi5OaihhLmEsMCxsKSsiLyIrQy54Qi5H
-KHQsbSkKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5oKCkKcmV0dXJuIG5ldyBQLlVmKHAs
-YS5iLGEuYyxhLmQsbCxlK3EsYi5yK3EsYS54KX1qPWEuYQpmb3IoaT1sO0MueEIuUWkoaiwiLi4vIixp
-KTspe2lmKHR5cGVvZiBpIT09Im51bWJlciIpcmV0dXJuIGkuaCgpCmkrPTN9aD0wCndoaWxlKCEwKXtp
-Zih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLmgoKQpnPW0rMwppZih0eXBlb2YgZSE9PSJudW1i
-ZXIiKXJldHVybiBILnBZKGUpCmlmKCEoZzw9ZSYmQy54Qi5RaSh0LCIuLi8iLG0pKSlicmVhazsrK2gK
-bT1nfWY9IiIKd2hpbGUoITApe2lmKHR5cGVvZiBrIT09Im51bWJlciIpcmV0dXJuIGsub3MoKQppZih0
-eXBlb2YgaSE9PSJudW1iZXIiKXJldHVybiBILnBZKGkpCmlmKCEoaz5pKSlicmVhazstLWsKaWYoQy54
-Qi5tKGosayk9PT00Nyl7aWYoaD09PTApe2Y9Ii8iCmJyZWFrfS0taApmPSIvIn19aWYoaz09PWkmJmEu
-Yjw9MCYmIUMueEIuUWkoaiwiLyIsbCkpe20tPWgqMwpmPSIifXE9ay1tK2YubGVuZ3RoCnJldHVybiBu
-ZXcgUC5VZihDLnhCLk5qKGosMCxrKStmK0MueEIuRyh0LG0pLGEuYixhLmMsYS5kLGwsZStxLGIucitx
-LGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwppZihwLmI+PTAmJiFwLmdOdygp
-KXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIitILmQocC5n
-RmkoKSkrIiBVUkkiKSkKdD1wLmYKcz1wLmEKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5K
-KCkKaWYodDxzLmxlbmd0aCl7aWYodDxwLnIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEg
-ZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIHF1ZXJ5IGNvbXBvbmVudCIpKQp0aHJvdyBILmIoUC5M
-NCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29t
-cG9uZW50IikpfXI9JC53USgpCmlmKEgub1QocikpdD1QLm1uKHApCmVsc2V7cT1wLmQKaWYodHlwZW9m
-IHEhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShxKQppZihwLmM8cSlILnZoKFAuTDQoIkNhbm5vdCBleHRy
-YWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0
-eSIpKQp0PUMueEIuTmoocyxwLmUsdCl9cmV0dXJuIHR9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
-cy55CnJldHVybiB0PT1udWxsP3RoaXMueT1DLnhCLmdpTyh0aGlzLmEpOnR9LApETjpmdW5jdGlvbihh
-LGIpe2lmKGI9PW51bGwpcmV0dXJuITEKaWYodGhpcz09PWIpcmV0dXJuITAKcmV0dXJuIHUudi5jKGIp
-JiZ0aGlzLmE9PT1iLncoMCl9LApSZTpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz1udWxsLHI9dC5nRmko
-KSxxPXQuZ2t1KCkscD10LmM+MD90LmdKZih0KTpzLG89dC5neEEoKT90Lmd0cCh0KTpzLG49dC5hLG09
-dC5mLGw9Qy54Qi5OaihuLHQuZSxtKSxrPXQucgppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBt
-LkooKQptPW08az90Lmd0UCgpOnMKcmV0dXJuIG5ldyBQLkRuKHIscSxwLG8sbCxtLGs8bi5sZW5ndGg/
-dC5nS2EoKTpzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRpaUQ6MX0KUC5xZS5wcm90
-b3R5cGU9e30KVy5xRS5wcm90b3R5cGU9e30KVy5HaC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiBTdHJpbmcoYSl9LAokaUdoOjF9ClcuZlkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
-cm4gU3RyaW5nKGEpfX0KVy5uQi5wcm90b3R5cGU9eyRpbkI6MX0KVy5Bei5wcm90b3R5cGU9eyRpQXo6
-MX0KVy5RUC5wcm90b3R5cGU9eyRpUVA6MX0KVy5ueC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXty
-ZXR1cm4gYS5sZW5ndGh9fQpXLm9KLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxl
-bmd0aH19ClcuaWQucHJvdG90eXBlPXt9ClcuUUYucHJvdG90eXBlPXt9ClcuTmgucHJvdG90eXBlPXsK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5JQi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
-KGEpe3JldHVybiJSZWN0YW5nbGUgKCIrSC5kKGEubGVmdCkrIiwgIitILmQoYS50b3ApKyIpICIrSC5k
-KGEud2lkdGgpKyIgeCAiK0guZChhLmhlaWdodCl9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwp
-cmV0dXJuITEKcmV0dXJuIHUucS5jKGIpJiZhLmxlZnQ9PT1iLmxlZnQmJmEudG9wPT09Yi50b3AmJmEu
-d2lkdGg9PT1iLndpZHRoJiZhLmhlaWdodD09PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVy
-biBXLnJFKEMuQ0QuZ2lPKGEubGVmdCksQy5DRC5naU8oYS50b3ApLEMuQ0QuZ2lPKGEud2lkdGgpLEMu
-Q0QuZ2lPKGEuaGVpZ2h0KSl9LAokaXRuOjF9ClcubjcucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RofX0KVy53ei5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILlNjKGIpCnQ9dGhpcy5hCmlmKGI8MHx8
-Yj49dC5sZW5ndGgpcmV0dXJuIEguT0godCxiKQpyZXR1cm4gdGhpcy4kdGkuZC5iKHRbYl0pfSwKWTpm
-dW5jdGlvbihhLGIsYyl7dGhpcy4kdGkuZC5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5
-IGxpc3QiKSl9fQpXLmN2LnByb3RvdHlwZT17CmdRZzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuaTco
-YSl9LApnRDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuSTQoYSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVy
-biBhLmxvY2FsTmFtZX0sCnRuOmZ1bmN0aW9uKGEpe3ZhciB0PSEhYS5zY3JvbGxJbnRvVmlld0lmTmVl
-ZGVkCmlmKHQpYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkKCkKZWxzZSBhLnNjcm9sbEludG9WaWV3KCl9
-LApyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscQppZihjPT1udWxsKXtpZihkPT1udWxsKXt0
-PSQubHQKaWYodD09bnVsbCl7dD1ILlZNKFtdLHUuUSkKcz1uZXcgVy52RCh0KQpDLk5tLmkodCxXLlR3
-KG51bGwpKQpDLk5tLmkodCxXLkJsKCkpCiQubHQ9cwpkPXN9ZWxzZSBkPXR9dD0kLkVVCmlmKHQ9PW51
-bGwpe3Q9bmV3IFcuS28oZCkKJC5FVT10CmM9dH1lbHNle3QuYT1kCmM9dH19ZWxzZSBpZihkIT1udWxs
-KXRocm93IEguYihQLnhZKCJ2YWxpZGF0b3IgY2FuIG9ubHkgYmUgcGFzc2VkIGlmIHRyZWVTYW5pdGl6
-ZXIgaXMgbnVsbCIpKQppZigkLnhvPT1udWxsKXt0PWRvY3VtZW50CnM9dC5pbXBsZW1lbnRhdGlvbi5j
-cmVhdGVIVE1MRG9jdW1lbnQoIiIpCiQueG89cwokLkJPPXMuY3JlYXRlUmFuZ2UoKQpzPSQueG8uY3Jl
-YXRlRWxlbWVudCgiYmFzZSIpCnUuRi5iKHMpCnMuaHJlZj10LmJhc2VVUkkKJC54by5oZWFkLmFwcGVu
-ZENoaWxkKHMpfXQ9JC54bwppZih0LmJvZHk9PW51bGwpe3M9dC5jcmVhdGVFbGVtZW50KCJib2R5IikK
-dC5ib2R5PXUuWS5iKHMpfXQ9JC54bwppZih1LlkuYyhhKSlyPXQuYm9keQplbHNle3I9dC5jcmVhdGVF
-bGVtZW50KGEudGFnTmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0
-dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdO
-YW1lKSl7JC5CTy5zZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFn
-bWVudChiKX1lbHNle3IuaW5uZXJIVE1MPWIKcT0kLnhvLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpm
-b3IoO3Q9ci5maXJzdENoaWxkLHQhPW51bGw7KXEuYXBwZW5kQ2hpbGQodCl9dD0kLnhvLmJvZHkKaWYo
-cj09bnVsbD90IT1udWxsOnIhPT10KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkK
-cmV0dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApz
-aGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29u
-dGVudD1udWxsCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihh
-LGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcu
-Q3EoYSwiY2xpY2siLCExLHUuQyl9LAokaWN2OjEsCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdO
-YW1lfX0KVy5Ddi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmModS5BLmIoYSkp
-fSwKJFM6MjJ9ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rp
-b24oYSxiLGMsZCl7dS5VLmIoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9u
-KGEsYixjKXtyZXR1cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0
-dXJuIGEuYWRkRXZlbnRMaXN0ZW5lcihiLEgudFIodS5VLmIoYyksMSksZCl9LAokaUQwOjF9ClcuVDUu
-cHJvdG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-bGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
-LlZiLnByb3RvdHlwZT17fQpXLk83LnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVy
-biBhLm9wZW4oYixjLCEwKX0sCiRpTzc6MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
-e3RoaXMuYS5zZXRSZXF1ZXN0SGVhZGVyKEgueShhKSxILnkoYikpfSwKJFM6MTB9ClcuaEgucHJvdG90
-eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscAp1LnAuYihhKQp0PXRoaXMuYQpzPXQuc3Rh
-dHVzCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMudEIoKQpyPXM+PTIwMCYmczwzMDAKcT1z
-PjMwNyYmczw0MDAKcz1yfHxzPT09MHx8cz09PTMwNHx8cQpwPXRoaXMuYgppZihzKXtwLiR0aS5DKCIx
-LyIpLmIodCkKcz1wLmEKaWYocy5hIT09MClILnZoKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRl
-ZCIpKQpzLlhmKHQpfWVsc2UgcC5wbShhKX0sCiRTOjI0fQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnBy
-b3RvdHlwZT17JGlTZzoxfQpXLnU4LnByb3RvdHlwZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2lu
-IiBpbiBhKXJldHVybiBhLm9yaWdpbgpyZXR1cm4gSC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9z
-dCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaXU4OjF9ClcuQWoucHJvdG90eXBl
-PXskaUFqOjF9ClcuZTcucHJvdG90eXBlPXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQu
-Y2hpbGROb2Rlcy5sZW5ndGgKaWYocz09PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlm
-KHM+MSl0aHJvdyBILmIoUC5QVigiTW9yZSB0aGFuIG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0
-Q2hpbGR9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxCnUuZWguYihiKQp0PWIuYQpzPXRoaXMu
-YQppZih0IT09cylmb3Iocj10LmNoaWxkTm9kZXMubGVuZ3RoLHE9MDtxPHI7KytxKXMuYXBwZW5kQ2hp
-bGQodC5maXJzdENoaWxkKQpyZXR1cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5iKGMp
-CnQ9dGhpcy5hCnM9dC5jaGlsZE5vZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxi
-KQp0LnJlcGxhY2VDaGlsZChjLHNbYl0pfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5jaGls
-ZE5vZGVzCnJldHVybiBuZXcgVy5XOSh0LHQubGVuZ3RoLEgueksodCkuQygiVzk8R20uRT4iKSl9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNoaWxkTm9kZXMubGVuZ3RofSwKcTpmdW5jdGlvbihh
-LGIpe3ZhciB0CkguU2MoYikKdD10aGlzLmEuY2hpbGROb2RlcwppZihiPDB8fGI+PXQubGVuZ3RoKXJl
-dHVybiBILk9IKHQsYikKcmV0dXJuIHRbYl19fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEp
-e3ZhciB0PWEucGFyZW50Tm9kZQppZih0IT1udWxsKXQucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlv
-bihhKXt2YXIgdApmb3IoO3Q9YS5maXJzdENoaWxkLHQhPW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LAp3
-OmZ1bmN0aW9uKGEpe3ZhciB0PWEubm9kZVZhbHVlCnJldHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwK
-JGl1SDoxfQpXLkJILnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6
-ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAu
-Q2YoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEu
-YihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0
-LiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikK
-cmV0dXJuIGFbYl19LAokaVhqOjEsCiRpY1g6MSwKJGl6TToxfQpXLlNOLnByb3RvdHlwZT17fQpXLmV3
-LnByb3RvdHlwZT17JGlldzoxfQpXLmxwLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBh
-Lmxlbmd0aH19ClcuVGIucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZigi
-Y3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0
-aGlzLkRXKGEsYixjLGQpCnQ9Vy5VOSgiPHRhYmxlPiIrSC5kKGIpKyI8L3RhYmxlPiIsYyxkKQpzPWRv
-Y3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpzLnRvU3RyaW5nCnQudG9TdHJpbmcKbmV3IFcu
-ZTcocykuRlYoMCxuZXcgVy5lNyh0KSkKcmV0dXJuIHN9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdp
-bmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQu
-Y3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiks
-YixjLGQpCnQudG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnIudG9TdHJpbmcKdD1uZXcg
-Vy5lNyhyKQpxPXQuZ3I4KHQpCnMudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5l
-dyBXLmU3KHEpKQpyZXR1cm4gc319ClcuQlQucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7
-dmFyIHQscyxyCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90
-b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRG
-cmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9TdHJp
-bmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnMudG9TdHJpbmcKci50b1N0cmluZwpuZXcgVy5lNyhz
-KS5GVigwLG5ldyBXLmU3KHIpKQpyZXR1cm4gc319ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciB0LHMKYS50ZXh0Q29udGVudD1udWxsCnQ9YS5jb250ZW50CnQudG9TdHJpbmcKSi5i
-VCh0KQpzPXRoaXMucjYoYSxiLG51bGwsYykKYS5jb250ZW50LmFwcGVuZENoaWxkKHMpfSwKWUM6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5wayhhLGIsbnVsbCl9LAokaXlZOjF9ClcudzYucHJvdG90eXBl
-PXt9ClcuSzUucHJvdG90eXBlPXskaUs1OjEsJGl2NjoxfQpXLkNtLnByb3RvdHlwZT17JGlDbToxfQpX
-LkNRLnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IlJlY3RhbmdsZSAoIitILmQoYS5sZWZ0KSsiLCAiK0guZChhLnRvcCkrIikgIitILmQoYS53aWR0aCkr
-IiB4ICIrSC5kKGEuaGVpZ2h0KX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpy
-ZXR1cm4gdS5xLmMoYikmJmEubGVmdD09PWIubGVmdCYmYS50b3A9PT1iLnRvcCYmYS53aWR0aD09PWIu
-d2lkdGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFcuckUoQy5D
-RC5naU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRvcCksQy5DRC5naU8oYS53aWR0aCksQy5DRC5naU8oYS5o
-ZWlnaHQpKX19ClcucmgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwK
-cTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIo
-UC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3Uu
-QS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExp
-c3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxi
-KQpyZXR1cm4gYVtiXX0sCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuRDkucHJvdG90eXBlPXsKSzpm
-dW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5ELmIoYikKZm9yKHQ9dGhpcy5nVigpLHM9dC5sZW5n
-dGgscj10aGlzLmEscT0wO3E8dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK3Epe3A9
-dFtxXQpiLiQyKHAsci5nZXRBdHRyaWJ1dGUocCkpfX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEs
-cD10aGlzLmEuYXR0cmlidXRlcyxvPUguVk0oW10sdS5zKQpmb3IodD1wLmxlbmd0aCxzPXUuaDkscj0w
-O3I8dDsrK3Ipe2lmKHI+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscikKcT1zLmIocFtyXSkKaWYocS5u
-YW1lc3BhY2VVUkk9PW51bGwpQy5ObS5pKG8scS5uYW1lKX1yZXR1cm4gb319ClcuaTcucHJvdG90eXBl
-PXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuZ2V0QXR0cmlidXRlKEgueShiKSl9LApZOmZ1
-bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0cmlidXRlKGIsYyl9LApnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3kucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVy
-biB0aGlzLmEuYS5nZXRBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oSC55KGIpKSl9LApZOmZ1bmN0aW9u
-KGEsYixjKXt0aGlzLmEuYS5zZXRBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oYiksYyl9LApLOmZ1bmN0
-aW9uKGEsYil7dGhpcy5hLksoMCxuZXcgVy5LUyh0aGlzLHUuRC5iKGIpKSl9LApnVjpmdW5jdGlvbigp
-e3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEuSygwLG5ldyBXLkEzKHRoaXMsdCkpCnJldHVybiB0fSwK
-Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGh9LAprOmZ1bmN0aW9uKGEpe3ZhciB0
-LHMscj1ILlZNKGEuc3BsaXQoIi0iKSx1LnMpCmZvcih0PTE7dDxyLmxlbmd0aDsrK3Qpe3M9clt0XQpp
-ZihzLmxlbmd0aD4wKUMuTm0uWShyLHQsc1swXS50b1VwcGVyQ2FzZSgpK0ouS1YocywxKSl9cmV0dXJu
-IEMuTm0uSChyLCIiKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscApmb3IodD1hLmxlbmd0aCxz
-PTAscj0iIjtzPHQ7KytzKXtxPWFbc10KcD1xLnRvTG93ZXJDYXNlKCkKcj0ocSE9PXAmJnM+MD9yKyIt
-IjpyKStwfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfX0KVy5LUy5wcm90b3R5cGU9ewokMjpm
-dW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKXRoaXMuYi4kMih0aGlzLmEuayhDLnhC
-LkcoYSw1KSksYil9LAokUzoxMH0KVy5BMy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEou
-clkoYSkubihhLCJkYXRhLSIpKUMuTm0uaSh0aGlzLmIsdGhpcy5hLmsoQy54Qi5HKGEsNSkpKX0sCiRT
-OjEwfQpXLkk0LnByb3RvdHlwZT17ClA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPVAuTHModS5OKQpm
-b3IodD10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1K
-LlQwKHRbcl0pCmlmKHEubGVuZ3RoIT09MClwLmkoMCxxKX1yZXR1cm4gcH0sClg6ZnVuY3Rpb24oYSl7
-dGhpcy5hLmNsYXNzTmFtZT11LlQuYihhKS5IKDAsIiAiKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0
-aGlzLmEuY2xhc3NMaXN0Lmxlbmd0aH0sClYxOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9IiJ9
-LAp0ZzpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5jbGFzc0xpc3QuY29udGFpbnMoYikKcmV0dXJu
-IHR9LAppOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdCxzPXQuY29udGFpbnMoYikK
-dC5hZGQoYikKcmV0dXJuIXN9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdCxz
-PXQuY29udGFpbnMoYikKdC5yZW1vdmUoYikKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe1cuVE4o
-dGhpcy5hLHUuWC5iKGIpKX19ClcuRmsucHJvdG90eXBlPXt9ClcuUk8ucHJvdG90eXBlPXt9ClcuQ3Eu
-cHJvdG90eXBlPXt9ClcueEMucHJvdG90eXBlPXt9Clcudk4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuYS4kMSh1LkIuYihhKSl9LAokUzoyNX0KVy5KUS5wcm90b3R5cGU9ewpDWTpm
-dW5jdGlvbihhKXt2YXIgdAppZigkLm9yLmE9PT0wKXtmb3IodD0wO3Q8MjYyOysrdCkkLm9yLlkoMCxD
-LmNtW3RdLFcucFMoKSkKZm9yKHQ9MDt0PDEyOysrdCkkLm9yLlkoMCxDLkJJW3RdLFcuVjQoKSl9fSwK
-aTA6ZnVuY3Rpb24oYSl7cmV0dXJuICQuQU4oKS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciB0PSQub3IucSgwLEguZChXLnJTKGEpKSsiOjoiK2IpCmlmKHQ9PW51bGwpdD0kLm9yLnEo
-MCwiKjo6IitiKQppZih0PT1udWxsKXJldHVybiExCnJldHVybiBILnhkKHQuJDQoYSxiLGMsdGhpcykp
-fSwKJGlrRjoxfQpXLkdtLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzko
-YSx0aGlzLmdBKGEpLEgueksoYSkuQygiVzk8R20uRT4iKSl9fQpXLnZELnByb3RvdHlwZT17CmkwOmZ1
-bmN0aW9uKGEpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5VdihhKSl9LApFYjpmdW5jdGlvbihh
-LGIsYyl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLkVnKGEsYixjKSl9LAokaWtGOjF9ClcuVXYu
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuZS5iKGEpLmkwKHRoaXMuYSl9LAokUzox
-NH0KVy5FZy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5lLmIoYSkuRWIodGhpcy5h
-LHRoaXMuYix0aGlzLmMpfSwKJFM6MTR9ClcubTYucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiLGMs
-ZCl7dmFyIHQscyxyCnRoaXMuYS5GVigwLGMpCnQ9Yi5ldigwLG5ldyBXLkVvKCkpCnM9Yi5ldigwLG5l
-dyBXLldrKCkpCnRoaXMuYi5GVigwLHQpCnI9dGhpcy5jCnIuRlYoMCxDLnhEKQpyLkZWKDAscyl9LApp
-MDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIs
-Yyl7dmFyIHQ9dGhpcyxzPVcuclMoYSkscj10LmMKaWYoci50ZygwLEguZChzKSsiOjoiK2IpKXJldHVy
-biB0LmQuRHQoYykKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuIHQuZC5EdChjKQplbHNle3I9
-dC5iCmlmKHIudGcoMCxILmQocykrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCwiKjo6Iiti
-KSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCxILmQocykrIjo6KiIpKXJldHVybiEwCmVsc2UgaWYoci50
-ZygwLCIqOjoqIikpcmV0dXJuITB9cmV0dXJuITF9LAokaWtGOjF9ClcuRW8ucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7cmV0dXJuIUMuTm0udGcoQy5CSSxILnkoYSkpfSwKJFM6N30KVy5Xay5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJLEgueShhKSl9LAokUzo3fQpXLmN0
-LnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtpZih0aGlzLmpGKGEsYixjKSlyZXR1cm4hMApp
-ZihiPT09InRlbXBsYXRlIiYmYz09PSIiKXJldHVybiEwCmlmKGEuZ2V0QXR0cmlidXRlKCJ0ZW1wbGF0
-ZSIpPT09IiIpcmV0dXJuIHRoaXMuZS50ZygwLGIpCnJldHVybiExfX0KVy5JQS5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXtyZXR1cm4iVEVNUExBVEU6OiIrSC5kKEgueShhKSl9LAokUzo4fQpXLk93LnBy
-b3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuZXcuYyhhKSlyZXR1cm4hMQp0PXUuZzcu
-YyhhKQppZih0JiZXLnJTKGEpPT09ImZvcmVpZ25PYmplY3QiKXJldHVybiExCmlmKHQpcmV0dXJuITAK
-cmV0dXJuITF9LApFYjpmdW5jdGlvbihhLGIsYyl7aWYoYj09PSJpcyJ8fEMueEIubihiLCJvbiIpKXJl
-dHVybiExCnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVuY3Rp
-b24oKXt2YXIgdD10aGlzLHM9dC5jKzEscj10LmIKaWYoczxyKXt0LnNwKEoudzIodC5hLHMpKQp0LmM9
-cwpyZXR1cm4hMH10LnNwKG51bGwpCnQuYz1yCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4g
-dGhpcy5kfSwKc3A6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KVy5k
-Vy5wcm90b3R5cGU9eyRpRDA6MSwkaXY2OjF9Clcua0YucHJvdG90eXBlPXt9ClcubWsucHJvdG90eXBl
-PXskaXkwOjF9ClcuS28ucHJvdG90eXBlPXsKUG46ZnVuY3Rpb24oYSl7bmV3IFcuZm0odGhpcykuJDIo
-YSxudWxsKX0sCkVQOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClKLkx0KGEpCmVsc2UgYi5yZW1vdmVD
-aGlsZChhKX0sCkk0OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPSEwLG49bnVsbCxtPW51bGwK
-dHJ5e249Si5pZyhhKQptPW4uYS5nZXRBdHRyaWJ1dGUoImlzIikKdS5oLmIoYSkKdD1mdW5jdGlvbihj
-KXtpZighKGMuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkpcmV0dXJuIHRydWUKdmFy
-IGw9Yy5jaGlsZE5vZGVzCmlmKGMubGFzdENoaWxkJiZjLmxhc3RDaGlsZCE9PWxbbC5sZW5ndGgtMV0p
-cmV0dXJuIHRydWUKaWYoYy5jaGlsZHJlbilpZighKGMuY2hpbGRyZW4gaW5zdGFuY2VvZiBIVE1MQ29s
-bGVjdGlvbnx8Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIE5vZGVMaXN0KSlyZXR1cm4gdHJ1ZQp2YXIgaz0w
-CmlmKGMuY2hpbGRyZW4paz1jLmNoaWxkcmVuLmxlbmd0aApmb3IodmFyIGo9MDtqPGs7aisrKXt2YXIg
-aT1jLmNoaWxkcmVuW2pdCmlmKGkuaWQ9PSdhdHRyaWJ1dGVzJ3x8aS5uYW1lPT0nYXR0cmlidXRlcyd8
-fGkuaWQ9PSdsYXN0Q2hpbGQnfHxpLm5hbWU9PSdsYXN0Q2hpbGQnfHxpLmlkPT0nY2hpbGRyZW4nfHxp
-Lm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZhbHNlfShhKQpvPUgub1QodCk/ITA6
-IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApfWNhdGNoKHEpe0guUnUocSl9cz0i
-ZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3M9Si5qKGEpfWNhdGNoKHEpe0guUnUocSl9dHJ5e3I9Vy5y
-UyhhKQp0aGlzLmtSKHUuaC5iKGEpLGIsbyxzLHIsdS5HLmIobiksSC55KG0pKX1jYXRjaChxKXtpZihI
-LlJ1KHEpIGluc3RhbmNlb2YgUC51KXRocm93IHEKZWxzZXt0aGlzLkVQKGEsYikKd2luZG93CnA9IlJl
-bW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5kKHMpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZp
-bmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApfX19LAprUjpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2
-YXIgdCxzLHIscSxwLG8sbj10aGlzCmlmKGMpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZWxl
-bWVudCBkdWUgdG8gY29ycnVwdGVkIGF0dHJpYnV0ZXMgb24gPCIrZCsiPiIKaWYodHlwZW9mIGNvbnNv
-bGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufWlmKCFuLmEuaTAoYSkp
-e24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBlbGVtZW50IDwiK0guZChlKSsi
-PiBmcm9tICIrSC5kKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29s
-ZS53YXJuKHQpCnJldHVybn1pZihnIT1udWxsKWlmKCFuLmEuRWIoYSwiaXMiLGcpKXtuLkVQKGEsYikK
-d2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24gPCIrSC5kKGUpKycgaXM9
-IicrZysnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJu
-KHQpCnJldHVybn10PWYuZ1YoKQpzPUguVk0odC5zbGljZSgwKSxILnQ2KHQpLkMoImpkPDE+IikpCmZv
-cihyPWYuZ1YoKS5sZW5ndGgtMSx0PWYuYTtyPj0wOy0tcil7aWYocj49cy5sZW5ndGgpcmV0dXJuIEgu
-T0gocyxyKQpxPXNbcl0KcD1uLmEKbz1KLmNIKHEpCkgueShxKQppZighcC5FYihhLG8sdC5nZXRBdHRy
-aWJ1dGUocSkpKXt3aW5kb3cKcD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBhdHRyaWJ1dGUgPCIrSC5kKGUp
-KyIgIitxKyc9IicrSC5kKHQuZ2V0QXR0cmlidXRlKHEpKSsnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0i
-dW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApCnQucmVtb3ZlQXR0cmlidXRlKHEpfX1pZih1
-LmFXLmMoYSkpbi5QbihhLmNvbnRlbnQpfSwKJGlvbjoxfQpXLmZtLnByb3RvdHlwZT17CiQyOmZ1bmN0
-aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzLmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTpwLkk0
-KGEsYikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZhdWx0OnAuRVAo
-YSxiKX10PWEubGFzdENoaWxkCmZvcihwPXUuQTtudWxsIT10Oyl7cz1udWxsCnRyeXtzPXQucHJldmlv
-dXNTaWJsaW5nfWNhdGNoKHIpe0guUnUocikKcT1wLmIodCkKYS5yZW1vdmVDaGlsZChxKQp0PW51bGwK
-cz1hLmxhc3RDaGlsZH1pZih0IT1udWxsKXRoaXMuJDIodCxhKQp0PXAuYihzKX19LAokUzozNX0KVy5M
-ZS5wcm90b3R5cGU9e30KVy5LNy5wcm90b3R5cGU9e30KVy5yQi5wcm90b3R5cGU9e30KVy5YVy5wcm90
-b3R5cGU9e30KVy5vYS5wcm90b3R5cGU9e30KUC5pSi5wcm90b3R5cGU9ewpWSDpmdW5jdGlvbihhKXt2
-YXIgdCxzPXRoaXMuYSxyPXMubGVuZ3RoCmZvcih0PTA7dDxyOysrdClpZihzW3RdPT09YSlyZXR1cm4g
-dApDLk5tLmkocyxhKQpDLk5tLmkodGhpcy5iLG51bGwpCnJldHVybiByfSwKUHY6ZnVuY3Rpb24oYSl7
-dmFyIHQscyxyLHE9dGhpcyxwPXt9CmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoSC5sKGEpKXJldHVybiBh
-CmlmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJu
-IGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIG5ldyBEYXRlKGEuYSkKaWYodS5mdi5jKGEpKXRo
-cm93IEguYihQLlNZKCJzdHJ1Y3R1cmVkIGNsb25lIG9mIFJlZ0V4cCIpKQppZih1LmM4LmMoYSkpcmV0
-dXJuIGEKaWYodS5kLmMoYSkpcmV0dXJuIGEKaWYodS5JLmMoYSkpcmV0dXJuIGEKdD11LmRELmMoYSl8
-fCExCmlmKHQpcmV0dXJuIGEKaWYodS5HLmMoYSkpe3M9cS5WSChhKQp0PXEuYgppZihzPj10Lmxlbmd0
-aClyZXR1cm4gSC5PSCh0LHMpCnI9cC5hPXRbc10KaWYociE9bnVsbClyZXR1cm4gcgpyPXt9CnAuYT1y
-CkMuTm0uWSh0LHMscikKYS5LKDAsbmV3IFAubFIocCxxKSkKcmV0dXJuIHAuYX1pZih1LmouYyhhKSl7
-cz1xLlZIKGEpCnA9cS5iCmlmKHM+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscykKcj1wW3NdCmlmKHIh
-PW51bGwpcmV0dXJuIHIKcmV0dXJuIHEuZWsoYSxzKX1pZih1LmVILmMoYSkpe3M9cS5WSChhKQp0PXEu
-YgppZihzPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LHMpCnI9cC5iPXRbc10KaWYociE9bnVsbClyZXR1
-cm4gcgpyPXt9CnAuYj1yCkMuTm0uWSh0LHMscikKcS5pbShhLG5ldyBQLmpnKHAscSkpCnJldHVybiBw
-LmJ9dGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVrOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscz1KLlU2KGEpLHI9cy5nQShhKSxxPW5ldyBBcnJheShyKQpDLk5tLlko
-dGhpcy5iLGIscSkKZm9yKHQ9MDt0PHI7Kyt0KUMuTm0uWShxLHQsdGhpcy5QdihzLnEoYSx0KSkpCnJl
-dHVybiBxfX0KUC5sUi5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5hW2FdPXRoaXMu
-Yi5QdihiKX0sCiRTOjF9ClAuamcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYlth
-XT10aGlzLmIuUHYoYil9LAokUzoxfQpQLkJmLnByb3RvdHlwZT17CmltOmZ1bmN0aW9uKGEsYil7dmFy
-IHQscyxyLHEKdS5iOC5iKGIpCmZvcih0PU9iamVjdC5rZXlzKGEpLHM9dC5sZW5ndGgscj0wO3I8czsr
-K3Ipe3E9dFtyXQpiLiQyKHEsYVtxXSl9fX0KUC5Bcy5wcm90b3R5cGU9ewpUOmZ1bmN0aW9uKGEpe3Zh
-ciB0CkgueShhKQp0PSQuaEcoKS5iCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILnZoKEgudEwoYSkpCmlm
-KHQudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhhLCJ2YWx1ZSIsIk5vdCBhIHZhbGlkIGNs
-YXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5QKCkuSCgwLCIgIil9LApna3o6
-ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5QKCkKcmV0dXJuIFAucmoodCx0LnIsSC5MaCh0KS5kKX0sCmdB
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlAoKS5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt0aGlzLlQoYikK
-cmV0dXJuIHRoaXMuUCgpLnRnKDAsYil9LAppOmZ1bmN0aW9uKGEsYil7dGhpcy5UKGIpCnJldHVybiBI
-LnhkKHRoaXMuT1MobmV3IFAuR0UoYikpKX0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCnRoaXMuVChi
-KQp0PXRoaXMuUCgpCnM9dC5SKDAsYikKdGhpcy5YKHQpCnJldHVybiBzfSwKT1M6ZnVuY3Rpb24oYSl7
-dmFyIHQscwp1LmNoLmIoYSkKdD10aGlzLlAoKQpzPWEuJDEodCkKdGhpcy5YKHQpCnJldHVybiBzfX0K
-UC5HRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5ULmIoYSkuaSgwLHRoaXMuYSl9
-LAokUzoyOX0KUC5oRi5wcm90b3R5cGU9eyRpaEY6MX0KUC5QQy5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXt2YXIgdAp1LlouYihhKQp0PWZ1bmN0aW9uKGIsYyxkKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1
-cm4gYihjLGQsdGhpcyxBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkoYXJndW1lbnRzKSl9fShQLlI0
-LGEsITEpClAuRG0odCwkLncoKSxhKQpyZXR1cm4gdH0sCiRTOjR9ClAuWW0ucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyB0aGlzLmEoYSl9LAokUzo0fQpQLk56LnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5yNyhhKX0sCiRTOjMwfQpQLlFTLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5UeihhLHUuYW0pfSwKJFM6MzF9ClAubnAucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkU0KGEpfSwKJFM6MzJ9ClAuRTQucHJvdG90eXBl
-PXsKcTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIi
-KXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnJldHVybiBQ
-Lkw3KHRoaXMuYVtiXSl9LApZOmZ1bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5
-cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBILmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9y
-IG51bSIpKQp0aGlzLmFbYl09UC53WShjKX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1
-cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAuRTQmJnRoaXMuYT09PWIuYX0sCnc6ZnVuY3Rpb24oYSl7
-dmFyIHQscwp0cnl7dD1TdHJpbmcodGhpcy5hKQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpCnQ9dGhp
-cy54YigwKQpyZXR1cm4gdH19LApWNzpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5hCmlmKGI9PW51
-bGwpdD1udWxsCmVsc2V7dD1ILnQ2KGIpCnQ9UC5DSChuZXcgSC5BOChiLHQuQygiQCgxKSIpLmIoUC5p
-RygpKSx0LkMoIkE4PDEsQD4iKSksITAsdS56KX1yZXR1cm4gUC5MNyhzW2FdLmFwcGx5KHMsdCkpfSwK
-Z2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfX0KUC5yNy5wcm90b3R5cGU9e30KUC5Uei5wcm90b3R5cGU9
-ewpjUDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9YTwwfHxhPj10LmdBKHQpCmlmKHMpdGhyb3cgSC5i
-KFAuVEUoYSwwLHQuZ0EodCksbnVsbCxudWxsKSl9LApxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9
-PSJudW1iZXIiJiZiPT09Qy5qbi55dShiKSl0aGlzLmNQKEguU2MoYikpCnJldHVybiB0aGlzLiR0aS5k
-LmIodGhpcy5VcigwLGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnRoaXMuJHRpLmQuYihjKQp0
-PUMuam4ueXUoYikKaWYoYj09PXQpdGhpcy5jUChiKQp0aGlzLmU0KDAsYixjKX0sCmdBOmZ1bmN0aW9u
-KGEpe3ZhciB0PXRoaXMuYS5sZW5ndGgKaWYodHlwZW9mIHQ9PT0ibnVtYmVyIiYmdD4+PjA9PT10KXJl
-dHVybiB0CnRocm93IEguYihQLlBWKCJCYWQgSnNBcnJheSBsZW5ndGgiKSl9LAokaWNYOjEsCiRpek06
-MX0KUC5jby5wcm90b3R5cGU9e30KUC5uZC5wcm90b3R5cGU9eyRpbmQ6MX0KUC5LZS5wcm90b3R5cGU9
-ewpQOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpLG89
-UC5Mcyh1Lk4pCmlmKHA9PW51bGwpcmV0dXJuIG8KZm9yKHQ9cC5zcGxpdCgiICIpLHM9dC5sZW5ndGgs
-cj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9PTApby5pKDAscSl9cmV0dXJuIG99
-LApYOmZ1bmN0aW9uKGEpe3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNsYXNzIixhLkgoMCwiICIpKX19ClAu
-ZDUucHJvdG90eXBlPXsKZ0Q6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0
-aW9uKGEsYil7dGhpcy5ZQyhhLGIpfSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxv
-CmlmKGQ9PW51bGwpe3Q9SC5WTShbXSx1LlEpCmQ9bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxs
-KSkKQy5ObS5pKHQsVy5CbCgpKQpDLk5tLmkodCxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnM9Jzxz
-dmcgdmVyc2lvbj0iMS4xIj4nK0guZChiKSsiPC9zdmc+Igp0PWRvY3VtZW50CnI9dC5ib2R5CnE9KHIm
-JkMuUlkpLkFIKHIscyxjKQpwPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnEudG9TdHJpbmcKdD1u
-ZXcgVy5lNyhxKQpvPXQuZ3I4KHQpCmZvcig7dD1vLmZpcnN0Q2hpbGQsdCE9bnVsbDspcC5hcHBlbmRD
-aGlsZCh0KQpyZXR1cm4gcH0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuQ3EoYSwiY2xpY2si
-LCExLHUuQyl9LAokaWQ1OjF9ClAubjYucHJvdG90eXBlPXskaWNYOjEsJGl6TToxLCRpQVM6MX0KVS5k
-Mi5wcm90b3R5cGU9e30KVS5TZS5wcm90b3R5cGU9e30KVS51Ri5wcm90b3R5cGU9e30KVS5NbC5wcm90
-b3R5cGU9e30KVC5HVi5wcm90b3R5cGU9e30KTC5lLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscgp1LkIuYihhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwuRzYod2luZG93Lmxv
-Y2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKTC5HZSgpCmlmKHQhPT0iLyIm
-JnQhPT1KLlQwKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4dENvbnRlbnQpKUwuRzco
-dCxzLHIsbmV3IEwuVlcodCxzLHIpKX0sCiRTOjEzfQpMLlZXLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
-KCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzowfQpMLkwucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyCnUuQi5iKGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5H
-Nih3aW5kb3cubG9jYXRpb24uaHJlZikKcj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZih0Lmxl
-bmd0aD4xKUwuRzcodCxzLHIsbnVsbCkKZWxzZXtMLkJFKHQsUC5FRihbInJlZ2lvbnMiLCIiLCJuYXZp
-Z2F0aW9uQ29udGVudCIsIiIsImVkaXRzIixbXV0sdS5OLHUueikpCkwuQlgoIiZuYnNwOyIsbnVsbCl9
-fSwKJFM6MTN9CkwuV3gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9ImNvbGxh
-cHNlZCIKdS5WLmIoYSkKdD10aGlzLmEKcz1KLlJFKHQpCnI9dGhpcy5iCmlmKCFzLmdEKHQpLnRnKDAs
-cSkpe3MuZ0QodCkuaSgwLHEpCkouZFIocikuaSgwLHEpfWVsc2V7cy5nRCh0KS5SKDAscSkKSi5kUihy
-KS5SKDAscSl9fSwKJFM6Nn0KTC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD1KLnFG
-KHUuaC5iKGEpKSxzPXQuJHRpLHI9cy5DKCJ+KDEpIikuYihuZXcgTC5kTigpKQp1Lk0uYihudWxsKQpX
-LkpFKHQuYSx0LmIsciwhMSxzLmQpfSwKJFM6M30KTC5kTi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgdAp1LlYuYihhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0i
-KQp0LnRvU3RyaW5nCkwudDIoYSx0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3
-KHQpKS5PKCJwYXRoIikpKX0sCiRTOjZ9CkwuSG8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHQscyxyCnUuaC5iKGEpCnQ9Si5xRihhKQpzPXQuJHRpCnI9cy5DKCJ+KDEpIikuYihuZXcgTC54eihh
-LHRoaXMuYSkpCnUuTS5iKG51bGwpClcuSkUodC5hLHQuYixyLCExLHMuZCl9LAokUzozfQpMLnh6LnBy
-b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5iKGEpCnQ9dGhpcy5hCkwuaFgodGhpcy5i
-LFAuUUEodC5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygib2Zmc2V0
-IikpLG51bGwsbnVsbCkpfSwKJFM6Nn0KTC5JQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
-dD1KLnFGKHUuaC5iKGEpKSxzPXQuJHRpCnMuQygifigxKSIpLmIoTC5IMCgpKQp1Lk0uYihudWxsKQpX
-LkpFKHQuYSx0LmIsTC5IMCgpLCExLHMuZCl9LAokUzozfQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0
-aW9uKCl7TC5Gcih0aGlzLmEuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjB9CkwuQloucHJvdG90eXBlPXsK
-JDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYS5hLG51bGwsbnVsbCl9LAokUzowfQpMLkZRLnByb3RvdHlw
-ZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXUuci5iKGEpLnN0YXR1cwppZih0IT09MjAwKXdpbmRvdy5h
-bGVydCgiUmVxdWVzdCBmYWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo1fQpMLnRZLnByb3Rv
-dHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5xSigiaGFuZGxlUG9zdExpbmtDbGljazogIitILmQoYSks
-YikKd2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9hZCAiK0guZCh0aGlzLmEuYSkrIiAoIitILmQoYSkr
-IikuIil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLkdILnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3UuaC5iKGEpCiQuekIoKS50b1N0cmluZwp1Lm0uYigkLm93KCkucSgwLCJobGpzIikpLlY3KCJoaWdo
-bGlnaHRCbG9jayIsW2FdKX0sCiRTOjN9CkwuRFQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHQKdS5yLmIoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtMLlQxKFUueXUoQy5DdC5wVygwLGEucmVz
-cG9uc2VUZXh0LG51bGwpKSkKTC55WCgiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiKX1lbHNlIHdp
-bmRvdy5hbGVydCgiUmVxdWVzdCBmYWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo1fQpMLmVI
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5xSigibG9hZFJlZ2lvbkV4cGxhbmF0aW9uOiAi
-K0guZChhKSxiKQp3aW5kb3cuYWxlcnQoIkNvdWxkIG5vdCBsb2FkICIrSC5kKHRoaXMuYSkrIiAoIitI
-LmQoYSkrIikuIil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLnpELnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciB0LHMscj10aGlzCnUuci5iKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMCl7cz1yLmEK
-TC5CRShzLHUuYS5iKEMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKSkpCnQ9ci5iCkwuZkcodCxy
-LmMpCkwuQlgoQy54Qi50ZyhzLCI/Iik/Qy54Qi5OaihzLDAsQy54Qi5PWShzLCI/IikpOnMsdCkKdD1y
-LmQKaWYodCE9bnVsbCl0LiQwKCl9ZWxzZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3QgZmFpbGVkOyBzdGF0
-dXMgb2YgIitILmQodCkpfSwKJFM6NX0KTC5PRS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wu
-cUooImxvYWRGaWxlOiAiK0guZChhKSxiKQp3aW5kb3cuYWxlcnQoIkNvdWxkIG5vdCBsb2FkICIrdGhp
-cy5hKyIgKCIrSC5kKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MX0KTC5UVy5wcm90b3R5cGU9
-ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKdS5yLmIoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtz
-PUMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQpyPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5u
-YXYtdHJlZSIpCkoubDUociwiIikKTC50WChyLHMpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZh
-aWxlZDsgc3RhdHVzIG9mICIrSC5kKHQpKX0sCiRTOjV9CkwueHIucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
-b24oYSxiKXtMLnFKKCJsb2FkTmF2aWdhdGlvblRyZWU6ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgi
-Q291bGQgbm90IGxvYWQgIit0aGlzLmErIiAoIitILmQoYSkrIikuIil9LAokQzoiJDIiLAokUjoyLAok
-UzoxfQpMLkVFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdS5WLmIoYSkKdD10aGlz
-LmEKcz10aGlzLmIKTC5hZih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsdCxzLG5ldyBMLlFMKHQscykp
-CkwuaFgodGhpcy5jLHQpfSwKJFM6Nn0KTC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIo
-d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KTC5WUy5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPSJzZWxlY3RlZC1maWxlIgp1LmguYihhKQphLnRvU3Ry
-aW5nCnQ9Si5SRShhKQppZihhLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEp
-KS5PKCJuYW1lIikpPT09dGhpcy5hLmEpdC5nRChhKS5pKDAscykKZWxzZSB0LmdEKGEpLlIoMCxzKX0s
-CiRTOjN9CkwuWEEucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiEwfSwKaTA6ZnVu
-Y3Rpb24oYSl7cmV0dXJuITB9LAokaWtGOjF9Ck0ubEkucHJvdG90eXBlPXsKV086ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzPW51bGwKTS5ZRigiYWJzb2x1dGUiLEguVk0oW2IsbnVsbCxudWxsLG51bGwsbnVsbCxu
-dWxsLG51bGxdLHUucykpCnQ9dGhpcy5hCnQ9dC5ZcihiKT4wJiYhdC5oSyhiKQppZih0KXJldHVybiBi
-CnQ9RC5SWCgpCnJldHVybiB0aGlzLnE3KDAsdCxiLHMscyxzLHMscyxzKX0sCnRNOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscj1YLkNMKGEsdGhpcy5hKQpyLklWKCkKdD1yLmQKcz10Lmxlbmd0aAppZihzPT09MCl7
-dD1yLmIKcmV0dXJuIHQ9PW51bGw/Ii4iOnR9aWYocz09PTEpe3Q9ci5iCnJldHVybiB0PT1udWxsPyIu
-Ijp0fWlmKDA+PXMpcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpDLk5tLm12KHIuZSkKci5JVigpCnJl
-dHVybiByLncoMCl9LApxNzpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQ9SC5WTShbYixj
-LGQsZSxmLGcsaCxpXSx1LnMpCk0uWUYoImpvaW4iLHQpCnJldHVybiB0aGlzLklQKG5ldyBILlU1KHQs
-dS5iQi5iKG5ldyBNLk1pKCkpLHUuY2MpKX0sCklQOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxu
-LG0sbAp1LlguYihhKQpmb3IodD1hLiR0aSxzPXQuQygiYTIoY1guRSkiKS5iKG5ldyBNLnE3KCkpLHI9
-YS5na3ooYSksdD1uZXcgSC5TTyhyLHMsdC5DKCJTTzxjWC5FPiIpKSxzPXRoaXMuYSxxPSExLHA9ITEs
-bz0iIjt0LkYoKTspe249ci5nbCgpCmlmKHMuaEsobikmJnApe209WC5DTChuLHMpCmw9by5jaGFyQ29k
-ZUF0KDApPT0wP286bwpvPUMueEIuTmoobCwwLHMuU3AobCwhMCkpCm0uYj1vCmlmKHMuZHMobykpQy5O
-bS5ZKG0uZSwwLHMuZ21JKCkpCm89bS53KDApfWVsc2UgaWYocy5ZcihuKT4wKXtwPSFzLmhLKG4pCm89
-SC5kKG4pfWVsc2V7aWYoIShuLmxlbmd0aD4wJiZzLlVkKG5bMF0pKSlpZihxKW8rPXMuZ21JKCkKbys9
-SC5kKG4pfXE9cy5kcyhuKX1yZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCm81OmZ1bmN0aW9u
-KGEpe3ZhciB0CmlmKCF0aGlzLnkzKGEpKXJldHVybiBhCnQ9WC5DTChhLHRoaXMuYSkKdC5yUigpCnJl
-dHVybiB0LncoMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsawphLnRvU3Ry
-aW5nCnQ9dGhpcy5hCnM9dC5ZcihhKQppZihzIT09MCl7aWYodD09PSQuS2soKSlmb3Iocj0wO3I8czsr
-K3IpaWYoQy54Qi5XKGEscik9PT00NylyZXR1cm4hMApxPXMKcD00N31lbHNle3E9MApwPW51bGx9Zm9y
-KG89bmV3IEgucWooYSkuYSxuPW8ubGVuZ3RoLHI9cSxtPW51bGw7cjxuOysrcixtPXAscD1sKXtsPUMu
-eEIubShvLHIpCmlmKHQucjQobCkpe2lmKHQ9PT0kLktrKCkmJmw9PT00NylyZXR1cm4hMAppZihwIT1u
-dWxsJiZ0LnI0KHApKXJldHVybiEwCmlmKHA9PT00NilrPW09PW51bGx8fG09PT00Nnx8dC5yNChtKQpl
-bHNlIGs9ITEKaWYoaylyZXR1cm4hMH19aWYocD09bnVsbClyZXR1cm4hMAppZih0LnI0KHApKXJldHVy
-biEwCmlmKHA9PT00Nil0PW09PW51bGx8fHQucjQobSl8fG09PT00NgplbHNlIHQ9ITEKaWYodClyZXR1
-cm4hMApyZXR1cm4hMX0sCkhQOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPXRoaXMsbj0nVW5h
-YmxlIHRvIGZpbmQgYSBwYXRoIHRvICInCmI9by5XTygwLGIpCnQ9by5hCmlmKHQuWXIoYik8PTAmJnQu
-WXIoYSk+MClyZXR1cm4gby5vNShhKQppZih0LllyKGEpPD0wfHx0LmhLKGEpKWE9by5XTygwLGEpCmlm
-KHQuWXIoYSk8PTAmJnQuWXIoYik+MCl0aHJvdyBILmIoWC5KVChuK0guZChhKSsnIiBmcm9tICInK0gu
-ZChiKSsnIi4nKSkKcz1YLkNMKGIsdCkKcy5yUigpCnI9WC5DTChhLHQpCnIuclIoKQpxPXMuZAppZihx
-Lmxlbmd0aD4wJiZKLlJNKHFbMF0sIi4iKSlyZXR1cm4gci53KDApCnE9cy5iCnA9ci5iCmlmKHEhPXAp
-cT1xPT1udWxsfHxwPT1udWxsfHwhdC5OYyhxLHApCmVsc2UgcT0hMQppZihxKXJldHVybiByLncoMCkK
-d2hpbGUoITApe3E9cy5kCmlmKHEubGVuZ3RoPjApe3A9ci5kCnE9cC5sZW5ndGg+MCYmdC5OYyhxWzBd
-LHBbMF0pfWVsc2UgcT0hMQppZighcSlicmVhawpDLk5tLlc0KHMuZCwwKQpDLk5tLlc0KHMuZSwxKQpD
-Lk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKX1xPXMuZAppZihxLmxlbmd0aD4wJiZKLlJNKHFbMF0s
-Ii4uIikpdGhyb3cgSC5iKFguSlQobitILmQoYSkrJyIgZnJvbSAiJytILmQoYikrJyIuJykpCnE9dS5O
-CkMuTm0uVUcoci5kLDAsUC5POChzLmQubGVuZ3RoLCIuLiIscSkpCkMuTm0uWShyLmUsMCwiIikKQy5O
-bS5VRyhyLmUsMSxQLk84KHMuZC5sZW5ndGgsdC5nbUkoKSxxKSkKdD1yLmQKcT10Lmxlbmd0aAppZihx
-PT09MClyZXR1cm4iLiIKaWYocT4xJiZKLlJNKEMuTm0uZ3JaKHQpLCIuIikpe3Q9ci5kCmlmKDA+PXQu
-bGVuZ3RoKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKdD1yLmUKQy5ObS5tdih0KQpDLk5tLm12KHQp
-CkMuTm0uaSh0LCIiKX1yLmI9IiIKci5JVigpCnJldHVybiByLncoMCl9fQpNLk1pLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBILnkoYSkhPW51bGx9LAokUzo3fQpNLnE3LnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBILnkoYSkhPT0iIn0sCiRTOjd9Ck0uTm8ucHJvdG90eXBlPXsK
-JDE6ZnVuY3Rpb24oYSl7SC55KGEpCnJldHVybiBhPT1udWxsPyJudWxsIjonIicrYSsnIid9LAokUzo4
-fQpCLkx1LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5ZcihhKQppZihzPjAp
-cmV0dXJuIEoubGQoYSwwLHMpCmlmKHRoaXMuaEsoYSkpe2lmKDA+PWEubGVuZ3RoKXJldHVybiBILk9I
-KGEsMCkKdD1hWzBdfWVsc2UgdD1udWxsCnJldHVybiB0fSwKTmM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-YT09Yn19ClguV0QucHJvdG90eXBlPXsKSVY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcwp3aGlsZSgh
-MCl7dD1yLmQKaWYoISh0Lmxlbmd0aCE9PTAmJkouUk0oQy5ObS5ncloodCksIiIpKSlicmVhawp0PXIu
-ZAppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCkMuTm0ubXYoci5lKX10PXIu
-ZQpzPXQubGVuZ3RoCmlmKHM+MClDLk5tLlkodCxzLTEsIiIpfSwKclI6ZnVuY3Rpb24oKXt2YXIgdCxz
-LHIscSxwLG8sbixtPXRoaXMsbD1ILlZNKFtdLHUucykKZm9yKHQ9bS5kLHM9dC5sZW5ndGgscj0wLHE9
-MDtxPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0Kbz1KLmlhKHAp
-CmlmKCEoby5ETihwLCIuIil8fG8uRE4ocCwiIikpKWlmKG8uRE4ocCwiLi4iKSlpZihsLmxlbmd0aD4w
-KWwucG9wKCkKZWxzZSArK3IKZWxzZSBDLk5tLmkobCxwKX1pZihtLmI9PW51bGwpQy5ObS5VRyhsLDAs
-UC5POChyLCIuLiIsdS5OKSkKaWYobC5sZW5ndGg9PT0wJiZtLmI9PW51bGwpQy5ObS5pKGwsIi4iKQpu
-PVAuZEgobC5sZW5ndGgsbmV3IFgucVIobSksITAsdS5OKQp0PW0uYgp0PXQhPW51bGwmJmwubGVuZ3Ro
-PjAmJm0uYS5kcyh0KT9tLmEuZ21JKCk6IiIKSC50NihuKS5kLmIodCkKaWYoISFuLmZpeGVkJGxlbmd0
-aClILnZoKFAuTDQoImluc2VydCIpKQpuLnNwbGljZSgwLDAsdCkKbS5zbkoobCkKbS5zUGgobikKdD1t
-LmIKaWYodCE9bnVsbCYmbS5hPT09JC5LaygpKXt0LnRvU3RyaW5nCm0uYj1ILnlzKHQsIi8iLCJcXCIp
-fW0uSVYoKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1yLmIKcT1xIT1udWxsP3E6IiIK
-Zm9yKHQ9MDt0PHIuZC5sZW5ndGg7Kyt0KXtzPXIuZQppZih0Pj1zLmxlbmd0aClyZXR1cm4gSC5PSChz
-LHQpCnM9cStILmQoc1t0XSkKcT1yLmQKaWYodD49cS5sZW5ndGgpcmV0dXJuIEguT0gocSx0KQpxPXMr
-SC5kKHFbdF0pfXErPUguZChDLk5tLmdyWihyLmUpKQpyZXR1cm4gcS5jaGFyQ29kZUF0KDApPT0wP3E6
-cX0sCnNuSjpmdW5jdGlvbihhKXt0aGlzLmQ9dS5pLmIoYSl9LApzUGg6ZnVuY3Rpb24oYSl7dGhpcy5l
-PXUuaS5iKGEpfX0KWC5xUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmEu
-Z21JKCl9LAokUzozN30KWC5kdi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRoRXhj
-ZXB0aW9uOiAiK3RoaXMuYX19Ck8uekwucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy5nb2ModGhpcyl9fQpFLk9GLnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRn
-KGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIg
-dD1hLmxlbmd0aApyZXR1cm4gdCE9PTAmJkMueEIubShhLHQtMSkhPT00N30sClNwOmZ1bmN0aW9uKGEs
-Yil7aWYoYS5sZW5ndGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwKWXI6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4hMX0s
-CmdvYzpmdW5jdGlvbigpe3JldHVybiJwb3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpG
-LnJ1LnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1
-bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0
-PT09MClyZXR1cm4hMQppZihDLnhCLm0oYSx0LTEpIT09NDcpcmV0dXJuITAKcmV0dXJuIEMueEIuVGMo
-YSwiOi8vIikmJnRoaXMuWXIoYSk9PT10fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPWEu
-bGVuZ3RoCmlmKHA9PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKZm9yKHQ9
-MDt0PHA7Kyt0KXtzPUMueEIuVyhhLHQpCmlmKHM9PT00NylyZXR1cm4gMAppZihzPT09NTgpe2lmKHQ9
-PT0wKXJldHVybiAwCnI9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8vIix0KzEpP3QrMzp0KQppZihy
-PD0wKXJldHVybiBwCmlmKCFifHxwPHIrMylyZXR1cm4gcgppZighQy54Qi5uKGEsImZpbGU6Ly8iKSly
-ZXR1cm4gcgppZighQi5ZdShhLHIrMSkpcmV0dXJuIHIKcT1yKzMKcmV0dXJuIHA9PT1xP3E6cis0fX1y
-ZXR1cm4gMH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24o
-YSl7cmV0dXJuIGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00N30sCmdvYzpmdW5jdGlvbigpe3Jl
-dHVybiJ1cmwifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIi8ifX0KTC5JVi5wcm90b3R5cGU9ewpVZDpm
-dW5jdGlvbihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09
-PTQ3fHxhPT09OTJ9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1cm4h
-MQp0PUMueEIubShhLHQtMSkKcmV0dXJuISh0PT09NDd8fHQ9PT05Mil9LApTcDpmdW5jdGlvbihhLGIp
-e3ZhciB0LHMscj1hLmxlbmd0aAppZihyPT09MClyZXR1cm4gMAp0PUMueEIuVyhhLDApCmlmKHQ9PT00
-NylyZXR1cm4gMQppZih0PT09OTIpe2lmKHI8Mnx8Qy54Qi5XKGEsMSkhPT05MilyZXR1cm4gMQpzPUMu
-eEIuWFUoYSwiXFwiLDIpCmlmKHM+MCl7cz1DLnhCLlhVKGEsIlxcIixzKzEpCmlmKHM+MClyZXR1cm4g
-c31yZXR1cm4gcn1pZihyPDMpcmV0dXJuIDAKaWYoIUIuT1ModCkpcmV0dXJuIDAKaWYoQy54Qi5XKGEs
-MSkhPT01OClyZXR1cm4gMApyPUMueEIuVyhhLDIpCmlmKCEocj09PTQ3fHxyPT09OTIpKXJldHVybiAw
-CnJldHVybiAzfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5ZcihhKT09PTF9LApPdDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PT1i
-KXJldHVybiEwCmlmKGE9PT00NylyZXR1cm4gYj09PTkyCmlmKGE9PT05MilyZXR1cm4gYj09PTQ3Cmlm
-KChhXmIpIT09MzIpcmV0dXJuITEKdD1hfDMyCnJldHVybiB0Pj05NyYmdDw9MTIyfSwKTmM6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzLHIKaWYoYT09YilyZXR1cm4hMAp0PWEubGVuZ3RoCmlmKHQhPT1iLmxlbmd0
-aClyZXR1cm4hMQpmb3Iocz1KLnJZKGIpLHI9MDtyPHQ7KytyKWlmKCF0aGlzLk90KEMueEIuVyhhLHIp
-LHMuVyhiLHIpKSlyZXR1cm4hMQpyZXR1cm4hMH0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ3aW5kb3dz
-In0sCmdtSTpmdW5jdGlvbigpe3JldHVybiJcXCJ9fTsoZnVuY3Rpb24gYWxpYXNlcygpe3ZhciB0PUou
-dkIucHJvdG90eXBlCnQuVT10LncKdC5Taj10LmU3CnQ9Si5NRi5wcm90b3R5cGUKdC50PXQudwp0PVAu
-Y1gucHJvdG90eXBlCnQuR0c9dC5ldgp0PVAuay5wcm90b3R5cGUKdC54Yj10LncKdD1XLmN2LnByb3Rv
-dHlwZQp0LkRXPXQucjYKdD1XLm02LnByb3RvdHlwZQp0LmpGPXQuRWIKdD1QLkU0LnByb3RvdHlwZQp0
-LlVyPXQucQp0LmU0PXQuWX0pKCk7KGZ1bmN0aW9uIGluc3RhbGxUZWFyT2Zmcygpe3ZhciB0PWh1bmtI
-ZWxwZXJzLl9zdGF0aWNfMSxzPWh1bmtIZWxwZXJzLl9zdGF0aWNfMCxyPWh1bmtIZWxwZXJzLmluc3Rh
-bGxJbnN0YW5jZVRlYXJPZmYscT1odW5rSGVscGVycy5pbnN0YWxsU3RhdGljVGVhck9mZgp0KFAsIkVY
-IiwiWlYiLDkpCnQoUCwieXQiLCJvQSIsOSkKdChQLCJxVyIsIkJ6Iiw5KQpzKFAsIlVJIiwiZU4iLDIp
-CnIoUC5QZi5wcm90b3R5cGUsImdZSiIsMCwxLG51bGwsWyIkMiIsIiQxIl0sWyJ3MCIsInBtIl0sMzYs
-MCkKdChQLCJQSCIsIk10Iiw4KQpxKFcsInBTIiw0LG51bGwsWyIkNCJdLFsieVciXSwxMSwwKQpxKFcs
-IlY0Iiw0LG51bGwsWyIkNCJdLFsiUVciXSwxMSwwKQp0KFAsImlHIiwid1kiLDQpCnQoUCwidzAiLCJM
-NyIsNDApCnEoTCwiWE4iLDEsbnVsbCxbIiQyJHJlbGF0aXZlVG8iLCIkMSJdLFsidDIiLGZ1bmN0aW9u
-KGEpe3JldHVybiBMLnQyKGEsbnVsbCl9XSw0MSwwKQp0KEwsIkgwIiwidW0iLDI4KX0pKCk7KGZ1bmN0
-aW9uIGluaGVyaXRhbmNlKCl7dmFyIHQ9aHVua0hlbHBlcnMubWl4aW4scz1odW5rSGVscGVycy5pbmhl
-cml0LHI9aHVua0hlbHBlcnMuaW5oZXJpdE1hbnkKcyhQLmssbnVsbCkKcihQLmssW0guZW8sSi52QixK
-Lm0xLFAublksUC5jWCxILmE3LFAuQW4sSC5TVSxILlJlLEgud3YsUC5QbixILldVLEguTEksSC5UcCxI
-LlpyLFAuWFMsSC5YTyxQLllrLEguZGIsSC5ONixILlZSLEguRUssSC5QYixILnRRLEguU2QsSC5KYyxI
-LkcsUC5XMyxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5NTyxQLmtULFAuQ3csUC5tMCxQLlh2LFAu
-Ym4sUC5sbSxQLmxELFAuS1AsUC5sZixQLldZLFAuVWssUC5SdyxQLmJ6LFAuYTIsUC5pUCxQLkZLLFAu
-azUsUC5LWSxQLkNELFAuYUUsUC5FSCxQLnpNLFAuWjAsUC5jOCxQLk9kLFAuaWIsUC5HeixQLnFVLFAu
-Um4sUC5HRCxQLkRuLFAuUEUsUC5VZixXLmlkLFcuRmssVy5KUSxXLkdtLFcudkQsVy5tNixXLk93LFcu
-VzksVy5kVyxXLmtGLFcubWssVy5LbyxQLmlKLFAuRTQsUC5uNixVLmQyLFUuU2UsVS51RixVLk1sLFQu
-R1YsTC5YQSxNLmxJLE8uekwsWC5XRCxYLmR2XSkKcihKLnZCLFtKLnlFLEouWUUsSi5NRixKLmpkLEou
-cUksSi5EcixILkVULFcuRDAsVy5BeixXLkxlLFcuTmgsVy5JQixXLm43LFcuZWEsVy5icixXLlNnLFcu
-dTgsVy5LNyxXLlhXLFAuaEZdKQpyKEouTUYsW0ouaUMsSi5rZCxKLmM1XSkKcyhKLlBvLEouamQpCnIo
-Si5xSSxbSi51cixKLlZBXSkKcyhQLkxVLFAublkpCnIoUC5MVSxbSC5YQyxXLnd6LFcuZTddKQpzKEgu
-cWosSC5YQykKcihQLmNYLFtILmJRLEguVTUsUC5tVyxILnVuXSkKcihILmJRLFtILmFMLEguaTUsUC54
-dV0pCnIoSC5hTCxbSC5uSCxILkE4LFAuaThdKQpzKEguU08sUC5BbikKcyhQLlJVLFAuUG4pCnMoUC5H
-aixQLlJVKQpzKEguUEQsUC5HaikKcyhILkxQLEguV1UpCnIoSC5UcCxbSC5DaixILkFtLEgubGMsSC5k
-QyxILndOLEguVlgsUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuZGEsUC5vUSxQLnBWLFAuVTcsUC52
-cixQLnJILFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUsUC5QSSxQLnBLLFAuaGosUC5W
-cCxQLk9SLFAuR0EsUC5XRixQLm4xLFAuY1MsUC5WQyxQLnRwLFAuZTEsUC5OWSxQLlJaLFAuTUUsUC55
-NSxQLnEzLFAueUksUC5jNixQLnFkLFcuQ3YsVy5iVSxXLmhILFcuS1MsVy5BMyxXLnZOLFcuVXYsVy5F
-ZyxXLkVvLFcuV2ssVy5JQSxXLmZtLFAubFIsUC5qZyxQLkdFLFAuUEMsUC5ZbSxQLk56LFAuUVMsUC5u
-cCxMLmUsTC5WVyxMLkwsTC5XeCxMLkFPLEwuZE4sTC5IbyxMLnh6LEwuSUMsTC5uVCxMLkJaLEwuRlEs
-TC50WSxMLkdILEwuRFQsTC5lSCxMLnpELEwuT0UsTC5UVyxMLnhyLEwuRUUsTC5RTCxMLlZTLE0uTWks
-TS5xNyxNLk5vLFgucVJdKQpyKFAuWFMsW0guVzAsSC5heixILnZWLEguRXEsUC5DNixILnU5LFAubixQ
-LnUsUC5tcCxQLnViLFAuZHMsUC5saixQLlVWLFAuY10pCnIoSC5sYyxbSC56eCxILnJUXSkKcyhILmtZ
-LFAuQzYpCnMoUC5pbCxQLllrKQpyKFAuaWwsW0guTjUsUC51dyxXLkQ5LFcuU3ldKQpzKEguS1csUC5t
-VykKcyhILmIwLEguRVQpCnIoSC5iMCxbSC5SRyxILldCXSkKcyhILlZQLEguUkcpCnMoSC5EZyxILlZQ
-KQpzKEguWkcsSC5XQikKcyhILlBnLEguWkcpCnIoSC5QZyxbSC54aixILmRFLEguWkEsSC53ZixILlBx
-LEguZUUsSC5WNl0pCnIoSC51OSxbSC5oeixILmlNXSkKcyhQLlpmLFAuUGYpCnMoUC5KaSxQLm0wKQpz
-KFAuYjYsUC5YdikKcyhQLlZqLFAuV1kpCnIoUC5VayxbUC5DVixQLlppLFAuYnldKQpzKFAud0ksUC5r
-VCkKcihQLndJLFtQLlU4LFAuTXgsUC5FMyxQLkdZXSkKcyhQLnU1LFAuWmkpCnIoUC5GSyxbUC5DUCxQ
-LktOXSkKcihQLnUsW1AuYkosUC5lWV0pCnMoUC5xZSxQLkRuKQpyKFcuRDAsW1cudUgsVy53YSxXLks1
-LFcuQ21dKQpyKFcudUgsW1cuY3YsVy5ueCxXLlFGLFcuQ1FdKQpyKFcuY3YsW1cucUUsUC5kNV0pCnIo
-Vy5xRSxbVy5HaCxXLmZZLFcubkIsVy5RUCxXLmg0LFcuU04sVy5scCxXLlRiLFcuSXYsVy5CVCxXLnlZ
-XSkKcyhXLm9KLFcuTGUpCnMoVy5UNSxXLkF6KQpzKFcuVmIsVy5RRikKcyhXLk83LFcud2EpCnIoVy5l
-YSxbVy53NixXLmV3XSkKcyhXLkFqLFcudzYpCnMoVy5yQixXLks3KQpzKFcuQkgsVy5yQikKcyhXLnc0
-LFcuSUIpCnMoVy5vYSxXLlhXKQpzKFcucmgsVy5vYSkKcyhXLmk3LFcuRDkpCnMoUC5BcyxQLlZqKQpy
-KFAuQXMsW1cuSTQsUC5LZV0pCnMoVy5STyxQLnFoKQpzKFcuQ3EsVy5STykKcyhXLnhDLFAuTU8pCnMo
-Vy5jdCxXLm02KQpzKFAuQmYsUC5pSikKcihQLkU0LFtQLnI3LFAuY29dKQpzKFAuVHosUC5jbykKcyhQ
-Lm5kLFAuZDUpCnMoQi5MdSxPLnpMKQpyKEIuTHUsW0UuT0YsRi5ydSxMLklWXSkKdChILlhDLEguUmUp
-CnQoSC5SRyxQLmxEKQp0KEguVlAsSC5TVSkKdChILldCLFAubEQpCnQoSC5aRyxILlNVKQp0KFAublks
-UC5sRCkKdChQLldZLFAubGYpCnQoUC5SVSxQLktQKQp0KFcuTGUsVy5pZCkKdChXLks3LFAubEQpCnQo
-Vy5yQixXLkdtKQp0KFcuWFcsUC5sRCkKdChXLm9hLFcuR20pCnQoUC5jbyxQLmxEKX0pKCkKdmFyIHY9
-e3R5cGVVbml2ZXJzZTp7ZUM6bmV3IE1hcCgpLHRSOnt9LGVUOnt9LHRQVjp7fSxzRUE6W119LG1hbmds
-ZWRHbG9iYWxOYW1lczp7S046ImludCIsQ1A6ImRvdWJsZSIsRks6Im51bSIscVU6IlN0cmluZyIsYTI6
-ImJvb2wiLGM4OiJOdWxsIix6TToiTGlzdCJ9LG1hbmdsZWROYW1lczp7fSxnZXRUeXBlRnJvbU5hbWU6
-Z2V0R2xvYmFsRnJvbU5hbWUsbWV0YWRhdGE6W10sdHlwZXM6WyJjOCgpIiwiYzgoQCxAKSIsIn4oKSIs
-ImM4KGN2KSIsIkAoQCkiLCJjOChPNykiLCJjOChBaikiLCJhMihxVSkiLCJxVShxVSkiLCJ+KH4oKSki
-LCJjOChxVSxxVSkiLCJhMihjdixxVSxxVSxKUSkiLCJjOChAKSIsImM4KGVhKSIsImEyKGtGKSIsImM4
-KHFVLEApIiwiYzgocVUpIiwiS04oS04sS04pIiwifihxVVtAXSkiLCJ+KHFVLHFVKSIsIm42KEtOKSIs
-In4ocVUsS04pIiwiYTIodUgpIiwiWjA8cVUscVU+KFowPHFVLHFVPixxVSkiLCJjOChldykiLCJAKGVh
-KSIsImM4KEdELEApIiwiQChxVSkiLCJ+KEFqKSIsImEyKHh1PHFVPikiLCJyNyhAKSIsIlR6PEA+KEAp
-IiwiRTQoQCkiLCJ2czxAPihAKSIsImM4KEBbR3pdKSIsIn4odUgsdUgpIiwifihrW0d6XSkiLCJxVShL
-TikiLCJAKEAscVUpIiwiYzgofigpKSIsImsoQCkiLCJ+KEFqe3JlbGF0aXZlVG86cVV9KSIsIm42KEAs
-QCkiXSxpbnRlcmNlcHRvcnNCeVRhZzpudWxsLGxlYWZUYWdzOm51bGx9CkgueGIodi50eXBlVW5pdmVy
-c2UsSlNPTi5wYXJzZSgneyJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiZDUiLCJXdCI6ImQ1IiwidjAi
-OiJldyIsIk1yIjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwieWMi
-OiJBaiIsInk0IjoidzYiLCJhUCI6IkNtIiwianIiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYi
-OiJFVCIsInlFIjp7ImEyIjpbXX0sIllFIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXX0sImlDIjp7InZt
-IjpbXX0sImtkIjp7InZtIjpbXX0sImM1Ijp7IkVIIjpbXSwidm0iOltdfSwiamQiOnsiek0iOlsiMSJd
-LCJjWCI6WyIxIl19LCJQbyI6eyJqZCI6WyIxIl0sInpNIjpbIjEiXSwiY1giOlsiMSJdfSwibTEiOnsi
-QW4iOlsiMSJdfSwicUkiOnsiQ1AiOltdLCJGSyI6W119LCJ1ciI6eyJLTiI6W10sIkNQIjpbXSwiRksi
-OltdfSwiVkEiOnsiQ1AiOltdLCJGSyI6W119LCJEciI6eyJxVSI6W10sInZYIjpbXX0sInFqIjp7IlJl
-IjpbIktOIl0sImxEIjpbIktOIl0sInpNIjpbIktOIl0sImNYIjpbIktOIl0sImxELkUiOiJLTiIsIlJl
-LkUiOiJLTiJ9LCJiUSI6eyJjWCI6WyIxIl19LCJhTCI6eyJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIx
-Il0sImNYIjpbIjEiXSwiYUwuRSI6IjEiLCJjWC5FIjoiMSJ9LCJhNyI6eyJBbiI6WyIxIl19LCJBOCI6
-eyJhTCI6WyIyIl0sImNYIjpbIjIiXSwiYUwuRSI6IjIiLCJjWC5FIjoiMiJ9LCJVNSI6eyJjWCI6WyIx
-Il0sImNYLkUiOiIxIn0sIlNPIjp7IkFuIjpbIjEiXX0sIlhDIjp7IlJlIjpbIjEiXSwibEQiOlsiMSJd
-LCJ6TSI6WyIxIl0sImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0s
-IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19
-LCJXVSI6eyJaMCI6WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0s
-IkxJIjp7InZRIjpbXX0sIlcwIjp7IlhTIjpbXX0sImF6Ijp7IlhTIjpbXX0sInZWIjp7IlhTIjpbXX0s
-IlhPIjp7Ikd6IjpbXX0sIlRwIjp7IkVIIjpbXX0sImxjIjp7IkVIIjpbXX0sInp4Ijp7IkVIIjpbXX0s
-InJUIjp7IkVIIjpbXX0sIkVxIjp7IlhTIjpbXX0sImtZIjp7IlhTIjpbXX0sIk41Ijp7IkZvIjpbIjEi
-LCIyIl0sIllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl0sIllrLksiOiIxIiwiWWsuViI6IjIifSwi
-aTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6eyJBbiI6WyIxIl19LCJWUiI6eyJ3TCI6W10s
-InZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwiS1ciOnsiY1giOlsiaWIiXSwiY1guRSI6Imli
-In0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6W119LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5F
-IjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7IkFTIjpbXX0sImIwIjp7IlhqIjpbIkAiXSwi
-RVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJdLCJYaiI6WyJAIl0sInpNIjpbIkNQIl0sIkVU
-IjpbXSwiU1UiOlsiQ1AiXSwiQVMiOltdLCJjWCI6WyJDUCJdLCJsRC5FIjoiQ1AifSwiUGciOnsibEQi
-OlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwi
-Y1giOlsiS04iXX0sInhqIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltd
-LCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJkRSI6eyJsRCI6WyJL
-TiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6
-WyJLTiJdLCJsRC5FIjoiS04ifSwiWkEiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJd
-LCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIndmIjp7
-ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJTVSI6WyJLTiJdLCJBUyI6
-W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJQcSI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJY
-aiI6WyJAIl0sIkVUIjpbXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04i
-fSwiZUUiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNVIjpbIktO
-Il0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIlY2Ijp7Im42IjpbXSwibEQiOlsiS04i
-XSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsi
-S04iXSwibEQuRSI6IktOIn0sInU5Ijp7IlhTIjpbXX0sImh6Ijp7IlhTIjpbXX0sImlNIjp7IlhTIjpb
-XX0sIlpmIjp7IlBmIjpbIjEiXX0sInZzIjp7ImI4IjpbIjEiXX0sIkN3Ijp7IlhTIjpbXX0sIm0wIjp7
-IkpCIjpbXX0sIkppIjp7IkpCIjpbXX0sImI2Ijp7Ilh2IjpbIjEiXSwieHUiOlsiMSJdLCJjWCI6WyIx
-Il19LCJsbSI6eyJBbiI6WyIxIl19LCJtVyI6eyJjWCI6WyIxIl19LCJMVSI6eyJsRCI6WyIxIl0sInpN
-IjpbIjEiXSwiY1giOlsiMSJdfSwiaWwiOnsiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIllr
-Ijp7IlowIjpbIjEiLCIyIl19LCJQbiI6eyJaMCI6WyIxIiwiMiJdfSwiR2oiOnsiUlUiOlsiMSIsIjIi
-XSwiUG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlZqIjp7ImxmIjpb
-IjEiXSwieHUiOlsiMSJdLCJjWCI6WyIxIl19LCJYdiI6eyJ4dSI6WyIxIl0sImNYIjpbIjEiXX0sInV3
-Ijp7IllrIjpbInFVIiwiQCJdLCJaMCI6WyJxVSIsIkAiXSwiWWsuSyI6InFVIiwiWWsuViI6IkAifSwi
-aTgiOnsiYUwiOlsicVUiXSwiY1giOlsicVUiXSwiYUwuRSI6InFVIiwiY1guRSI6InFVIn0sIkNWIjp7
-IlVrIjpbInpNPEtOPiIsInFVIl0sIlVrLlMiOiJ6TTxLTj4ifSwiVTgiOnsid0kiOlsiek08S04+Iiwi
-cVUiXX0sIlppIjp7IlVrIjpbInFVIiwiek08S04+Il19LCJieSI6eyJVayI6WyJrIiwicVUiXSwiVWsu
-UyI6ImsifSwiTXgiOnsid0kiOlsicVUiLCJrIl19LCJ1NSI6eyJVayI6WyJxVSIsInpNPEtOPiJdLCJV
-ay5TIjoicVUifSwiRTMiOnsid0kiOlsicVUiLCJ6TTxLTj4iXX0sIkdZIjp7IndJIjpbInpNPEtOPiIs
-InFVIl19LCJDUCI6eyJGSyI6W119LCJDNiI6eyJYUyI6W119LCJuIjp7IlhTIjpbXX0sInUiOnsiWFMi
-OltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMi
-OltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMi
-OltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJLTiI6eyJGSyI6W119LCJ6TSI6eyJjWCI6
-WyIxIl19LCJpYiI6eyJPZCI6W119LCJ4dSI6eyJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJSbiI6
-eyJCTCI6W119LCJEbiI6eyJpRCI6W119LCJVZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6
-eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiR2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZ
-Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwi
-UVAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsi
-dUgiOltdLCJEMCI6W119LCJJQiI6eyJ0biI6WyJGSyJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIx
-Il0sImNYIjpbIjEiXSwibEQuRSI6IjEifSwiY3YiOnsidUgiOltdLCJEMCI6W119LCJUNSI6eyJBeiI6
-W119LCJoNCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVmIiOnsidUgiOltdLCJEMCI6W119LCJP
-NyI6eyJEMCI6W119LCJ3YSI6eyJEMCI6W119LCJBaiI6eyJlYSI6W119LCJlNyI6eyJsRCI6WyJ1SCJd
-LCJ6TSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgifSwidUgiOnsiRDAiOltdfSwiQkgiOnsi
-R20iOlsidUgiXSwibEQiOlsidUgiXSwiek0iOlsidUgiXSwiWGoiOlsidUgiXSwiY1giOlsidUgiXSwi
-bEQuRSI6InVIIiwiR20uRSI6InVIIn0sIlNOIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJldyI6
-eyJlYSI6W119LCJscCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVGIiOnsiY3YiOltdLCJ1SCI6
-W10sIkQwIjpbXX0sIkl2Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJCVCI6eyJjdiI6W10sInVI
-IjpbXSwiRDAiOltdfSwieVkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sInc2Ijp7ImVhIjpbXX0s
-Iks1Ijp7InY2IjpbXSwiRDAiOltdfSwiQ20iOnsiRDAiOltdfSwiQ1EiOnsidUgiOltdLCJEMCI6W119
-LCJ3NCI6eyJ0biI6WyJGSyJdfSwicmgiOnsiR20iOlsidUgiXSwibEQiOlsidUgiXSwiek0iOlsidUgi
-XSwiWGoiOlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIiwiR20uRSI6InVIIn0sIkQ5Ijp7Illr
-IjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdfSwiaTciOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6
-WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJTeSI6eyJZayI6WyJxVSIsInFVIl0s
-IlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6InFVIn0sIkk0Ijp7ImxmIjpbInFVIl0s
-Inh1IjpbInFVIl0sImNYIjpbInFVIl19LCJSTyI6eyJxaCI6WyIxIl19LCJDcSI6eyJSTyI6WyIxIl0s
-InFoIjpbIjEiXX0sIkpRIjp7ImtGIjpbXX0sInZEIjp7ImtGIjpbXX0sIm02Ijp7ImtGIjpbXX0sImN0
-Ijp7ImtGIjpbXX0sIk93Ijp7ImtGIjpbXX0sIlc5Ijp7IkFuIjpbIjEiXX0sImRXIjp7InY2IjpbXSwi
-RDAiOltdfSwibWsiOnsieTAiOltdfSwiS28iOnsib24iOltdfSwiQXMiOnsibGYiOlsicVUiXSwieHUi
-OlsicVUiXSwiY1giOlsicVUiXX0sInI3Ijp7IkU0IjpbXX0sIlR6Ijp7ImxEIjpbIjEiXSwiek0iOlsi
-MSJdLCJFNCI6W10sImNYIjpbIjEiXSwibEQuRSI6IjEifSwibmQiOnsiZDUiOltdLCJjdiI6W10sInVI
-IjpbXSwiRDAiOltdfSwiS2UiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiY1giOlsicVUiXX0sImQ1
-Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJuNiI6eyJ6TSI6WyJLTiJdLCJBUyI6W10sImNYIjpb
-IktOIl19LCJYQSI6eyJrRiI6W119LCJPRiI6eyJMdSI6W119LCJydSI6eyJMdSI6W119LCJJViI6eyJM
-dSI6W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYlEiOjEsIlhDIjoxLCJN
-TyI6MSwia1QiOjIsIm1XIjoxLCJMVSI6MSwiaWwiOjIsIlZqIjoxLCJuWSI6MSwiV1kiOjEsImNvIjox
-fScpKQp2YXIgdT0oZnVuY3Rpb24gcnRpaSgpe3ZhciB0PUguTjAKcmV0dXJue2s6dCgiR2giKSxuOnQo
-IkN3IiksRjp0KCJuQiIpLGQ6dCgiQXoiKSxZOnQoIlFQIiksZ0Y6dCgiUEQ8R0QsQD4iKSxoOnQoImN2
-IiksYlU6dCgiWFMiKSxCOnQoImVhIiksYVM6dCgiRDAiKSxjODp0KCJUNSIpLFo6dCgiRUgiKSxjOnQo
-ImI4PEA+Iikscjp0KCJPNyIpLEk6dCgiU2ciKSxvOnQoInZRIiksZWg6dCgiY1g8dUg+IiksWDp0KCJj
-WDxxVT4iKSxSOnQoImNYPEA+IiksZkE6dCgiamQ8U2U+IiksYlA6dCgiamQ8dUY+IiksUTp0KCJqZDxr
-Rj4iKSxzOnQoImpkPHFVPiIpLGI6dCgiamQ8QD4iKSx0OnQoImpkPEtOPiIpLGVIOnQoInZtIiksZzp0
-KCJjNSIpLGFVOnQoIlhqPEA+IiksYW06dCgiVHo8QD4iKSxlbzp0KCJONTxHRCxAPiIpLG06dCgiRTQi
-KSxkejp0KCJoRiIpLGk6dCgiek08cVU+Iiksajp0KCJ6TTxAPiIpLEw6dCgiek08S04+IiksZjp0KCJa
-MDxxVSxxVT4iKSxhOnQoIlowPHFVLEA+IiksRzp0KCJaMDxALEA+IiksZHY6dCgiQTg8cVUscVU+Iiks
-ZG86dCgiQTg8cVUsQD4iKSxWOnQoIkFqIiksZEQ6dCgiRVQiKSxibTp0KCJWNiIpLEE6dCgidUgiKSxl
-OnQoImtGIiksUDp0KCJjOCIpLEs6dCgiayIpLHA6dCgiZXciKSxxOnQoInRuPEZLPiIpLGZ2OnQoIndM
-IiksZXc6dCgibmQiKSxUOnQoInh1PHFVPiIpLGw6dCgiR3oiKSxOOnQoInFVIiksZEc6dCgicVUocVUp
-IiksZzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFXOnQoInlZIiksdTp0KCJBUyIpLGdjOnQoIm42IiksYWs6
-dCgia2QiKSxXOnQoIkdqPHFVLHFVPiIpLHY6dCgiaUQiKSxjYzp0KCJVNTxxVT4iKSxnNDp0KCJLNSIp
-LGNpOnQoInY2IiksZzI6dCgiQ20iKSxFOnQoIlpmPE83PiIpLGg5OnQoIkNRIiksYWM6dCgiZTciKSxD
-OnQoIkNxPEFqPiIpLFM6dCgid3o8Y3Y+IikseDp0KCJGZTxALEA+IiksYW86dCgidnM8Tzc+IiksXzp0
-KCJ2czxAPiIpLGZKOnQoInZzPEtOPiIpLE86dCgiSlEiKSxKOnQoImJuIiksY0o6dCgiYTIiKSxhbDp0
-KCJhMihrKSIpLGJCOnQoImEyKHFVKSIpLGJmOnQoImEyKEApIiksejp0KCJAIiksZk86dCgiQCgpIiks
-VTp0KCJAKGVhKSIpLHk6dCgiQChrKSIpLGVwOnQoIkAoayxrKSIpLHc6dCgiQChrLEd6KSIpLGNoOnQo
-IkAoeHU8cVU+KSIpLGRPOnQoIkAocVUpIiksYjg6dCgiQChALEApIiksSDp0KCJ+IiksTTp0KCJ+KCki
-KSxhbjp0KCJ+KGV3KSIpLEQ6dCgifihxVSxxVSkiKSxjQTp0KCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rp
-b24gY29uc3RhbnRzKCl7dmFyIHQ9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLlJZPVcuUVAucHJv
-dG90eXBlCkMuQlo9Vy5WYi5wcm90b3R5cGUKQy5EdD1XLk83LnByb3RvdHlwZQpDLk9rPUoudkIucHJv
-dG90eXBlCkMuTm09Si5qZC5wcm90b3R5cGUKQy5qbj1KLnVyLnByb3RvdHlwZQpDLmpOPUouWUUucHJv
-dG90eXBlCkMuQ0Q9Si5xSS5wcm90b3R5cGUKQy54Qj1KLkRyLnByb3RvdHlwZQpDLkRHPUouYzUucHJv
-dG90eXBlCkMuRXg9Vy51OC5wcm90b3R5cGUKQy5MdD1XLlNOLnByb3RvdHlwZQpDLlpRPUouaUMucHJv
-dG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52Qj1KLmtkLnByb3RvdHlwZQpDLm9sPVcuSzUucHJv
-dG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5PW5ldyBQLkNWKCkKQy5PND1mdW5jdGlvbiBnZXRUYWdG
-YWxsYmFjayhvKSB7CiAgdmFyIHMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7CiAg
-cmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7Cn0KQy5ZcT1mdW5jdGlvbigpIHsKICB2
-YXIgdG9TdHJpbmdGdW5jdGlvbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CiAgZnVuY3Rpb24g
-Z2V0VGFnKG8pIHsKICAgIHZhciBzID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG8pOwogICAgcmV0dXJu
-IHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25UYWco
-b2JqZWN0LCB0YWcpIHsKICAgIGlmICgvXkhUTUxbQS1aXS4qRWxlbWVudCQvLnRlc3QodGFnKSkgewog
-ICAgICB2YXIgbmFtZSA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvYmplY3QpOwogICAgICBpZiAobmFt
-ZSA9PSAiW29iamVjdCBPYmplY3RdIikgcmV0dXJuIG51bGw7CiAgICAgIHJldHVybiAiSFRNTEVsZW1l
-bnQiOwogICAgfQogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFnR2VuZXJpY0Jyb3dzZXIob2JqZWN0
-LCB0YWcpIHsKICAgIGlmIChzZWxmLkhUTUxFbGVtZW50ICYmIG9iamVjdCBpbnN0YW5jZW9mIEhUTUxF
-bGVtZW50KSByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIHJldHVybiBnZXRVbmtub3duVGFnKG9iamVj
-dCwgdGFnKTsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnKHRhZykgewogICAgaWYgKHR5cGVv
-ZiB3aW5kb3cgPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgaWYgKHR5cGVvZiB3aW5kb3db
-dGFnXSA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5k
-b3dbdGFnXTsKICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT0gImZ1bmN0aW9uIikgcmV0dXJuIG51
-bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBmdW5jdGlvbiBkaXNjcmlt
-aW5hdG9yKHRhZykgeyByZXR1cm4gbnVsbDsgfQogIHZhciBpc0Jyb3dzZXIgPSB0eXBlb2YgbmF2aWdh
-dG9yID09ICJvYmplY3QiOwogIHJldHVybiB7CiAgICBnZXRUYWc6IGdldFRhZywKICAgIGdldFVua25v
-d25UYWc6IGlzQnJvd3NlciA/IGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlciA6IGdldFVua25vd25U
-YWcsCiAgICBwcm90b3R5cGVGb3JUYWc6IHByb3RvdHlwZUZvclRhZywKICAgIGRpc2NyaW1pbmF0b3I6
-IGRpc2NyaW1pbmF0b3IgfTsKfQpDLndiPWZ1bmN0aW9uKGdldFRhZ0ZhbGxiYWNrKSB7CiAgcmV0dXJu
-IGZ1bmN0aW9uKGhvb2tzKSB7CiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPSAib2JqZWN0IikgcmV0
-dXJuIGhvb2tzOwogICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDsKICAgIGlmICh1YS5pbmRl
-eE9mKCJEdW1wUmVuZGVyVHJlZSIpID49IDApIHJldHVybiBob29rczsKICAgIGlmICh1YS5pbmRleE9m
-KCJDaHJvbWUiKSA+PSAwKSB7CiAgICAgIGZ1bmN0aW9uIGNvbmZpcm0ocCkgewogICAgICAgIHJldHVy
-biB0eXBlb2Ygd2luZG93ID09ICJvYmplY3QiICYmIHdpbmRvd1twXSAmJiB3aW5kb3dbcF0ubmFtZSA9
-PSBwOwogICAgICB9CiAgICAgIGlmIChjb25maXJtKCJXaW5kb3ciKSAmJiBjb25maXJtKCJIVE1MRWxl
-bWVudCIpKSByZXR1cm4gaG9va3M7CiAgICB9CiAgICBob29rcy5nZXRUYWcgPSBnZXRUYWdGYWxsYmFj
-azsKICB9Owp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICBpZiAodHlwZW9mIGRhcnRFeHBlcmltZW50
-YWxGaXh1cEdldFRhZyAhPSAiZnVuY3Rpb24iKSByZXR1cm4gaG9va3M7CiAgaG9va3MuZ2V0VGFnID0g
-ZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnKGhvb2tzLmdldFRhZyk7Cn0KQy5mUT1mdW5jdGlvbiho
-b29rcykgewogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHByb3RvdHlwZUZvclRhZyA9
-IGhvb2tzLnByb3RvdHlwZUZvclRhZzsKICBmdW5jdGlvbiBnZXRUYWdGaXhlZChvKSB7CiAgICB2YXIg
-dGFnID0gZ2V0VGFnKG8pOwogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSB7CiAgICAgIGlmICghIW8u
-eG1sVmVyc2lvbikgcmV0dXJuICIhRG9jdW1lbnQiOwogICAgICByZXR1cm4gIiFIVE1MRG9jdW1lbnQi
-OwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnRml4ZWQo
-dGFnKSB7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHJldHVybiBudWxsOwogICAgcmV0dXJuIHBy
-b3RvdHlwZUZvclRhZyh0YWcpOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXhlZDsKICBob29r
-cy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdGaXhlZDsKfQpDLmRrPWZ1bmN0aW9uKGhv
-b2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBuYXZp
-Z2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKCJGaXJlZm94IikgPT0g
-LTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBxdWlja01h
-cCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRyYW5zZmVyIjog
-IkNsaXBib2FyZCIsCiAgICAiR2VvR2VvbG9jYXRpb24iOiAiR2VvbG9jYXRpb24iLAogICAgIkxvY2F0
-aW9uIjogIiFMb2NhdGlvbiIsCiAgICAiV29ya2VyTWVzc2FnZUV2ZW50IjogIk1lc3NhZ2VFdmVudCIs
-CiAgICAiWE1MRG9jdW1lbnQiOiAiIURvY3VtZW50In07CiAgZnVuY3Rpb24gZ2V0VGFnRmlyZWZveChv
-KSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgcmV0dXJuIHF1aWNrTWFwW3RhZ10gfHwgdGFn
-OwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXJlZm94Owp9CkMueGk9ZnVuY3Rpb24oaG9va3Mp
-IHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRv
-ci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIlRyaWRlbnQvIikgPT0gLTEp
-IHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBxdWlja01hcCA9
-IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRyYW5zZmVyIjogIkNs
-aXBib2FyZCIsCiAgICAiSFRNTERERWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTERURWxl
-bWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTFBocmFzZUVsZW1lbnQiOiAiSFRNTEVsZW1lbnQi
-LAogICAgIlBvc2l0aW9uIjogIkdlb3Bvc2l0aW9uIgogIH07CiAgZnVuY3Rpb24gZ2V0VGFnSUUobykg
-ewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHZhciBuZXdUYWcgPSBxdWlja01hcFt0YWddOwog
-ICAgaWYgKG5ld1RhZykgcmV0dXJuIG5ld1RhZzsKICAgIGlmICh0YWcgPT0gIk9iamVjdCIpIHsKICAg
-ICAgaWYgKHdpbmRvdy5EYXRhVmlldyAmJiAobyBpbnN0YW5jZW9mIHdpbmRvdy5EYXRhVmlldykpIHJl
-dHVybiAiRGF0YVZpZXciOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90
-eXBlRm9yVGFnSUUodGFnKSB7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAgIGlm
-IChjb25zdHJ1Y3RvciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBjb25zdHJ1Y3Rvci5w
-cm90b3R5cGU7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0lFOwogIGhvb2tzLnByb3RvdHlwZUZv
-clRhZyA9IHByb3RvdHlwZUZvclRhZ0lFOwp9CkMuaTc9ZnVuY3Rpb24oaG9va3MpIHsgcmV0dXJuIGhv
-b2tzOyB9CgpDLkN0PW5ldyBQLmJ5KCkKQy5FcT1uZXcgUC5rNSgpCkMueE09bmV3IFAudTUoKQpDLlFr
-PW5ldyBQLkUzKCkKQy5OVT1uZXcgUC5KaSgpCkMuQTM9bmV3IFAuTXgobnVsbCkKQy5HYj1ILlZNKHQo
-WzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5WTSh0KFswLDAsMzI3NzYsMzM3OTIs
-MSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xhc3MiLCIqOjpkaXIiLCIqOjpkcmFn
-Z2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3AiLCIqOjppdGVt
-cmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0aXRsZSIsIio6
-OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5nIiwiQTo6bmFt
-ZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwiQVJFQTo6YWNj
-ZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwiQVJFQTo6c2hh
-cGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9scyIsIkFVRElP
-Ojpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6cHJlbG9hZCIs
-IkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGluayIsIkJPRFk6
-OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5IiwiQlVUVE9O
-OjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRUT046OnR5cGUi
-LCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwiQ0FQVElPTjo6
-YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09MOjpzcGFuIiwi
-Q09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JPVVA6OmNoYXIi
-LCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZhbGlnbiIsIkNP
-TEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5kIiwiQ09NTUFO
-RDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAiLCJDT01NQU5E
-Ojp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3BlbiIsIkRJUjo6
-Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNhYmxlZCIsIkZP
-TlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQiLCJGT1JNOjph
-dXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6bmFtZSIsIkZP
-Uk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjphbGlnbiIsIkgy
-OjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2OjphbGlnbiIsIkhS
-OjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1MOjp2ZXJzaW9u
-IiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6OmhlaWdodCIsIklG
-UkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6d2lkdGgiLCJJ
-TUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0IiwiSU1HOjpoc3Bh
-Y2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZzcGFjZSIsIklN
-Rzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVUOjphbGlnbiIs
-IklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1cyIsIklOUFVU
-OjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklOUFVUOjppc21h
-cCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJTlBVVDo6bWlu
-IiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xkZXIiLCJJTlBV
-VDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVUOjpzdGVwIiwi
-SU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5QVVQ6OnZhbHVl
-IiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5cGUiLCJLRVlH
-RU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6YWNjZXNza2V5
-IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6ZXMiLCJNQVA6
-Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwiTUVURVI6Omhp
-Z2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6dmFsdWUiLCJP
-QkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIsIk9MOjpzdGFy
-dCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVsIiwiT1BUSU9O
-OjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BUSU9OOjp2YWx1
-ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6OndpZHRoIiwiUFJP
-R1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxFQ1Q6OmF1dG9j
-b21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VMRUNUOjpuYW1l
-IiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5kZXgiLCJTT1VS
-Q0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpib3JkZXIiLCJU
-QUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJhbWUiLCJUQUJM
-RTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjphbGlnbiIsIlRC
-T0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFiYnIiLCJURDo6
-YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hhcm9mZiIsIlRE
-Ojpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIsIlREOjpyb3dz
-cGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVBOjphY2Nlc3Nr
-ZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhUQVJFQTo6ZGlz
-YWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhUQVJFQTo6cGxh
-Y2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQiLCJURVhUQVJF
-QTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZPT1Q6OmFsaWdu
-IiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJUSDo6YWJiciIs
-IlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRIOjpjaGFyb2Zm
-IiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93cmFwIiwiVEg6
-OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhFQUQ6OmFsaWdu
-IiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJUUjo6YWxpZ24i
-LCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWduIiwiVFJBQ0s6
-OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNsYW5nIiwiVUw6
-OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIsIlZJREVPOjpoZWlnaHQiLCJWSURF
-Tzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11dGVkIiwiVklERU86OnByZWxvYWQi
-LCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCwwLDY1NDkwLDQ1MDU1LDY1NTM1LDM0
-ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCwwLDI2NjI0LDEwMjMsNjU1MzQsMjA0
-Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQiLCJBUkVBIiwiQkFTRSIsIkJBU0VG
-T05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNFVCIsIkhSIiwi
-SU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFNIiwiU09VUkNF
-IiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMueEQ9SC5WTSh0KFtdKSx1LnMpCkMuZG49SC5W
-TSh0KFtdKSx1LmIpCkMudG89SC5WTSh0KFswLDAsMzI3MjIsMTIyODcsNjU1MzQsMzQ4MTUsNjU1MzQs
-MTg0MzFdKSx1LnQpCkMuRjM9SC5WTSh0KFswLDAsMjQ1NzYsMTAyMyw2NTUzNCwzNDgxNSw2NTUzNCwx
-ODQzMV0pLHUudCkKQy5lYT1ILlZNKHQoWzAsMCwzMjc1NCwxMTI2Myw2NTUzNCwzNDgxNSw2NTUzNCwx
-ODQzMV0pLHUudCkKQy5aSj1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwx
-ODQzMV0pLHUudCkKQy5XZD1ILlZNKHQoWzAsMCw2NTQ5MCwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwx
-ODQzMV0pLHUudCkKQy5ReD1ILlZNKHQoWyJiaW5kIiwiaWYiLCJyZWYiLCJyZXBlYXQiLCJzeW50YXgi
-XSksdS5zKQpDLkJJPUguVk0odChbIkE6OmhyZWYiLCJBUkVBOjpocmVmIiwiQkxPQ0tRVU9URTo6Y2l0
-ZSIsIkJPRFk6OmJhY2tncm91bmQiLCJDT01NQU5EOjppY29uIiwiREVMOjpjaXRlIiwiRk9STTo6YWN0
-aW9uIiwiSU1HOjpzcmMiLCJJTlBVVDo6c3JjIiwiSU5TOjpjaXRlIiwiUTo6Y2l0ZSIsIlZJREVPOjpw
-b3N0ZXIiXSksdS5zKQpDLldPPW5ldyBILkxQKDAse30sQy54RCxILk4wKCJMUDxxVSxxVT4iKSkKQy5o
-VT1ILlZNKHQoW10pLEguTjAoImpkPEdEPiIpKQpDLkNNPW5ldyBILkxQKDAse30sQy5oVSxILk4wKCJM
-UDxHRCxAPiIpKQpDLlRlPW5ldyBILnd2KCJjYWxsIil9KSgpOyhmdW5jdGlvbiBzdGF0aWNGaWVsZHMo
-KXskLnlqPTAKJC5tSj1udWxsCiQuUDQ9bnVsbAokLk5GPW51bGwKJC5UWD1udWxsCiQueDc9bnVsbAok
-Lm53PW51bGwKJC52dj1udWxsCiQuQnY9bnVsbAokLlM2PW51bGwKJC5rOD1udWxsCiQubWc9bnVsbAok
-LlVEPSExCiQuWDM9Qy5OVQokLnhnPVtdCiQueG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQuRVU9
-bnVsbAokLm9yPVAuRmwodS5OLHUuWikKJC5JNj1udWxsCiQuRmY9bnVsbH0pKCk7KGZ1bmN0aW9uIGxh
-enlJbml0aWFsaXplcnMoKXt2YXIgdD1odW5rSGVscGVycy5sYXp5CnQoJCwiZmEiLCJ3IixmdW5jdGlv
-bigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydENsb3N1cmUiKX0pCnQoJCwiWWYiLCJVTiIsZnVuY3Rp
-b24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2pzIil9KQp0KCQsIlUyIiwiU24iLGZ1bmN0aW9uKCl7cmV0
-dXJuIEguY00oSC5TNyh7CnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0p
-CnQoJCwieHEiLCJscSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHskbWV0aG9kJDpudWxsLAp0
-b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiIkcmVjZWl2ZXIkIn19KSl9KQp0KCQsIlIxIiwiTjkiLGZ1
-bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyhudWxsKSl9KQp0KCQsImZOIiwiaUkiLGZ1bmN0aW9uKCl7
-cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5
-e251bGwuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0o
-KSl9KQp0KCQsInFpIiwiS2YiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh2b2lkIDApKX0pCnQo
-JCwicloiLCJaaCIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRz
-RXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7KHZvaWQgMCkuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1j
-YXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsImtxIiwiY1AiLGZ1bmN0aW9uKCl7cmV0
-dXJuIEguY00oSC5NaihudWxsKSl9KQp0KCQsInR0IiwiYzMiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00o
-ZnVuY3Rpb24oKXt0cnl7bnVsbC4kbWV0aG9kJH1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9
-KQp0KCQsImR0IiwiSEsiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5Naih2b2lkIDApKX0pCnQoJCwi
-QTciLCJyMSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXsodm9pZCAwKS4kbWV0
-aG9kJH1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsIldjIiwidXQiLGZ1bmN0aW9u
-KCl7cmV0dXJuIFAuT2ooKX0pCnQoJCwia2giLCJyZiIsZnVuY3Rpb24oKXtyZXR1cm4gUC5XSSgpfSkK
-dCgkLCJidCIsIlY3IixmdW5jdGlvbigpe3JldHVybiBILkRRKEguWEYoSC5WTShbLTIsLTIsLTIsLTIs
-LTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIs
-LTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTEsLTIsLTIsLTIsLTIsLTIsNjIs
-LTIsNjIsLTIsNjMsNTIsNTMsNTQsNTUsNTYsNTcsNTgsNTksNjAsNjEsLTIsLTIsLTIsLTEsLTIsLTIs
-LTIsMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMCwyMSwy
-MiwyMywyNCwyNSwtMiwtMiwtMiwtMiw2MywtMiwyNiwyNywyOCwyOSwzMCwzMSwzMiwzMywzNCwzNSwz
-NiwzNywzOCwzOSw0MCw0MSw0Miw0Myw0NCw0NSw0Niw0Nyw0OCw0OSw1MCw1MSwtMiwtMiwtMiwtMiwt
-Ml0sdS50KSkpfSkKdCgkLCJNNSIsIndRIixmdW5jdGlvbigpe3JldHVybiB0eXBlb2YgcHJvY2VzcyE9
-InVuZGVmaW5lZCImJk9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChwcm9jZXNzKT09IltvYmpl
-Y3QgcHJvY2Vzc10iJiZwcm9jZXNzLnBsYXRmb3JtPT0id2luMzIifSkKdCgkLCJtZiIsIno0IixmdW5j
-dGlvbigpe3JldHVybiBQLm51KCJeW1xcLVxcLjAtOUEtWl9hLXp+XSokIil9KQp0KCQsIkpHIiwidloi
-LGZ1bmN0aW9uKCl7cmV0dXJuIFAudXgoKX0pCnQoJCwiU0MiLCJBTiIsZnVuY3Rpb24oKXtyZXR1cm4g
-UC50TShbIkEiLCJBQkJSIiwiQUNST05ZTSIsIkFERFJFU1MiLCJBUkVBIiwiQVJUSUNMRSIsIkFTSURF
-IiwiQVVESU8iLCJCIiwiQkRJIiwiQkRPIiwiQklHIiwiQkxPQ0tRVU9URSIsIkJSIiwiQlVUVE9OIiwi
-Q0FOVkFTIiwiQ0FQVElPTiIsIkNFTlRFUiIsIkNJVEUiLCJDT0RFIiwiQ09MIiwiQ09MR1JPVVAiLCJD
-T01NQU5EIiwiREFUQSIsIkRBVEFMSVNUIiwiREQiLCJERUwiLCJERVRBSUxTIiwiREZOIiwiRElSIiwi
-RElWIiwiREwiLCJEVCIsIkVNIiwiRklFTERTRVQiLCJGSUdDQVBUSU9OIiwiRklHVVJFIiwiRk9OVCIs
-IkZPT1RFUiIsIkZPUk0iLCJIMSIsIkgyIiwiSDMiLCJINCIsIkg1IiwiSDYiLCJIRUFERVIiLCJIR1JP
-VVAiLCJIUiIsIkkiLCJJRlJBTUUiLCJJTUciLCJJTlBVVCIsIklOUyIsIktCRCIsIkxBQkVMIiwiTEVH
-RU5EIiwiTEkiLCJNQVAiLCJNQVJLIiwiTUVOVSIsIk1FVEVSIiwiTkFWIiwiTk9CUiIsIk9MIiwiT1BU
-R1JPVVAiLCJPUFRJT04iLCJPVVRQVVQiLCJQIiwiUFJFIiwiUFJPR1JFU1MiLCJRIiwiUyIsIlNBTVAi
-LCJTRUNUSU9OIiwiU0VMRUNUIiwiU01BTEwiLCJTT1VSQ0UiLCJTUEFOIiwiU1RSSUtFIiwiU1RST05H
-IiwiU1VCIiwiU1VNTUFSWSIsIlNVUCIsIlRBQkxFIiwiVEJPRFkiLCJURCIsIlRFWFRBUkVBIiwiVEZP
-T1QiLCJUSCIsIlRIRUFEIiwiVElNRSIsIlRSIiwiVFJBQ0siLCJUVCIsIlUiLCJVTCIsIlZBUiIsIlZJ
-REVPIiwiV0JSIl0sdS5OKX0pCnQoJCwiWDQiLCJoRyIsZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXlxc
-UyskIil9KQp0KCQsIndPIiwib3ciLGZ1bmN0aW9uKCl7cmV0dXJuIHUubS5iKFAuTkQoc2VsZikpfSkK
-dCgkLCJrdCIsIlI4IixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkK
-dCgkLCJKZSIsImtJIixmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMu
-bz1hfX0pCnQoJCwicXQiLCJ6QiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFQuR1YoKX0pCnQoJCwiZmUi
-LCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEwuWEEoKX0pCnQoJCwibU0iLCJuVSIsZnVuY3Rpb24o
-KXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0pCnQoJCwieXIiLCJiRCIsZnVuY3Rpb24oKXtyZXR1cm4g
-bmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlteL10kIiksUC5udSgiXi8iKSl9KQp0KCQsIk1rIiwiS2si
-LGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklWKFAubnUoIlsvXFxcXF0iKSxQLm51KCJbXi9cXFxcXSQi
-KSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStcXFxcW15cXFxcL10rfFthLXpBLVpdOlsvXFxcXF0pIiks
-UC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIpKX0pCnQoJCwiYWsiLCJFYiIsZnVuY3Rpb24oKXtyZXR1
-cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUoIiheW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly98W14v
-XSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly9bXi9dKiIpLFAubnUoIl4vIikpfSkK
-dCgkLCJscyIsIkhrIixmdW5jdGlvbigpe3JldHVybiBPLlJoKCl9KX0pKCk7KGZ1bmN0aW9uIG5hdGl2
-ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIgdD1mdW5jdGlvbihhKXt2YXIgbj17fQpuW2FdPTEKcmV0
-dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJzLmNvbnZlcnRUb0Zhc3RPYmplY3QobikpWzBdfQp2Lmdl
-dElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0dXJuIHQoIl9fX2RhcnRfIithK3YuaXNvbGF0ZVRhZyl9
-CnZhciBzPSJfX19kYXJ0X2lzb2xhdGVfdGFnc18iCnZhciByPU9iamVjdFtzXXx8KE9iamVjdFtzXT1P
-YmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcT0iX1p4WXhYIgpmb3IodmFyIHA9MDs7cCsrKXt2YXIgbz10
-KHErIl8iK3ArIl8iKQppZighKG8gaW4gcikpe3Jbb109MQp2Lmlzb2xhdGVUYWc9bwpicmVha319di5k
-aXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElzb2xhdGVUYWcoImRpc3BhdGNoX3JlY29yZCIpfSgpCmh1
-bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcoe0RPTUVycm9yOkoudkIsRE9NSW1w
-bGVtZW50YXRpb246Si52QixNZWRpYUVycm9yOkoudkIsTmF2aWdhdG9yOkoudkIsTmF2aWdhdG9yQ29u
-Y3VycmVudEhhcmR3YXJlOkoudkIsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6Si52QixPdmVyY29uc3Ry
-YWluZWRFcnJvcjpKLnZCLFBvc2l0aW9uRXJyb3I6Si52QixSYW5nZTpKLnZCLFNRTEVycm9yOkoudkIs
-RGF0YVZpZXc6SC5FVCxBcnJheUJ1ZmZlclZpZXc6SC5FVCxGbG9hdDMyQXJyYXk6SC5EZyxGbG9hdDY0
-QXJyYXk6SC5EZyxJbnQxNkFycmF5OkgueGosSW50MzJBcnJheTpILmRFLEludDhBcnJheTpILlpBLFVp
-bnQxNkFycmF5Okgud2YsVWludDMyQXJyYXk6SC5QcSxVaW50OENsYW1wZWRBcnJheTpILmVFLENhbnZh
-c1BpeGVsQXJyYXk6SC5lRSxVaW50OEFycmF5OkguVjYsSFRNTEF1ZGlvRWxlbWVudDpXLnFFLEhUTUxC
-UkVsZW1lbnQ6Vy5xRSxIVE1MQnV0dG9uRWxlbWVudDpXLnFFLEhUTUxDYW52YXNFbGVtZW50OlcucUUs
-SFRNTENvbnRlbnRFbGVtZW50OlcucUUsSFRNTERMaXN0RWxlbWVudDpXLnFFLEhUTUxEYXRhRWxlbWVu
-dDpXLnFFLEhUTUxEYXRhTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGV0YWlsc0VsZW1lbnQ6Vy5xRSxIVE1M
-RGlhbG9nRWxlbWVudDpXLnFFLEhUTUxEaXZFbGVtZW50OlcucUUsSFRNTEVtYmVkRWxlbWVudDpXLnFF
-LEhUTUxGaWVsZFNldEVsZW1lbnQ6Vy5xRSxIVE1MSFJFbGVtZW50OlcucUUsSFRNTEhlYWRFbGVtZW50
-OlcucUUsSFRNTEhlYWRpbmdFbGVtZW50OlcucUUsSFRNTEh0bWxFbGVtZW50OlcucUUsSFRNTElGcmFt
-ZUVsZW1lbnQ6Vy5xRSxIVE1MSW1hZ2VFbGVtZW50OlcucUUsSFRNTElucHV0RWxlbWVudDpXLnFFLEhU
-TUxMSUVsZW1lbnQ6Vy5xRSxIVE1MTGFiZWxFbGVtZW50OlcucUUsSFRNTExlZ2VuZEVsZW1lbnQ6Vy5x
-RSxIVE1MTGlua0VsZW1lbnQ6Vy5xRSxIVE1MTWFwRWxlbWVudDpXLnFFLEhUTUxNZWRpYUVsZW1lbnQ6
-Vy5xRSxIVE1MTWVudUVsZW1lbnQ6Vy5xRSxIVE1MTWV0YUVsZW1lbnQ6Vy5xRSxIVE1MTWV0ZXJFbGVt
-ZW50OlcucUUsSFRNTE1vZEVsZW1lbnQ6Vy5xRSxIVE1MT0xpc3RFbGVtZW50OlcucUUsSFRNTE9iamVj
-dEVsZW1lbnQ6Vy5xRSxIVE1MT3B0R3JvdXBFbGVtZW50OlcucUUsSFRNTE9wdGlvbkVsZW1lbnQ6Vy5x
-RSxIVE1MT3V0cHV0RWxlbWVudDpXLnFFLEhUTUxQYXJhbUVsZW1lbnQ6Vy5xRSxIVE1MUGljdHVyZUVs
-ZW1lbnQ6Vy5xRSxIVE1MUHJlRWxlbWVudDpXLnFFLEhUTUxQcm9ncmVzc0VsZW1lbnQ6Vy5xRSxIVE1M
-UXVvdGVFbGVtZW50OlcucUUsSFRNTFNjcmlwdEVsZW1lbnQ6Vy5xRSxIVE1MU2hhZG93RWxlbWVudDpX
-LnFFLEhUTUxTbG90RWxlbWVudDpXLnFFLEhUTUxTb3VyY2VFbGVtZW50OlcucUUsSFRNTFNwYW5FbGVt
-ZW50OlcucUUsSFRNTFN0eWxlRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OlcucUUs
-SFRNTFRhYmxlQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1M
-VGFibGVIZWFkZXJDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNvbEVsZW1lbnQ6Vy5xRSxIVE1MVGV4
-dEFyZWFFbGVtZW50OlcucUUsSFRNTFRpbWVFbGVtZW50OlcucUUsSFRNTFRpdGxlRWxlbWVudDpXLnFF
-LEhUTUxUcmFja0VsZW1lbnQ6Vy5xRSxIVE1MVUxpc3RFbGVtZW50OlcucUUsSFRNTFVua25vd25FbGVt
-ZW50OlcucUUsSFRNTFZpZGVvRWxlbWVudDpXLnFFLEhUTUxEaXJlY3RvcnlFbGVtZW50OlcucUUsSFRN
-TEZvbnRFbGVtZW50OlcucUUsSFRNTEZyYW1lRWxlbWVudDpXLnFFLEhUTUxGcmFtZVNldEVsZW1lbnQ6
-Vy5xRSxIVE1MTWFycXVlZUVsZW1lbnQ6Vy5xRSxIVE1MRWxlbWVudDpXLnFFLEhUTUxBbmNob3JFbGVt
-ZW50OlcuR2gsSFRNTEFyZWFFbGVtZW50OlcuZlksSFRNTEJhc2VFbGVtZW50OlcubkIsQmxvYjpXLkF6
-LEhUTUxCb2R5RWxlbWVudDpXLlFQLENEQVRBU2VjdGlvbjpXLm54LENoYXJhY3RlckRhdGE6Vy5ueCxD
-b21tZW50OlcubngsUHJvY2Vzc2luZ0luc3RydWN0aW9uOlcubngsVGV4dDpXLm54LENTU1N0eWxlRGVj
-bGFyYXRpb246Vy5vSixNU1N0eWxlQ1NTUHJvcGVydGllczpXLm9KLENTUzJQcm9wZXJ0aWVzOlcub0os
-WE1MRG9jdW1lbnQ6Vy5RRixEb2N1bWVudDpXLlFGLERPTUV4Y2VwdGlvbjpXLk5oLERPTVJlY3RSZWFk
-T25seTpXLklCLERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5jdixBYm9ydFBheW1lbnRFdmVudDpX
-LmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5pbWF0aW9uUGxheWJhY2tFdmVudDpXLmVhLEFwcGxpY2F0
-aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVudDpXLmVhLEJhY2tn
-cm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50OlcuZWEsQmFja2dyb3Vu
-ZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDpXLmVhLEJlZm9yZVVubG9h
-ZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEsQ2FuTWFrZVBheW1lbnRFdmVudDpXLmVhLENsaXBib2Fy
-ZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVhLEN1c3RvbUV2ZW50OlcuZWEsRGV2aWNlTW90aW9uRXZl
-bnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OlcuZWEsRXJyb3JFdmVudDpXLmVhLEV4dGVuZGFi
-bGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6Vy5lYSxGZXRjaEV2ZW50OlcuZWEsRm9u
-dEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3JlaWduRmV0Y2hFdmVudDpXLmVhLEdhbWVwYWRFdmVudDpX
-LmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLEluc3RhbGxFdmVudDpXLmVhLE1lZGlhRW5jcnlwdGVkRXZl
-bnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVudDpXLmVhLE1lZGlhUXVlcnlMaXN0RXZlbnQ6Vy5lYSxN
-ZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFTdHJlYW1UcmFja0V2ZW50OlcuZWEsTWVzc2FnZUV2ZW50
-OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpXLmVhLE1JRElNZXNzYWdlRXZlbnQ6Vy5lYSxNdXRhdGlv
-bkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQYWdlVHJhbnNpdGlvbkV2ZW50OlcuZWEs
-UGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6Vy5lYSxQb3BT
-dGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50OlcuZWEsUHJl
-c2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6Vy5lYSxQcm9taXNlUmVqZWN0aW9uRXZlbnQ6Vy5l
-YSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hhbm5lbEV2ZW50OlcuZWEsUlRDRFRNRlRvbmVDaGFuZ2VF
-dmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6Vy5lYSxSVENUcmFja0V2ZW50OlcuZWEs
-U2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDpXLmVhLFNlbnNvckVycm9yRXZlbnQ6Vy5lYSxTcGVl
-Y2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3BlZWNoUmVjb2duaXRpb25FdmVudDpXLmVhLFNwZWVjaFN5
-bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2ZW50OlcuZWEsU3luY0V2ZW50OlcuZWEsVHJhY2tFdmVu
-dDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVhLFdlYktpdFRyYW5zaXRpb25FdmVudDpXLmVhLFZSRGV2
-aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVudDpXLmVhLFZSU2Vzc2lvbkV2ZW50OlcuZWEsTW9qb0lu
-dGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVTQkNvbm5lY3Rpb25FdmVudDpXLmVhLElEQlZlcnNpb25D
-aGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OlcuZWEsT2ZmbGluZUF1ZGlvQ29tcGxl
-dGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0RXZlbnQ6Vy5lYSxFdmVudDpXLmVhLElucHV0RXZlbnQ6
-Vy5lYSxFdmVudFRhcmdldDpXLkQwLEZpbGU6Vy5UNSxIVE1MRm9ybUVsZW1lbnQ6Vy5oNCxIaXN0b3J5
-OlcuYnIsSFRNTERvY3VtZW50OlcuVmIsWE1MSHR0cFJlcXVlc3Q6Vy5PNyxYTUxIdHRwUmVxdWVzdEV2
-ZW50VGFyZ2V0Olcud2EsSW1hZ2VEYXRhOlcuU2csTG9jYXRpb246Vy51OCxNb3VzZUV2ZW50OlcuQWos
-RHJhZ0V2ZW50OlcuQWosUG9pbnRlckV2ZW50OlcuQWosV2hlZWxFdmVudDpXLkFqLERvY3VtZW50RnJh
-Z21lbnQ6Vy51SCxTaGFkb3dSb290OlcudUgsRG9jdW1lbnRUeXBlOlcudUgsTm9kZTpXLnVILE5vZGVM
-aXN0OlcuQkgsUmFkaW9Ob2RlTGlzdDpXLkJILEhUTUxQYXJhZ3JhcGhFbGVtZW50OlcuU04sUHJvZ3Jl
-c3NFdmVudDpXLmV3LFJlc291cmNlUHJvZ3Jlc3NFdmVudDpXLmV3LEhUTUxTZWxlY3RFbGVtZW50Olcu
-bHAsSFRNTFRhYmxlRWxlbWVudDpXLlRiLEhUTUxUYWJsZVJvd0VsZW1lbnQ6Vy5JdixIVE1MVGFibGVT
-ZWN0aW9uRWxlbWVudDpXLkJULEhUTUxUZW1wbGF0ZUVsZW1lbnQ6Vy55WSxDb21wb3NpdGlvbkV2ZW50
-OlcudzYsRm9jdXNFdmVudDpXLnc2LEtleWJvYXJkRXZlbnQ6Vy53NixUZXh0RXZlbnQ6Vy53NixUb3Vj
-aEV2ZW50OlcudzYsVUlFdmVudDpXLnc2LFdpbmRvdzpXLks1LERPTVdpbmRvdzpXLks1LERlZGljYXRl
-ZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOlcuQ20sU2hhcmVk
-V29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxXb3JrZXJHbG9iYWxTY29wZTpXLkNtLEF0dHI6Vy5DUSxDbGll
-bnRSZWN0OlcudzQsRE9NUmVjdDpXLnc0LE5hbWVkTm9kZU1hcDpXLnJoLE1vek5hbWVkQXR0ck1hcDpX
-LnJoLElEQktleVJhbmdlOlAuaEYsU1ZHU2NyaXB0RWxlbWVudDpQLm5kLFNWR0FFbGVtZW50OlAuZDUs
-U1ZHQW5pbWF0ZUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDpQLmQ1LFNWR0FuaW1h
-dGVUcmFuc2Zvcm1FbGVtZW50OlAuZDUsU1ZHQW5pbWF0aW9uRWxlbWVudDpQLmQ1LFNWR0NpcmNsZUVs
-ZW1lbnQ6UC5kNSxTVkdDbGlwUGF0aEVsZW1lbnQ6UC5kNSxTVkdEZWZzRWxlbWVudDpQLmQ1LFNWR0Rl
-c2NFbGVtZW50OlAuZDUsU1ZHRGlzY2FyZEVsZW1lbnQ6UC5kNSxTVkdFbGxpcHNlRWxlbWVudDpQLmQ1
-LFNWR0ZFQmxlbmRFbGVtZW50OlAuZDUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6UC5kNSxTVkdGRUNv
-bXBvbmVudFRyYW5zZmVyRWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9zaXRlRWxlbWVudDpQLmQ1LFNWR0ZF
-Q29udm9sdmVNYXRyaXhFbGVtZW50OlAuZDUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OlAuZDUs
-U1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OlAuZDUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OlAu
-ZDUsU1ZHRkVGbG9vZEVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNBRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0JF
-bGVtZW50OlAuZDUsU1ZHRkVGdW5jR0VsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNSRWxlbWVudDpQLmQ1LFNW
-R0ZFR2F1c3NpYW5CbHVyRWxlbWVudDpQLmQ1LFNWR0ZFSW1hZ2VFbGVtZW50OlAuZDUsU1ZHRkVNZXJn
-ZUVsZW1lbnQ6UC5kNSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6UC5kNSxTVkdGRU1vcnBob2xvZ3lFbGVt
-ZW50OlAuZDUsU1ZHRkVPZmZzZXRFbGVtZW50OlAuZDUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDpQLmQ1
-LFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6UC5k
-NSxTVkdGRVRpbGVFbGVtZW50OlAuZDUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDpQLmQ1LFNWR0ZpbHRl
-ckVsZW1lbnQ6UC5kNSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDpQLmQ1LFNWR0dFbGVtZW50OlAuZDUs
-U1ZHR2VvbWV0cnlFbGVtZW50OlAuZDUsU1ZHR3JhcGhpY3NFbGVtZW50OlAuZDUsU1ZHSW1hZ2VFbGVt
-ZW50OlAuZDUsU1ZHTGluZUVsZW1lbnQ6UC5kNSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6UC5kNSxT
-VkdNYXJrZXJFbGVtZW50OlAuZDUsU1ZHTWFza0VsZW1lbnQ6UC5kNSxTVkdNZXRhZGF0YUVsZW1lbnQ6
-UC5kNSxTVkdQYXRoRWxlbWVudDpQLmQ1LFNWR1BhdHRlcm5FbGVtZW50OlAuZDUsU1ZHUG9seWdvbkVs
-ZW1lbnQ6UC5kNSxTVkdQb2x5bGluZUVsZW1lbnQ6UC5kNSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6
-UC5kNSxTVkdSZWN0RWxlbWVudDpQLmQ1LFNWR1NldEVsZW1lbnQ6UC5kNSxTVkdTdG9wRWxlbWVudDpQ
-LmQ1LFNWR1N0eWxlRWxlbWVudDpQLmQ1LFNWR1NWR0VsZW1lbnQ6UC5kNSxTVkdTd2l0Y2hFbGVtZW50
-OlAuZDUsU1ZHU3ltYm9sRWxlbWVudDpQLmQ1LFNWR1RTcGFuRWxlbWVudDpQLmQ1LFNWR1RleHRDb250
-ZW50RWxlbWVudDpQLmQ1LFNWR1RleHRFbGVtZW50OlAuZDUsU1ZHVGV4dFBhdGhFbGVtZW50OlAuZDUs
-U1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDpQLmQ1LFNWR1RpdGxlRWxlbWVudDpQLmQ1LFNWR1VzZUVs
-ZW1lbnQ6UC5kNSxTVkdWaWV3RWxlbWVudDpQLmQ1LFNWR0dyYWRpZW50RWxlbWVudDpQLmQ1LFNWR0Nv
-bXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OlAuZDUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDpQ
-LmQ1LFNWR01QYXRoRWxlbWVudDpQLmQ1LFNWR0VsZW1lbnQ6UC5kNX0pCmh1bmtIZWxwZXJzLnNldE9y
-VXBkYXRlTGVhZlRhZ3Moe0RPTUVycm9yOnRydWUsRE9NSW1wbGVtZW50YXRpb246dHJ1ZSxNZWRpYUVy
-cm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQ29uY3VycmVudEhhcmR3YXJlOnRydWUsTmF2
-aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29uc3RyYWluZWRFcnJvcjp0cnVlLFBvc2l0aW9u
-RXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRydWUsRGF0YVZpZXc6dHJ1ZSxBcnJheUJ1ZmZl
-clZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxvYXQ2NEFycmF5OnRydWUsSW50MTZBcnJheTp0
-cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1ZSxVaW50MTZBcnJheTp0cnVlLFVpbnQzMkFy
-cmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxDYW52YXNQaXhlbEFycmF5OnRydWUsVWludDhB
-cnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUsSFRNTEJSRWxlbWVudDp0cnVlLEhUTUxCdXR0
-b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6dHJ1ZSxIVE1MQ29udGVudEVsZW1lbnQ6dHJ1
-ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFFbGVtZW50OnRydWUsSFRNTERhdGFMaXN0RWxl
-bWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFsb2dFbGVtZW50OnRydWUsSFRN
-TERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRNTEZpZWxkU2V0RWxlbWVudDp0
-cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZGluZ0VsZW1l
-bnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVudDp0cnVlLEhUTUxJbWFn
-ZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRydWUsSFRNTExJRWxlbWVudDp0cnVlLEhUTUxM
-YWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVudDp0cnVlLEhUTUxMaW5rRWxlbWVudDp0cnVl
-LEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxlbWVudDp0cnVlLEhUTUxNZW51RWxlbWVudDp0
-cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRlckVsZW1lbnQ6dHJ1ZSxIVE1MTW9kRWxlbWVu
-dDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVudDp0cnVlLEhUTUxPcHRH
-cm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVudDp0cnVlLEhUTUxPdXRwdXRFbGVtZW50OnRy
-dWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0dXJlRWxlbWVudDp0cnVlLEhUTUxQcmVFbGVt
-ZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVlLEhUTUxRdW90ZUVsZW1lbnQ6dHJ1ZSxIVE1M
-U2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVtZW50OnRydWUsSFRNTFNsb3RFbGVtZW50OnRy
-dWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5bGVFbGVt
-ZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDZWxsRWxlbWVudDp0
-cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50
-OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhUTUxUZXh0QXJlYUVsZW1lbnQ6dHJ1ZSxIVE1M
-VGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50OnRydWUsSFRNTFRyYWNrRWxlbWVudDp0cnVl
-LEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlkZW9FbGVt
-ZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1ZSxIVE1M
-RnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxlbWVudDp0cnVlLEhUTUxNYXJxdWVlRWxlbWVu
-dDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNob3JFbGVtZW50OnRydWUsSFRNTEFyZWFFbGVt
-ZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxvYjpmYWxzZSxIVE1MQm9keUVsZW1lbnQ6dHJ1
-ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRhOnRydWUsQ29tbWVudDp0cnVlLFByb2Nlc3Np
-bmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NTdHlsZURlY2xhcmF0aW9uOnRydWUsTVNTdHls
-ZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGllczp0cnVlLFhNTERvY3VtZW50OnRydWUsRG9j
-dW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9NUmVjdFJlYWRPbmx5OmZhbHNlLERPTVRva2Vu
-TGlzdDp0cnVlLEVsZW1lbnQ6ZmFsc2UsQWJvcnRQYXltZW50RXZlbnQ6dHJ1ZSxBbmltYXRpb25FdmVu
-dDp0cnVlLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6dHJ1ZSxBcHBsaWNhdGlvbkNhY2hlRXJyb3JFdmVu
-dDp0cnVlLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hFdmVudDp0
-cnVlLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaGVkRXZlbnQ6dHJ1
-ZSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6dHJ1ZSxCZWZvcmVVbmxvYWRFdmVudDp0cnVlLEJsb2JF
-dmVudDp0cnVlLENhbk1ha2VQYXltZW50RXZlbnQ6dHJ1ZSxDbGlwYm9hcmRFdmVudDp0cnVlLENsb3Nl
-RXZlbnQ6dHJ1ZSxDdXN0b21FdmVudDp0cnVlLERldmljZU1vdGlvbkV2ZW50OnRydWUsRGV2aWNlT3Jp
-ZW50YXRpb25FdmVudDp0cnVlLEVycm9yRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlRXZlbnQ6dHJ1ZSxFeHRl
-bmRhYmxlTWVzc2FnZUV2ZW50OnRydWUsRmV0Y2hFdmVudDp0cnVlLEZvbnRGYWNlU2V0TG9hZEV2ZW50
-OnRydWUsRm9yZWlnbkZldGNoRXZlbnQ6dHJ1ZSxHYW1lcGFkRXZlbnQ6dHJ1ZSxIYXNoQ2hhbmdlRXZl
-bnQ6dHJ1ZSxJbnN0YWxsRXZlbnQ6dHJ1ZSxNZWRpYUVuY3J5cHRlZEV2ZW50OnRydWUsTWVkaWFLZXlN
-ZXNzYWdlRXZlbnQ6dHJ1ZSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OnRydWUsTWVkaWFTdHJlYW1FdmVudDp0
-cnVlLE1lZGlhU3RyZWFtVHJhY2tFdmVudDp0cnVlLE1lc3NhZ2VFdmVudDp0cnVlLE1JRElDb25uZWN0
-aW9uRXZlbnQ6dHJ1ZSxNSURJTWVzc2FnZUV2ZW50OnRydWUsTXV0YXRpb25FdmVudDp0cnVlLE5vdGlm
-aWNhdGlvbkV2ZW50OnRydWUsUGFnZVRyYW5zaXRpb25FdmVudDp0cnVlLFBheW1lbnRSZXF1ZXN0RXZl
-bnQ6dHJ1ZSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OnRydWUsUG9wU3RhdGVFdmVudDp0cnVlLFBy
-ZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDp0cnVlLFByZXNlbnRhdGlvbkNvbm5lY3Rp
-b25DbG9zZUV2ZW50OnRydWUsUHJvbWlzZVJlamVjdGlvbkV2ZW50OnRydWUsUHVzaEV2ZW50OnRydWUs
-UlRDRGF0YUNoYW5uZWxFdmVudDp0cnVlLFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6dHJ1ZSxSVENQZWVy
-Q29ubmVjdGlvbkljZUV2ZW50OnRydWUsUlRDVHJhY2tFdmVudDp0cnVlLFNlY3VyaXR5UG9saWN5Vmlv
-bGF0aW9uRXZlbnQ6dHJ1ZSxTZW5zb3JFcnJvckV2ZW50OnRydWUsU3BlZWNoUmVjb2duaXRpb25FcnJv
-cjp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6dHJ1ZSxTcGVlY2hTeW50aGVzaXNFdmVudDp0cnVl
-LFN0b3JhZ2VFdmVudDp0cnVlLFN5bmNFdmVudDp0cnVlLFRyYWNrRXZlbnQ6dHJ1ZSxUcmFuc2l0aW9u
-RXZlbnQ6dHJ1ZSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxWUkRldmljZUV2ZW50OnRydWUsVlJE
-aXNwbGF5RXZlbnQ6dHJ1ZSxWUlNlc3Npb25FdmVudDp0cnVlLE1vam9JbnRlcmZhY2VSZXF1ZXN0RXZl
-bnQ6dHJ1ZSxVU0JDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6dHJ1ZSxB
-dWRpb1Byb2Nlc3NpbmdFdmVudDp0cnVlLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDp0cnVlLFdl
-YkdMQ29udGV4dEV2ZW50OnRydWUsRXZlbnQ6ZmFsc2UsSW5wdXRFdmVudDpmYWxzZSxFdmVudFRhcmdl
-dDpmYWxzZSxGaWxlOnRydWUsSFRNTEZvcm1FbGVtZW50OnRydWUsSGlzdG9yeTp0cnVlLEhUTUxEb2N1
-bWVudDp0cnVlLFhNTEh0dHBSZXF1ZXN0OnRydWUsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpmYWxz
-ZSxJbWFnZURhdGE6dHJ1ZSxMb2NhdGlvbjp0cnVlLE1vdXNlRXZlbnQ6dHJ1ZSxEcmFnRXZlbnQ6dHJ1
-ZSxQb2ludGVyRXZlbnQ6dHJ1ZSxXaGVlbEV2ZW50OnRydWUsRG9jdW1lbnRGcmFnbWVudDp0cnVlLFNo
-YWRvd1Jvb3Q6dHJ1ZSxEb2N1bWVudFR5cGU6dHJ1ZSxOb2RlOmZhbHNlLE5vZGVMaXN0OnRydWUsUmFk
-aW9Ob2RlTGlzdDp0cnVlLEhUTUxQYXJhZ3JhcGhFbGVtZW50OnRydWUsUHJvZ3Jlc3NFdmVudDp0cnVl
-LFJlc291cmNlUHJvZ3Jlc3NFdmVudDp0cnVlLEhUTUxTZWxlY3RFbGVtZW50OnRydWUsSFRNTFRhYmxl
-RWxlbWVudDp0cnVlLEhUTUxUYWJsZVJvd0VsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVTZWN0aW9uRWxlbWVu
-dDp0cnVlLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6dHJ1ZSxDb21wb3NpdGlvbkV2ZW50OnRydWUsRm9jdXNF
-dmVudDp0cnVlLEtleWJvYXJkRXZlbnQ6dHJ1ZSxUZXh0RXZlbnQ6dHJ1ZSxUb3VjaEV2ZW50OnRydWUs
-VUlFdmVudDpmYWxzZSxXaW5kb3c6dHJ1ZSxET01XaW5kb3c6dHJ1ZSxEZWRpY2F0ZWRXb3JrZXJHbG9i
-YWxTY29wZTp0cnVlLFNlcnZpY2VXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFNoYXJlZFdvcmtlckdsb2Jh
-bFNjb3BlOnRydWUsV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxBdHRyOnRydWUsQ2xpZW50UmVjdDp0cnVl
-LERPTVJlY3Q6dHJ1ZSxOYW1lZE5vZGVNYXA6dHJ1ZSxNb3pOYW1lZEF0dHJNYXA6dHJ1ZSxJREJLZXlS
-YW5nZTp0cnVlLFNWR1NjcmlwdEVsZW1lbnQ6dHJ1ZSxTVkdBRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVF
-bGVtZW50OnRydWUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlVHJhbnNmb3Jt
-RWxlbWVudDp0cnVlLFNWR0FuaW1hdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdDaXJjbGVFbGVtZW50OnRydWUs
-U1ZHQ2xpcFBhdGhFbGVtZW50OnRydWUsU1ZHRGVmc0VsZW1lbnQ6dHJ1ZSxTVkdEZXNjRWxlbWVudDp0
-cnVlLFNWR0Rpc2NhcmRFbGVtZW50OnRydWUsU1ZHRWxsaXBzZUVsZW1lbnQ6dHJ1ZSxTVkdGRUJsZW5k
-RWxlbWVudDp0cnVlLFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVDb21wb25lbnRUcmFu
-c2ZlckVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvc2l0ZUVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbnZvbHZlTWF0
-cml4RWxlbWVudDp0cnVlLFNWR0ZFRGlmZnVzZUxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFRGlzcGxh
-Y2VtZW50TWFwRWxlbWVudDp0cnVlLFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFRmxv
-b2RFbGVtZW50OnRydWUsU1ZHRkVGdW5jQUVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNCRWxlbWVudDp0cnVl
-LFNWR0ZFRnVuY0dFbGVtZW50OnRydWUsU1ZHRkVGdW5jUkVsZW1lbnQ6dHJ1ZSxTVkdGRUdhdXNzaWFu
-Qmx1ckVsZW1lbnQ6dHJ1ZSxTVkdGRUltYWdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VFbGVtZW50OnRy
-dWUsU1ZHRkVNZXJnZU5vZGVFbGVtZW50OnRydWUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDp0cnVlLFNW
-R0ZFT2Zmc2V0RWxlbWVudDp0cnVlLFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVNwZWN1
-bGFyTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVUaWxl
-RWxlbWVudDp0cnVlLFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6dHJ1ZSxTVkdGaWx0ZXJFbGVtZW50OnRy
-dWUsU1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6dHJ1ZSxTVkdHRWxlbWVudDp0cnVlLFNWR0dlb21ldHJ5
-RWxlbWVudDp0cnVlLFNWR0dyYXBoaWNzRWxlbWVudDp0cnVlLFNWR0ltYWdlRWxlbWVudDp0cnVlLFNW
-R0xpbmVFbGVtZW50OnRydWUsU1ZHTGluZWFyR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHTWFya2VyRWxl
-bWVudDp0cnVlLFNWR01hc2tFbGVtZW50OnRydWUsU1ZHTWV0YWRhdGFFbGVtZW50OnRydWUsU1ZHUGF0
-aEVsZW1lbnQ6dHJ1ZSxTVkdQYXR0ZXJuRWxlbWVudDp0cnVlLFNWR1BvbHlnb25FbGVtZW50OnRydWUs
-U1ZHUG9seWxpbmVFbGVtZW50OnRydWUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHUmVj
-dEVsZW1lbnQ6dHJ1ZSxTVkdTZXRFbGVtZW50OnRydWUsU1ZHU3RvcEVsZW1lbnQ6dHJ1ZSxTVkdTdHls
-ZUVsZW1lbnQ6dHJ1ZSxTVkdTVkdFbGVtZW50OnRydWUsU1ZHU3dpdGNoRWxlbWVudDp0cnVlLFNWR1N5
-bWJvbEVsZW1lbnQ6dHJ1ZSxTVkdUU3BhbkVsZW1lbnQ6dHJ1ZSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6
-dHJ1ZSxTVkdUZXh0RWxlbWVudDp0cnVlLFNWR1RleHRQYXRoRWxlbWVudDp0cnVlLFNWR1RleHRQb3Np
-dGlvbmluZ0VsZW1lbnQ6dHJ1ZSxTVkdUaXRsZUVsZW1lbnQ6dHJ1ZSxTVkdVc2VFbGVtZW50OnRydWUs
-U1ZHVmlld0VsZW1lbnQ6dHJ1ZSxTVkdHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdDb21wb25lbnRUcmFu
-c2ZlckZ1bmN0aW9uRWxlbWVudDp0cnVlLFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6dHJ1ZSxTVkdNUGF0
-aEVsZW1lbnQ6dHJ1ZSxTVkdFbGVtZW50OmZhbHNlfSkKSC5iMC4kbmF0aXZlU3VwZXJjbGFzc1RhZz0i
-QXJyYXlCdWZmZXJWaWV3IgpILlJHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXci
-CkguVlAuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5EZy4kbmF0aXZlU3Vw
-ZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILldCLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJh
-eUJ1ZmZlclZpZXciCkguWkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5Q
-Zy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3In0pKCkKY29udmVydEFsbFRvRmFz
-dE9iamVjdCh3KQpjb252ZXJ0VG9GYXN0T2JqZWN0KCQpOyhmdW5jdGlvbihhKXtpZih0eXBlb2YgZG9j
-dW1lbnQ9PT0idW5kZWZpbmVkIil7YShudWxsKQpyZXR1cm59aWYodHlwZW9mIGRvY3VtZW50LmN1cnJl
-bnRTY3JpcHQhPSd1bmRlZmluZWQnKXthKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQpCnJldHVybn12YXIg
-dD1kb2N1bWVudC5zY3JpcHRzCmZ1bmN0aW9uIG9uTG9hZChiKXtmb3IodmFyIHI9MDtyPHQubGVuZ3Ro
-Oysrcil0W3JdLnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSkKYShiLnRhcmdl
-dCl9Zm9yKHZhciBzPTA7czx0Lmxlbmd0aDsrK3MpdFtzXS5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixv
-bkxvYWQsZmFsc2UpfSkoZnVuY3Rpb24oYSl7di5jdXJyZW50U2NyaXB0PWEKaWYodHlwZW9mIGRhcnRN
-YWluUnVubmVyPT09ImZ1bmN0aW9uIilkYXJ0TWFpblJ1bm5lcihMLklxLFtdKQplbHNlIEwuSXEoW10p
-fSl9KSgpCi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pZ3JhdGlvbi5qcy5tYXAK
+LGIpe3ZhciB0LHMscj1hLmNsYXNzTGlzdApmb3IodD1iLmxlbmd0aCxzPTA7czxiLmxlbmd0aDtiLmxl
+bmd0aD09PXR8fCgwLEgubGspKGIpLCsrcylyLmFkZChiW3NdKX0sCkpFOmZ1bmN0aW9uKGEsYixjLGQs
+ZSl7dmFyIHQ9Vy5hRihuZXcgVy52TihjKSx1LkIpCmlmKHQhPW51bGwmJiEwKUouZFooYSxiLHQsITEp
+CnJldHVybiBuZXcgVy54QyhhLGIsdCwhMSxlLkMoInhDPDA+IikpfSwKVHc6ZnVuY3Rpb24oYSl7dmFy
+IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpLHM9bmV3IFcubWsodCx3aW5kb3cubG9jYXRpb24p
+CnM9bmV3IFcuSlEocykKcy5DWShhKQpyZXR1cm4gc30sCnlXOmZ1bmN0aW9uKGEsYixjLGQpe3UuaC5i
+KGEpCkgueShiKQpILnkoYykKdS5PLmIoZCkKcmV0dXJuITB9LApRVzpmdW5jdGlvbihhLGIsYyxkKXt2
+YXIgdCxzLHIKdS5oLmIoYSkKSC55KGIpCkgueShjKQp0PXUuTy5iKGQpLmEKcz10LmEKcy5ocmVmPWMK
+cj1zLmhvc3RuYW1lCnQ9dC5iCmlmKCEocj09dC5ob3N0bmFtZSYmcy5wb3J0PT10LnBvcnQmJnMucHJv
+dG9jb2w9PXQucHJvdG9jb2wpKWlmKHI9PT0iIilpZihzLnBvcnQ9PT0iIil7dD1zLnByb3RvY29sCnQ9
+dD09PSI6Inx8dD09PSIifWVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSEwCnJldHVybiB0fSwKQmw6
+ZnVuY3Rpb24oKXt2YXIgdD11Lk4scz1QLnRNKEMuUXgsdCkscj11LmRHLmIobmV3IFcuSUEoKSkscT1I
+LlZNKFsiVEVNUExBVEUiXSx1LnMpCnQ9bmV3IFcuY3QocyxQLkxzKHQpLFAuTHModCksUC5Mcyh0KSxu
+dWxsKQp0LkNZKG51bGwsbmV3IEguQTgoQy5ReCxyLHUuZHYpLHEsbnVsbCkKcmV0dXJuIHR9LApxYzpm
+dW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKXJldHVybgppZigicG9zdE1lc3NhZ2UiIGluIGEpe3Q9
+Vy5QMShhKQpyZXR1cm4gdH1lbHNlIHJldHVybiB1LmFTLmIoYSl9LApQMTpmdW5jdGlvbihhKXtpZihh
+PT09d2luZG93KXJldHVybiB1LmNpLmIoYSkKZWxzZSByZXR1cm4gbmV3IFcuZFcoKX0sCmFGOmZ1bmN0
+aW9uKGEsYil7dmFyIHQ9JC5YMwppZih0PT09Qy5OVSlyZXR1cm4gYQpyZXR1cm4gdC5QeShhLGIpfSwK
+cUU6ZnVuY3Rpb24gcUUoKXt9LApHaDpmdW5jdGlvbiBHaCgpe30sCmZZOmZ1bmN0aW9uIGZZKCl7fSwK
+bkI6ZnVuY3Rpb24gbkIoKXt9LApBejpmdW5jdGlvbiBBeigpe30sClFQOmZ1bmN0aW9uIFFQKCl7fSwK
+bng6ZnVuY3Rpb24gbngoKXt9LApvSjpmdW5jdGlvbiBvSigpe30sCmlkOmZ1bmN0aW9uIGlkKCl7fSwK
+UUY6ZnVuY3Rpb24gUUYoKXt9LApOaDpmdW5jdGlvbiBOaCgpe30sCklCOmZ1bmN0aW9uIElCKCl7fSwK
+bjc6ZnVuY3Rpb24gbjcoKXt9LAp3ejpmdW5jdGlvbiB3eihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9
+LApjdjpmdW5jdGlvbiBjdigpe30sCkN2OmZ1bmN0aW9uIEN2KCl7fSwKZWE6ZnVuY3Rpb24gZWEoKXt9
+LApEMDpmdW5jdGlvbiBEMCgpe30sClQ1OmZ1bmN0aW9uIFQ1KCl7fSwKaDQ6ZnVuY3Rpb24gaDQoKXt9
+LApicjpmdW5jdGlvbiBicigpe30sClZiOmZ1bmN0aW9uIFZiKCl7fSwKTzc6ZnVuY3Rpb24gTzcoKXt9
+LApiVTpmdW5jdGlvbiBiVShhKXt0aGlzLmE9YX0sCmhIOmZ1bmN0aW9uIGhIKGEsYil7dGhpcy5hPWEK
+dGhpcy5iPWJ9LAp3YTpmdW5jdGlvbiB3YSgpe30sClNnOmZ1bmN0aW9uIFNnKCl7fSwKdTg6ZnVuY3Rp
+b24gdTgoKXt9LApBajpmdW5jdGlvbiBBaigpe30sCmU3OmZ1bmN0aW9uIGU3KGEpe3RoaXMuYT1hfSwK
+dUg6ZnVuY3Rpb24gdUgoKXt9LApCSDpmdW5jdGlvbiBCSCgpe30sClNOOmZ1bmN0aW9uIFNOKCl7fSwK
+ZXc6ZnVuY3Rpb24gZXcoKXt9LApscDpmdW5jdGlvbiBscCgpe30sClRiOmZ1bmN0aW9uIFRiKCl7fSwK
+SXY6ZnVuY3Rpb24gSXYoKXt9LApCVDpmdW5jdGlvbiBCVCgpe30sCnlZOmZ1bmN0aW9uIHlZKCl7fSwK
+dzY6ZnVuY3Rpb24gdzYoKXt9LApLNTpmdW5jdGlvbiBLNSgpe30sCkNtOmZ1bmN0aW9uIENtKCl7fSwK
+Q1E6ZnVuY3Rpb24gQ1EoKXt9LAp3NDpmdW5jdGlvbiB3NCgpe30sCnJoOmZ1bmN0aW9uIHJoKCl7fSwK
+RDk6ZnVuY3Rpb24gRDkoKXt9LAppNzpmdW5jdGlvbiBpNyhhKXt0aGlzLmE9YX0sClN5OmZ1bmN0aW9u
+IFN5KGEpe3RoaXMuYT1hfSwKS1M6ZnVuY3Rpb24gS1MoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkEz
+OmZ1bmN0aW9uIEEzKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJNDpmdW5jdGlvbiBJNChhKXt0aGlz
+LmE9YX0sCkZrOmZ1bmN0aW9uIEZrKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sClJPOmZ1bmN0aW9u
+IFJPKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy4kdGk9ZH0sCkNxOmZ1bmN0
+aW9uIENxKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy4kdGk9ZH0sCnhDOmZ1
+bmN0aW9uIHhDKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmI9YQpfLmM9YgpfLmQ9YwpfLmU9ZApfLiR0
+aT1lfSwKdk46ZnVuY3Rpb24gdk4oYSl7dGhpcy5hPWF9LApKUTpmdW5jdGlvbiBKUShhKXt0aGlzLmE9
+YX0sCkdtOmZ1bmN0aW9uIEdtKCl7fSwKdkQ6ZnVuY3Rpb24gdkQoYSl7dGhpcy5hPWF9LApVdjpmdW5j
+dGlvbiBVdihhKXt0aGlzLmE9YX0sCkVnOmZ1bmN0aW9uIEVnKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9
+Ygp0aGlzLmM9Y30sCm02OmZ1bmN0aW9uIG02KCl7fSwKRW86ZnVuY3Rpb24gRW8oKXt9LApXazpmdW5j
+dGlvbiBXaygpe30sCmN0OmZ1bmN0aW9uIGN0KGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmU9YQpfLmE9
+YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCklBOmZ1bmN0aW9uIElBKCl7fSwKT3c6ZnVuY3Rpb24gT3coKXt9
+LApXOTpmdW5jdGlvbiBXOShhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9LTEKXy5kPW51
+bGwKXy4kdGk9Y30sCmRXOmZ1bmN0aW9uIGRXKCl7fSwKa0Y6ZnVuY3Rpb24ga0YoKXt9LAptazpmdW5j
+dGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhpcy5hPWF9
+LApmbTpmdW5jdGlvbiBmbShhKXt0aGlzLmE9YX0sCkxlOmZ1bmN0aW9uIExlKCl7fSwKSzc6ZnVuY3Rp
+b24gSzcoKXt9LApyQjpmdW5jdGlvbiByQigpe30sClhXOmZ1bmN0aW9uIFhXKCl7fSwKb2E6ZnVuY3Rp
+b24gb2EoKXt9fSxVPXsKeXU6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49SC5WTShbXSx1LmJQ
+KQpmb3IodD1KLlU2KGEpLHM9Si5JVCh1LlIuYih0LnEoYSwiZGV0YWlscyIpKSk7cy5GKCk7KXtyPXMu
+Z2woKQpxPUouVTYocikKcD1ILnkocS5xKHIsImRlc2NyaXB0aW9uIikpCnE9cS5xKHIsImxpbmsiKQpp
+ZihxPT1udWxsKXE9bnVsbAplbHNle289Si5VNihxKQpxPW5ldyBVLk1sKEgueShvLnEocSwiaHJlZiIp
+KSxILlNjKG8ucShxLCJsaW5lIikpLEgueShvLnEocSwicGF0aCIpKSl9Qy5ObS5pKG4sbmV3IFUudUYo
+cCxxKSl9cmV0dXJuIG5ldyBVLmQyKG4sVS5qZih0LnEoYSwiZWRpdHMiKSksSC55KHQucShhLCJleHBs
+YW5hdGlvbiIpKSxILlNjKHQucShhLCJsaW5lIikpLEgueSh0LnEoYSwicGF0aCIpKSxVLk5kKHQucShh
+LCJ0cmFjZXMiKSkpfSwKamY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEKaWYoYT09bnVsbCl0PW51bGwK
+ZWxzZXt0PUguVk0oW10sdS5mQSkKZm9yKHM9Si5JVCh1LlIuYihhKSk7cy5GKCk7KXtyPXMuZ2woKQpx
+PUouVTYocikKQy5ObS5pKHQsbmV3IFUuU2UoSC55KHEucShyLCJkZXNjcmlwdGlvbiIpKSxILnkocS5x
+KHIsImhyZWYiKSkpKX19cmV0dXJuIHR9LApOZDpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKGE9PW51bGwp
+dD1udWxsCmVsc2V7dD1ILlZNKFtdLHUuaGgpCmZvcihzPUouSVQodS5SLmIoYSkpO3MuRigpOylDLk5t
+LmkodCxVLk5mKHMuZ2woKSkpfXJldHVybiB0fSwKTmY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxv
+PSJkZXNjcmlwdGlvbiIsbj1KLlU2KGEpLG09SC55KG4ucShhLG8pKSxsPUguVk0oW10sdS5hSikKZm9y
+KG49Si5JVCh1LlIuYihuLnEoYSwiZW50cmllcyIpKSk7bi5GKCk7KXt0PW4uZ2woKQpzPUouVTYodCkK
+cj1ILnkocy5xKHQsbykpCnE9SC55KHMucSh0LCJmdW5jdGlvbiIpKQpzPXMucSh0LCJsaW5rIikKaWYo
+cz09bnVsbClzPW51bGwKZWxzZXtwPUouVTYocykKcz1uZXcgVS5NbChILnkocC5xKHMsImhyZWYiKSks
+SC5TYyhwLnEocywibGluZSIpKSxILnkocC5xKHMsInBhdGgiKSkpfUMuTm0uaShsLG5ldyBVLndiKHIs
+cSxzKSl9cmV0dXJuIG5ldyBVLnlEKG0sbCl9LApkMjpmdW5jdGlvbiBkMihhLGIsYyxkLGUsZil7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9Zn0sClNlOmZ1bmN0aW9uIFNl
+KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1RjpmdW5jdGlvbiB1RihhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKTWw6ZnVuY3Rpb24gTWwoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKeUQ6
+ZnVuY3Rpb24geUQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCndiOmZ1bmN0aW9uIHdiKGEsYixjKXt0
+aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y319LFQ9e0dWOmZ1bmN0aW9uIEdWKCl7fX0sTD17CklxOmZ1
+bmN0aW9uKCl7Qy5CWi5CKGRvY3VtZW50LCJET01Db250ZW50TG9hZGVkIixuZXcgTC5lKCkpCkMub2wu
+Qih3aW5kb3csInBvcHN0YXRlIixuZXcgTC5MKCkpfSwKa3o6ZnVuY3Rpb24oYSl7dmFyIHQscz11Lmgu
+YShhLnBhcmVudE5vZGUpLnF1ZXJ5U2VsZWN0b3IoIjpzY29wZSA+IHVsIikscj1zLnN0eWxlLHE9IiIr
+Qy5DRC56UShzLm9mZnNldEhlaWdodCkqMisicHgiCnIubWF4SGVpZ2h0PXEKcj1KLnFGKGEpCnE9ci4k
+dGkKdD1xLkMoIn4oMSkiKS5iKG5ldyBMLld4KHMsYSkpCnUuTS5iKG51bGwpClcuSkUoci5hLHIuYix0
+LCExLHEuZCl9LAp5WDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG89InF1ZXJ5U2VsZWN0b3JBbGwi
+LG49ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihhKSxtPXUuaApuLnRvU3RyaW5nCkguRGgobSxtLCJUIixv
+KQp0PXUuUwpzPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1saW5rIiksdCkKcy5LKHMs
+bmV3IEwuQU8oKSkKSC5EaChtLG0sIlQiLG8pCnI9bmV3IFcud3oobi5xdWVyeVNlbGVjdG9yQWxsKCIu
+cmVnaW9uIiksdCkKaWYoci5nQShyKSE9PTApe3E9bi5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBh
+dGhdIikKcS50b1N0cmluZwpyLksocixuZXcgTC5IbyhxLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBX
+LlN5KG5ldyBXLmk3KHEpKS5PKCJwYXRoIikpKSl9SC5EaChtLG0sIlQiLG8pCnA9bmV3IFcud3oobi5x
+dWVyeVNlbGVjdG9yQWxsKCIucG9zdC1saW5rIiksdCkKcC5LKHAsbmV3IEwuSUMoKSl9LAp0eTpmdW5j
+dGlvbihhKXt2YXIgdD11Lk4KcmV0dXJuIFcucUQoYSwiUE9TVCIsUC5FRihbIkNvbnRlbnQtVHlwZSIs
+ImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiXSx0LHQpKS5XNyhuZXcgTC5MMSgpLHUucil9
+LAphSzpmdW5jdGlvbihhKXt2YXIgdD1QLmhLKGEpLmdoWSgpLnEoMCwibGluZSIpCnJldHVybiB0PT1u
+dWxsP251bGw6SC5IcCh0LG51bGwpfSwKRzY6ZnVuY3Rpb24oYSl7dmFyIHQ9UC5oSyhhKS5naFkoKS5x
+KDAsIm9mZnNldCIpCnJldHVybiB0PT1udWxsP251bGw6SC5IcCh0LG51bGwpfSwKdDI6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzLHIscSxwLG8sbj17fQp1LlYuYihhKQp0PW4uYT11LmguYihXLnFjKGEuY3VycmVu
+dFRhcmdldCkpLmdldEF0dHJpYnV0ZSgiaHJlZiIpCmlmKEouemwodCwiPyIpKXtzPUMueEIuTmoodCww
+LEMueEIuT1kodCwiPyIpKQpuLmE9cwpyPXN9ZWxzZSByPXQKaWYoYiE9bnVsbCl7cT0kLm5VKCkKcj1u
+LmE9cS5vNShELm5yKHEudE0oYikscikpfXA9TC5HNih0KQpvPUwuYUsodCkKaWYocCE9bnVsbClMLmFm
+KHIscCxvLG5ldyBMLm5UKG4scCxvKSkKZWxzZSBMLmFmKHIsbnVsbCxudWxsLG5ldyBMLkJaKG4pKQph
+LnByZXZlbnREZWZhdWx0KCl9LAp1bTpmdW5jdGlvbihhKXt2YXIgdAp1LlYuYihhKQp0PXUuaC5hKFcu
+cWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKTC50eSh0KS5PQShuZXcgTC5G
+USh0KSkKYS5wcmV2ZW50RGVmYXVsdCgpfSwKdlU6ZnVuY3Rpb24oKXt2YXIgdD1kb2N1bWVudCxzPXUu
+aApILkRoKHMscywiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQp0PW5ldyBXLnd6KHQucXVlcnlTZWxlY3Rv
+ckFsbCgiLmNvZGUiKSx1LlMpCnQuSyh0LG5ldyBMLkdIKCkpfSwKaFg6ZnVuY3Rpb24oYSxiKXt2YXIg
+dD11Lk4KVy5xRChILmQoYSkrIj9yZWdpb249cmVnaW9uJm9mZnNldD0iK0guZChiKSxudWxsLFAuRUYo
+WyJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04Il0sdCx0KSkuVzco
+bmV3IEwuRFQoKSx1LlApLk9BKG5ldyBMLmVIKGEpKX0sCkc3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0
+LHMKaWYoIUouclkoYSkuVGMoYSwiLmRhcnQiKSl7TC5CRShhLFAuRUYoWyJyZWdpb25zIiwiIiwibmF2
+aWdhdGlvbkNvbnRlbnQiLCIiLCJlZGl0cyIsW11dLHUuTix1LnopKQpMLkJYKGEsbnVsbCkKaWYoZCE9
+bnVsbClkLiQwKCkKcmV0dXJufXQ9Qy54Qi50ZyhhLCI/Iik/YSsiJmlubGluZT10cnVlIjphKyI/aW5s
+aW5lPXRydWUiCnM9dS5OClcucUQodCxudWxsLFAuRUYoWyJDb250ZW50LVR5cGUiLCJhcHBsaWNhdGlv
+bi9qc29uOyBjaGFyc2V0PVVURi04Il0scyxzKSkuVzcobmV3IEwuekQoYSxiLGMsZCksdS5QKS5PQShu
+ZXcgTC5PRShhKSl9LApHZTpmdW5jdGlvbigpe3ZhciB0PSIvX3ByZXZpZXcvbmF2aWdhdGlvblRyZWUu
+anNvbiIscz11Lk4KVy5xRCh0LG51bGwsUC5FRihbIkNvbnRlbnQtVHlwZSIsImFwcGxpY2F0aW9uL2pz
+b247IGNoYXJzZXQ9VVRGLTgiXSxzLHMpKS5XNyhuZXcgTC5UVygpLHUuUCkuT0EobmV3IEwueHIodCkp
+fSwKcUo6ZnVuY3Rpb24oYSxiKXt2YXIgdAp3aW5kb3cKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmlu
+ZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKGEpCndpbmRvdwp0PUguZChiKQppZih0eXBlb2YgY29uc29s
+ZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUuZXJyb3IodCl9LApxTzpmdW5jdGlvbihhKXt2YXIg
+dD1hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHM9dC5ib3R0b20scj13aW5kb3cuaW5uZXJIZWlnaHQK
+aWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShyKQppZihzPnIpSi5kaChhKQplbHNlIGlm
+KHQudG9wPDApSi5kaChhKX0sCmZHOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmlmKGEhPW51bGwpe3Q9
+ZG9jdW1lbnQKcz10LmdldEVsZW1lbnRCeUlkKCJvIitILmQoYSkpCnI9dC5xdWVyeVNlbGVjdG9yKCIu
+bGluZS0iK0guZChiKSkKaWYocyE9bnVsbCl7TC5xTyhzKQpKLmRSKHMpLmkoMCwidGFyZ2V0Iil9ZWxz
+ZSBpZihyIT1udWxsKUwucU8oci5wYXJlbnRFbGVtZW50KQppZihyIT1udWxsKUouZFIodS5oLmEoci5w
+YXJlbnROb2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNlIEwucU8oZG9jdW1lbnQuZ2V0RWxlbWVudEJ5
+SWQoInVuaXQtbmFtZSIpKX0sCmFmOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscj1MLkc2KHdpbmRv
+dy5sb2NhdGlvbi5ocmVmKSxxPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCmlmKHIhPW51bGwpe3Q9
+ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm8iK0guZChyKSkKaWYodCE9bnVsbClKLmRSKHQpLlIoMCwi
+dGFyZ2V0Iil9aWYocSE9bnVsbCl7cz1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubGluZS0iK0guZChx
+KSkKaWYocyE9bnVsbClKLmRSKHMucGFyZW50RWxlbWVudCkuUigwLCJoaWdobGlnaHQiKX1pZihhPT13
+aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpe0wuZkcoYixjKQpkLiQwKCl9ZWxzZSBMLkc3KGEsYixjLGQp
+fSwKTHg6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPT09MSl0PWIKZWxzZSB0PWIrInMiCnJldHVybiB0
+fSwKVDE6ZnVuY3Rpb24oYTgpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxi
+LGEsYTAsYTEsYTIsYTMsYTQsYTUsYTY9ZG9jdW1lbnQsYTc9YTYucXVlcnlTZWxlY3RvcigiLmVkaXQt
+cGFuZWwgLnBhbmVsLWNvbnRlbnQiKQpKLmw1KGE3LCIiKQppZihhOD09bnVsbCl7YTY9YTYuY3JlYXRl
+RWxlbWVudCgicCIpCmE2LnRleHRDb250ZW50PSJTZWUgZGV0YWlscyBhYm91dCBhIHByb3Bvc2VkIGVk
+aXQuIgpDLkx0LnNEKGE2LEguVk0oWyJwbGFjZWhvbGRlciJdLHUucykpCmE3LmFwcGVuZENoaWxkKGE2
+KQpyZXR1cm59dD1hOC5lCnM9JC5uVSgpCnI9cy50TSh0KQpxPWE4LmMKcD1zLkhQKHQsSi5UMChhNi5x
+dWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSkKbz1hOC5kCnM9YTYuY3JlYXRlRWxlbWVu
+dCgicCIpCm49dS5oCm4uYihhNy5hcHBlbmRDaGlsZChzKSkuYXBwZW5kQ2hpbGQoYTYuY3JlYXRlVGV4
+dE5vZGUoSC5kKHEpKyIgYXQgIitILmQocCkrIjoiK0guZChvKSsiLiIpKQpzPWE4LmEKaWYocy5sZW5n
+dGghPT0wKXttPWE2LmNyZWF0ZUVsZW1lbnQoInAiKQptLnRleHRDb250ZW50PSJFZGl0IHJhdGlvbmFs
+ZToiCmE3LmFwcGVuZENoaWxkKG0pCm09YTYuY3JlYXRlRWxlbWVudCgidWwiKQpsPW4uYihhNy5hcHBl
+bmRDaGlsZChtKSkKZm9yKG09cy5sZW5ndGgsaz0wO2s8cy5sZW5ndGg7cy5sZW5ndGg9PT1tfHwoMCxI
+LmxrKShzKSwrK2spe2o9c1trXQppPWE2LmNyZWF0ZUVsZW1lbnQoImxpIikKaD1sLmFwcGVuZENoaWxk
+KGkpCmguYXBwZW5kQ2hpbGQoYTYuY3JlYXRlVGV4dE5vZGUoai5hKSkKZz1qLmIKaWYoZyE9bnVsbCl7
+aC5hcHBlbmRDaGlsZChhNi5jcmVhdGVUZXh0Tm9kZSgiICgiKSkKaC5hcHBlbmRDaGlsZChMLmM0KGcs
+cikpCmguYXBwZW5kQ2hpbGQoYTYuY3JlYXRlVGV4dE5vZGUoIikiKSl9fX1zPWE4LmIKaWYocyE9bnVs
+bClmb3IobT1zLmxlbmd0aCxpPXUucyxmPXUuWCxrPTA7azxzLmxlbmd0aDtzLmxlbmd0aD09PW18fCgw
+LEgubGspKHMpLCsrayl7ZT1zW2tdCmQ9YTYuY3JlYXRlRWxlbWVudCgicCIpCmM9bi5iKGE3LmFwcGVu
+ZENoaWxkKGQpKQpkPWE2LmNyZWF0ZUVsZW1lbnQoImEiKQpiPW4uYihjLmFwcGVuZENoaWxkKGQpKQpi
+LmFwcGVuZENoaWxkKGE2LmNyZWF0ZVRleHROb2RlKGUuYSkpCmIuc2V0QXR0cmlidXRlKCJocmVmIixl
+LmIpCmQ9Zi5iKEguVk0oWyJwb3N0LWxpbmsiLCJiZWZvcmUtYXBwbHkiXSxpKSkKYT1KLmRSKGIpCmEu
+VjEoMCkKYS5GVigwLGQpfWZvcihzPWE4LmYsbj1zLmxlbmd0aCxrPTA7azxzLmxlbmd0aDtzLmxlbmd0
+aD09PW58fCgwLEgubGspKHMpLCsrayl7YTA9c1trXQptPWE2LmNyZWF0ZUVsZW1lbnQoInAiKQphMT1h
+Ny5hcHBlbmRDaGlsZChtKQphMS5hcHBlbmRDaGlsZChhNi5jcmVhdGVUZXh0Tm9kZShhMC5hKSkKbT1h
+Ni5jcmVhdGVFbGVtZW50KCJ1bCIpCmEyPWExLmFwcGVuZENoaWxkKG0pCmZvcihtPWEwLmIsaT1tLmxl
+bmd0aCxhMz0wO2EzPG0ubGVuZ3RoO20ubGVuZ3RoPT09aXx8KDAsSC5saykobSksKythMyl7YTQ9bVth
+M10KZj1hNi5jcmVhdGVFbGVtZW50KCJsaSIpCmE1PWEyLmFwcGVuZENoaWxkKGYpCmY9YTQuYgppZihm
+PT1udWxsKWY9InVua25vd24iCmE1LmFwcGVuZENoaWxkKGE2LmNyZWF0ZVRleHROb2RlKGYpKQpnPWE0
+LmMKaWYoZyE9bnVsbCl7YTUuYXBwZW5kQ2hpbGQoYTYuY3JlYXRlVGV4dE5vZGUoIiAoIikpCmE1LmFw
+cGVuZENoaWxkKEwuYzQoZyxyKSkKYTUuYXBwZW5kQ2hpbGQoYTYuY3JlYXRlVGV4dE5vZGUoIikiKSl9
+YTUuYXBwZW5kQ2hpbGQoYTYuY3JlYXRlVGV4dE5vZGUoIjogIikpCmE1LmFwcGVuZENoaWxkKGE2LmNy
+ZWF0ZVRleHROb2RlKGE0LmEpKX19fSwKTEg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsayxqLGksaCxnLGYsZSxkPWRvY3VtZW50LGM9ZC5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0IC5w
+YW5lbC1jb250ZW50IikKSi5sNShjLCIiKQp0PWQuY3JlYXRlRWxlbWVudCgicCIpCnM9dS5oCnI9cy5i
+KGMuYXBwZW5kQ2hpbGQodCkpCnQ9Si5VNihiKQpxPXQuZ0EoYikKaWYocT09PTApci5hcHBlbmRDaGls
+ZChkLmNyZWF0ZVRleHROb2RlKCJObyBwcm9wb3NlZCBlZGl0cyIpKQplbHNlIHIuYXBwZW5kQ2hpbGQo
+ZC5jcmVhdGVUZXh0Tm9kZSgiIitxKyIgcHJvcG9zZWQgIitMLkx4KHEsImVkaXQiKSsiOiIpKQpwPWQu
+Y3JlYXRlRWxlbWVudCgidWwiKQpvPXMuYihjLmFwcGVuZENoaWxkKHApKQpmb3IodD10LmdreihiKSxw
+PXUuayxuPXUuUSxtPW4uQygifigxKSIpLGw9dS5NLG49bi5kLGs9dS5hO3QuRigpOyl7aj1rLmIodC5n
+bCgpKQppPWQuY3JlYXRlRWxlbWVudCgibGkiKQpoPXMuYihvLmFwcGVuZENoaWxkKGkpKQpKLmRSKGgp
+LmkoMCwiZWRpdCIpCmk9ZC5jcmVhdGVFbGVtZW50KCJhIikKZz1wLmIoaC5hcHBlbmRDaGlsZChpKSkK
+Zy5jbGFzc0xpc3QuYWRkKCJlZGl0LWxpbmsiKQpmPUguU2Moai5xKDAsIm9mZnNldCIpKQppPUguZChm
+KQpnLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGcpKS5PKCJvZmZzZXQiKSxp
+KQplPUguU2Moai5xKDAsImxpbmUiKSkKaT1ILmQoZSkKZy5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcg
+Vy5TeShuZXcgVy5pNyhnKSkuTygibGluZSIpLGkpCmcuYXBwZW5kQ2hpbGQoZC5jcmVhdGVUZXh0Tm9k
+ZSgibGluZSAiK0guZChlKSkpCmk9bS5iKG5ldyBMLkVFKGYsZSxhKSkKbC5iKG51bGwpClcuSkUoZywi
+Y2xpY2siLGksITEsbikKaC5hcHBlbmRDaGlsZChkLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5kKGoucSgw
+LCJleHBsYW5hdGlvbiIpKSkpfUwuVDEobnVsbCl9LApGcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxy
+LHE9d2luZG93LmxvY2F0aW9uLHA9UC5oSygocSYmQy5FeCkuZ0RyKHEpK0guZChhKSkKcT11LnoKdD1Q
+LkZsKHUuTixxKQppZihiIT1udWxsKXQuWSgwLCJvZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbCl0Llko
+MCwibGluZSIsSC5kKGMpKQpwPXAubm0oMCx0LmE9PT0wP251bGw6dCkKcz13aW5kb3cuaGlzdG9yeQpy
+PXAudygwKQpzLnRvU3RyaW5nCnMucHVzaFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHEscSkp
+LCIiLHIpfSwKRW46ZnVuY3Rpb24oYSl7dmFyIHQ9Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIu
+cm9vdCIpLnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uKGEsdCkpcmV0dXJuIEMueEIuRyhhLHQubGVu
+Z3RoKQplbHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9e30Kci5hPWEKYT1M
+LkVuKGEpCnIuYT1hCnQ9ZG9jdW1lbnQKdC5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1lIikudGV4dENv
+bnRlbnQ9YQpzPXUuaApILkRoKHMscywiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQp0PW5ldyBXLnd6KHQu
+cXVlcnlTZWxlY3RvckFsbCgiLm5hdi1wYW5lbCAubmF2LWxpbmsiKSx1LlMpCnQuSyh0LG5ldyBMLlZT
+KHIpKX0sCkJFOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Ii5yZWdpb25zIixzPWRvY3VtZW50LHI9cy5xdWVy
+eVNlbGVjdG9yKHQpLHE9cy5xdWVyeVNlbGVjdG9yKCIuY29kZSIpCkoudEgocixILnkoYi5xKDAsInJl
+Z2lvbnMiKSksJC5LRygpKQpKLnRIKHEsSC55KGIucSgwLCJuYXZpZ2F0aW9uQ29udGVudCIpKSwkLktH
+KCkpCkwuTEgoYSx1LmouYihiLnEoMCwiZWRpdHMiKSkpCkwudlUoKQpMLnlYKCIuY29kZSIpCkwueVgo
+dCl9LAp0WDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGo9Im5hbWUiLGk9ZG9j
+dW1lbnQsaD1pLmNyZWF0ZUVsZW1lbnQoInVsIiksZz11LmgsZj1nLmIoYS5hcHBlbmRDaGlsZChoKSkK
+Zm9yKGg9Si5JVCh1LlIuYihiKSksdD11Lk07aC5GKCk7KXtzPWguZ2woKQpyPWkuY3JlYXRlRWxlbWVu
+dCgibGkiKQpxPWcuYihmLmFwcGVuZENoaWxkKHIpKQpyPUouVTYocykKcD1KLlJFKHEpCmlmKEouUk0o
+ci5xKHMsInR5cGUiKSwiZGlyZWN0b3J5Iikpe3AuZ0QocSkuaSgwLCJkaXIiKQpwPWkuY3JlYXRlRWxl
+bWVudCgic3BhbiIpCm89Zy5iKHEuYXBwZW5kQ2hpbGQocCkpCnA9Si5SRShvKQpwLmdEKG8pLmkoMCwi
+YXJyb3ciKQpwLnNoZihvLCImI3gyNUJDOyIpCnA9aS5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5sNShn
+LmIocS5hcHBlbmRDaGlsZChwKSksIiYjeDFGNEMxOyIpCnEuYXBwZW5kQ2hpbGQoaS5jcmVhdGVUZXh0
+Tm9kZShILnkoci5xKHMsaikpKSkKTC50WChxLHIucShzLCJzdWJ0cmVlIikpCkwua3oobyl9ZWxzZXtw
+LnNoZihxLCImI3gxRjRDNDsiKQpwPWkuY3JlYXRlRWxlbWVudCgiYSIpCm49Zy5iKHEuYXBwZW5kQ2hp
+bGQocCkpCnA9Si5SRShuKQpwLmdEKG4pLmkoMCwibmF2LWxpbmsiKQptPUgueShyLnEocywicGF0aCIp
+KQpuLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KG4pKS5PKGopLG0pCm4uc2V0
+QXR0cmlidXRlKCJocmVmIixILnkoci5xKHMsImhyZWYiKSkpCm4uYXBwZW5kQ2hpbGQoaS5jcmVhdGVU
+ZXh0Tm9kZShILnkoci5xKHMsaikpKSkKcD1wLmdWbChuKQptPXAuJHRpCm0uQygifigxKSIpLmIoTC5Y
+TigpKQp0LmIobnVsbCkKVy5KRShwLmEscC5iLEwuWE4oKSwhMSxtLmQpCmw9SC5TYyhyLnEocywiZWRp
+dENvdW50IikpCmlmKHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwub3MoKQppZihsPjApe3I9aS5j
+cmVhdGVFbGVtZW50KCJzcGFuIikKaz1nLmIocS5hcHBlbmRDaGlsZChyKSkKSi5kUihrKS5pKDAsImVk
+aXQtY291bnQiKQpyPSIiK2wrIiAiCmlmKGw9PT0xKXA9ImVkaXQiCmVsc2UgcD0iZWRpdHMiCmsuc2V0
+QXR0cmlidXRlKCJ0aXRsZSIscitwKQprLmFwcGVuZENoaWxkKGkuY3JlYXRlVGV4dE5vZGUoQy5qbi53
+KGwpKSl9fX19LApjNDpmdW5jdGlvbihhLGIpe3ZhciB0PWRvY3VtZW50LHM9dC5jcmVhdGVFbGVtZW50
+KCJhIikKdS5rLmIocykKcy5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKEguZChhLmMpKyI6IitI
+LmQoYS5iKSkpCnQ9RC5ucihiLGEuYSkKcy5zZXRBdHRyaWJ1dGUoImhyZWYiLCQublUoKS5vNSh0KSkK
+cy5jbGFzc0xpc3QuYWRkKCJuYXYtbGluayIpCnJldHVybiBzfSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6
+ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24g
+b1ooKXt9LApqcjpmdW5jdGlvbiBqcigpe30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKTDpmdW5jdGlvbiBM
+KCl7fSwKV3g6ZnVuY3Rpb24gV3goYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFPOmZ1bmN0aW9uIEFP
+KCl7fSwKZE46ZnVuY3Rpb24gZE4oKXt9LApIbzpmdW5jdGlvbiBIbyhhKXt0aGlzLmE9YX0sCnh6OmZ1
+bmN0aW9uIHh6KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJQzpmdW5jdGlvbiBJQygpe30sCkwxOmZ1
+bmN0aW9uIEwxKCl7fSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
+Yz1jfSwKQlo6ZnVuY3Rpb24gQlooYSl7dGhpcy5hPWF9LApGUTpmdW5jdGlvbiBGUShhKXt0aGlzLmE9
+YX0sCkdIOmZ1bmN0aW9uIEdIKCl7fSwKRFQ6ZnVuY3Rpb24gRFQoKXt9LAplSDpmdW5jdGlvbiBlSChh
+KXt0aGlzLmE9YX0sCnpEOmZ1bmN0aW9uIHpEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
+Xy5jPWMKXy5kPWR9LApPRTpmdW5jdGlvbiBPRShhKXt0aGlzLmE9YX0sClRXOmZ1bmN0aW9uIFRXKCl7
+fSwKeHI6ZnVuY3Rpb24geHIoYSl7dGhpcy5hPWF9LApFRTpmdW5jdGlvbiBFRShhLGIsYyl7dGhpcy5h
+PWEKdGhpcy5iPWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBRTChhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
+fSwKVlM6ZnVuY3Rpb24gVlMoYSl7dGhpcy5hPWF9LApYQTpmdW5jdGlvbiBYQSgpe30sCklWOmZ1bmN0
+aW9uIElWKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxNPXsKWUY6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbgpmb3IodD1iLmxlbmd0aCxzPTE7czx0Oysrcyl7
+aWYoYltzXT09bnVsbHx8YltzLTFdIT1udWxsKWNvbnRpbnVlCmZvcig7dD49MTt0PXIpe3I9dC0xCmlm
+KGJbcl0hPW51bGwpYnJlYWt9cT1uZXcgUC5SbigiIikKcD1hKyIoIgpxLmE9cApvPUgucUMoYiwwLHQs
+SC50NihiKS5kKQpuPW8uJHRpCm49cCtuZXcgSC5BOChvLG4uQygicVUoYUwuRSkiKS5iKG5ldyBNLk5v
+KCkpLG4uQygiQTg8YUwuRSxxVT4iKSkuSCgwLCIsICIpCnEuYT1uCnEuYT1uKygiKTogcGFydCAiKyhz
+LTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0ICIrcysiIHdhcyBub3QuIikKdGhyb3cgSC5iKFAueFkocS53
+KDApKSl9fSwKbEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5hPWF9LApNaTpmdW5jdGlvbiBNaSgpe30sCnE3
+OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24gTm8oKXt9fSxCPXtMdTpmdW5jdGlvbiBMdSgpe30s
+Ck9TOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCEoYT49NjUmJmE8PTkwKSl0PWE+PTk3JiZhPD0xMjIKZWxz
+ZSB0PSEwCnJldHVybiB0fSwKWXU6ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLmxlbmd0aCxzPWIrMgppZih0
+PHMpcmV0dXJuITEKaWYoIUIuT1MoQy54Qi5tKGEsYikpKXJldHVybiExCmlmKEMueEIubShhLGIrMSkh
+PT01OClyZXR1cm4hMQppZih0PT09cylyZXR1cm4hMApyZXR1cm4gQy54Qi5tKGEscyk9PT00N319LFg9
+ewpDTDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz1iLnhaKGEpCmIuaEsoYSkKaWYobyE9bnVs
+bClhPUouS1YoYSxvLmxlbmd0aCkKdD11LnMKcz1ILlZNKFtdLHQpCnI9SC5WTShbXSx0KQp0PWEubGVu
+Z3RoCmlmKHQhPT0wJiZiLnI0KEMueEIuVyhhLDApKSl7aWYoMD49dClyZXR1cm4gSC5PSChhLDApCkMu
+Tm0uaShyLGFbMF0pCnE9MX1lbHNle0MuTm0uaShyLCIiKQpxPTB9Zm9yKHA9cTtwPHQ7KytwKWlmKGIu
+cjQoQy54Qi5XKGEscCkpKXtDLk5tLmkocyxDLnhCLk5qKGEscSxwKSkKQy5ObS5pKHIsYVtwXSkKcT1w
+KzF9aWYocTx0KXtDLk5tLmkocyxDLnhCLkcoYSxxKSkKQy5ObS5pKHIsIiIpfXJldHVybiBuZXcgWC5X
+RChiLG8scyxyKX0sCldEOmZ1bmN0aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
+Xy5kPWMKXy5lPWR9LApxUjpmdW5jdGlvbiBxUihhKXt0aGlzLmE9YX0sCkpUOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBuZXcgWC5kdihhKX0sCmR2OmZ1bmN0aW9uIGR2KGEpe3RoaXMuYT1hfX0sTz17ClJoOmZ1bmN0
+aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPW51bGwKaWYoUC51bygpLmdGaSgpIT09ImZp
+bGUiKXJldHVybiAkLkViKCkKdD1QLnVvKCkKaWYoIUMueEIuVGModC5nSWkodCksIi8iKSlyZXR1cm4g
+JC5FYigpCnM9UC5QaShpLDAsMCkKcj1QLnpSKGksMCwwKQpxPVAuT2UoaSwwLDAsITEpCnA9UC5sZShp
+LDAsMCxpKQpvPVAudEcoaSwwLDApCm49UC53QihpLHMpCm09cz09PSJmaWxlIgppZihxPT1udWxsKXQ9
+ci5sZW5ndGghPT0wfHxuIT1udWxsfHxtCmVsc2UgdD0hMQppZih0KXE9IiIKdD1xPT1udWxsCmw9IXQK
+az1QLmthKCJhL2IiLDAsMyxpLHMsbCkKaj1zLmxlbmd0aD09PTAKaWYoaiYmdCYmIUMueEIubihrLCIv
+Iikpaz1QLndGKGssIWp8fGwpCmVsc2Ugaz1QLnhlKGspCmlmKG5ldyBQLkRuKHMscix0JiZDLnhCLm4o
+aywiLy8iKT8iIjpxLG4sayxwLG8pLnQ0KCk9PT0iYVxcYiIpcmV0dXJuICQuS2soKQpyZXR1cm4gJC5i
+RCgpfSwKekw6ZnVuY3Rpb24gekwoKXt9fSxFPXtPRjpmdW5jdGlvbiBPRihhLGIsYyl7dGhpcy5kPWEK
+dGhpcy5lPWIKdGhpcy5mPWN9fSxGPXtydTpmdW5jdGlvbiBydShhLGIsYyxkKXt2YXIgXz10aGlzCl8u
+ZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sRD17ClJYOmZ1bmN0aW9uKCl7dmFyIHQscyxyPVAudW8oKQpp
+ZihKLlJNKHIsJC5JNikpcmV0dXJuICQuRmYKJC5JNj1yCmlmKCQuSGsoKT09JC5FYigpKXJldHVybiAk
+LkZmPXIuWkkoIi4iKS53KDApCmVsc2V7dD1yLnQ0KCkKcz10Lmxlbmd0aC0xCnJldHVybiAkLkZmPXM9
+PT0wP3Q6Qy54Qi5Oaih0LDAscyl9fSwKbnI6ZnVuY3Rpb24oYSxiKXt2YXIgdD1udWxsCnJldHVybiAk
+Lm5VKCkucTcoMCxhLGIsdCx0LHQsdCx0LHQpfX0KdmFyIHc9W0MsSCxKLFAsVyxVLFQsTCxNLEIsWCxP
+LEUsRixEXQpodW5rSGVscGVycy5zZXRGdW5jdGlvbk5hbWVzSWZOZWNlc3NhcnkodykKdmFyICQ9e30K
+SC5lby5wcm90b3R5cGU9e30KSi52Qi5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBh
+PT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUShhKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+Ikluc3RhbmNlIG9mICciK0guZChILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmIoYikK
+dGhyb3cgSC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIGE/
+NTE5MDE4OjIxODE1OX0sCiRpYTI6MX0KSi5ZRS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBudWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24oYSl7
+cmV0dXJuIDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdS5vLmIoYikpfSwKJGlj
+ODoxfQpKLk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90b3R5
+cGU9e30KSi5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PWFbJC53KCldCmlmKHQ9PW51
+bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILmQoSi5q
+KHQpKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJue2Z1bmM6MSxvcHQ6WywsLCwsLCwsLCwsLCwsLCxdfX0s
+CiRpRUg6MX0KSi5qZC5wcm90b3R5cGU9ewppOmZ1bmN0aW9uKGEsYil7SC50NihhKS5kLmIoYikKaWYo
+ISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImFkZCIpKQphLnB1c2goYil9LApXNDpmdW5jdGlvbihh
+LGIpe3ZhciB0CmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJyZW1vdmVBdCIpKQp0PWEubGVu
+Z3RoCmlmKGI+PXQpdGhyb3cgSC5iKFAueChiLG51bGwpKQpyZXR1cm4gYS5zcGxpY2UoYiwxKVswXX0s
+ClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKSC50NihhKS5DKCJjWDwxPiIpLmIoYykKaWYoISFh
+LmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImluc2VydEFsbCIpKQp0PWEubGVuZ3RoClAud0EoYiwwLHQs
+ImluZGV4IikKcz1jLmxlbmd0aAp0aGlzLnNBKGEsdCtzKQpyPWIrcwp0aGlzLllXKGEscixhLmxlbmd0
+aCxhLGIpCnRoaXMudmcoYSxiLHIsYyl9LAptdjpmdW5jdGlvbihhKXtpZighIWEuZml4ZWQkbGVuZ3Ro
+KUgudmgoUC5MNCgicmVtb3ZlTGFzdCIpKQppZihhLmxlbmd0aD09PTApdGhyb3cgSC5iKEguSFkoYSwt
+MSkpCnJldHVybiBhLnBvcCgpfSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdApILnQ2KGEpLkMoImNYPDE+
+IikuYihiKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiYWRkQWxsIikpCmZvcih0PUouSVQo
+Yik7dC5GKCk7KWEucHVzaCh0LmdsKCkpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50NihhKS5D
+KCJ+KDEpIikuYihiKQp0PWEubGVuZ3RoCmZvcihzPTA7czx0Oysrcyl7Yi4kMShhW3NdKQppZihhLmxl
+bmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILnQ2
+KGEpCnJldHVybiBuZXcgSC5BOChhLHQuS3EoYykuQygiMSgyKSIpLmIoYiksdC5DKCJAPDE+IikuS3Eo
+YykuQygiQTg8MSwyPiIpKX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPW5ldyBBcnJheShhLmxlbmd0
+aCkKcy5maXhlZCRsZW5ndGg9QXJyYXkKZm9yKHQ9MDt0PGEubGVuZ3RoOysrdCl0aGlzLlkocyx0LEgu
+ZChhW3RdKSkKcmV0dXJuIHMuam9pbihiKX0sCk4wOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgpk
+LmIoYikKSC50NihhKS5LcShkKS5DKCIxKDEsMikiKS5iKGMpCnQ9YS5sZW5ndGgKZm9yKHM9YixyPTA7
+cjx0Oysrcil7cz1jLiQyKHMsYVtyXSkKaWYoYS5sZW5ndGghPT10KXRocm93IEguYihQLmE0KGEpKX1y
+ZXR1cm4gc30sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEs
+YikKcmV0dXJuIGFbYl19LAphTTpmdW5jdGlvbihhLGIsYyl7aWYoYjwwfHxiPmEubGVuZ3RoKXRocm93
+IEguYihQLlRFKGIsMCxhLmxlbmd0aCwic3RhcnQiLG51bGwpKQppZihjPGJ8fGM+YS5sZW5ndGgpdGhy
+b3cgSC5iKFAuVEUoYyxiLGEubGVuZ3RoLCJlbmQiLG51bGwpKQppZihiPT09YylyZXR1cm4gSC5WTShb
+XSxILnQ2KGEpKQpyZXR1cm4gSC5WTShhLnNsaWNlKGIsYyksSC50NihhKSl9LApnclo6ZnVuY3Rpb24o
+YSl7dmFyIHQ9YS5sZW5ndGgKaWYodD4wKXJldHVybiBhW3QtMV0KdGhyb3cgSC5iKEguV3AoKSl9LApZ
+VzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscj1ILnQ2KGEpCnIuQygiY1g8MT4iKS5iKGQpCmlm
+KCEhYS5pbW11dGFibGUkbGlzdClILnZoKFAuTDQoInNldFJhbmdlIikpClAuakIoYixjLGEubGVuZ3Ro
+KQp0PWMtYgppZih0PT09MClyZXR1cm4KUC5rMShlLCJza2lwQ291bnQiKQpyLkMoInpNPDE+IikuYihk
+KQpyPUouVTYoZCkKaWYoZSt0PnIuZ0EoZCkpdGhyb3cgSC5iKEguYXIoKSkKaWYoZTxiKWZvcihzPXQt
+MTtzPj0wOy0tcylhW2Irc109ci5xKGQsZStzKQplbHNlIGZvcihzPTA7czx0OysrcylhW2Irc109ci5x
+KGQsZStzKX0sCnZnOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLllXKGEsYixjLGQsMCl9LApW
+cjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50NihhKS5DKCJhMigxKSIpLmIoYikKdD1hLmxlbmd0aApm
+b3Iocz0wO3M8dDsrK3Mpe2lmKEgub1QoYi4kMShhW3NdKSkpcmV0dXJuITAKaWYoYS5sZW5ndGghPT10
+KXRocm93IEguYihQLmE0KGEpKX1yZXR1cm4hMX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9
+MDt0PGEubGVuZ3RoOysrdClpZihKLlJNKGFbdF0sYikpcmV0dXJuITAKcmV0dXJuITF9LAp3OmZ1bmN0
+aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9LApna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBK
+Lm0xKGEsYS5sZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4g
+SC5lUShhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnNBOmZ1bmN0aW9uKGEsYil7
+aWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoInNldCBsZW5ndGgiKSkKaWYoYjwwKXRocm93IEgu
+YihQLlRFKGIsMCxudWxsLCJuZXdMZW5ndGgiLG51bGwpKQphLmxlbmd0aD1ifSwKcTpmdW5jdGlvbihh
+LGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4g
+YVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuZC5iKGMpCmlmKCEhYS5pbW11dGFibGUkbGlz
+dClILnZoKFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cgSC5iKEgu
+SFkoYSxiKSkKYVtiXT1jfSwKJGljWDoxLAokaXpNOjF9CkouUG8ucHJvdG90eXBlPXt9CkoubTEucHJv
+dG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHM9
+dGhpcyxyPXMuYSxxPXIubGVuZ3RoCmlmKHMuYiE9PXEpdGhyb3cgSC5iKEgubGsocikpCnQ9cy5jCmlm
+KHQ+PXEpe3Muc00obnVsbCkKcmV0dXJuITF9cy5zTShyW3RdKTsrK3MuYwpyZXR1cm4hMH0sCnNNOmZ1
+bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5kLmIoYSl9LAokaUFuOjF9CkoucUkucHJvdG90eXBlPXsK
+eXU6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT49LTIxNDc0ODM2NDgmJmE8PTIxNDc0ODM2NDcpcmV0dXJu
+IGF8MAppZihpc0Zpbml0ZShhKSl7dD1hPDA/TWF0aC5jZWlsKGEpOk1hdGguZmxvb3IoYSkKcmV0dXJu
+IHQrMH10aHJvdyBILmIoUC5MNCgiIithKyIudG9JbnQoKSIpKX0sCnpROmZ1bmN0aW9uKGEpe2lmKGE+
+MCl7aWYoYSE9PTEvMClyZXR1cm4gTWF0aC5yb3VuZChhKX1lbHNlIGlmKGE+LTEvMClyZXR1cm4gMC1N
+YXRoLnJvdW5kKDAtYSkKdGhyb3cgSC5iKFAuTDQoIiIrYSsiLnJvdW5kKCkiKSl9LApXWjpmdW5jdGlv
+bihhLGIpe3ZhciB0LHMscixxCmlmKGI8Mnx8Yj4zNil0aHJvdyBILmIoUC5URShiLDIsMzYsInJhZGl4
+IixudWxsKSkKdD1hLnRvU3RyaW5nKGIpCmlmKEMueEIubSh0LHQubGVuZ3RoLTEpIT09NDEpcmV0dXJu
+IHQKcz0vXihbXGRhLXpdKykoPzpcLihbXGRhLXpdKykpP1woZVwrKFxkKylcKSQvLmV4ZWModCkKaWYo
+cz09bnVsbClILnZoKFAuTDQoIlVuZXhwZWN0ZWQgdG9TdHJpbmcgcmVzdWx0OiAiK3QpKQpyPXMubGVu
+Z3RoCmlmKDE+PXIpcmV0dXJuIEguT0gocywxKQp0PXNbMV0KaWYoMz49cilyZXR1cm4gSC5PSChzLDMp
+CnE9K3NbM10Kcj1zWzJdCmlmKHIhPW51bGwpe3QrPXIKcS09ci5sZW5ndGh9cmV0dXJuIHQrQy54Qi5J
+eCgiMCIscSl9LAp3OmZ1bmN0aW9uKGEpe2lmKGE9PT0wJiYxL2E8MClyZXR1cm4iLTAuMCIKZWxzZSBy
+ZXR1cm4iIithfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9YXwwCmlmKGE9PT1wKXJldHVy
+biA1MzY4NzA5MTEmcAp0PU1hdGguYWJzKGEpCnM9TWF0aC5sb2codCkvMC42OTMxNDcxODA1NTk5NDUz
+fDAKcj1NYXRoLnBvdygyLHMpCnE9dDwxP3QvcjpyL3QKcmV0dXJuIDUzNjg3MDkxMSYoKHEqOTAwNzE5
+OTI1NDc0MDk5MnwwKSsocSozNTQyMjQzMTgxMTc2NTIxfDApKSo1OTkxOTcrcyoxMjU5fSwKelk6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdD1hJWIKaWYodD09PTApcmV0dXJuIDAKaWYodD4wKXJldHVybiB0CmlmKGI8
+MClyZXR1cm4gdC1iCmVsc2UgcmV0dXJuIHQrYn0sCndHOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYT4w
+KXQ9dGhpcy5wMyhhLGIpCmVsc2V7dD1iPjMxPzMxOmIKdD1hPj50Pj4+MH1yZXR1cm4gdH0sCmJmOmZ1
+bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILnRMKGIpKQpyZXR1cm4gdGhpcy5wMyhhLGIpfSwK
+cDM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYj4zMT8wOmE+Pj5ifSwKJGlDUDoxLAokaUZLOjF9CkoudXIu
+cHJvdG90eXBlPXskaUtOOjF9CkouVkEucHJvdG90eXBlPXt9CkouRHIucHJvdG90eXBlPXsKbTpmdW5j
+dGlvbihhLGIpe2lmKGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQppZihiPj1hLmxlbmd0aClILnZoKEgu
+SFkoYSxiKSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sClc6ZnVuY3Rpb24oYSxiKXtpZihiPj1hLmxl
+bmd0aCl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKZGQ6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gbmV3IEgudW4oYixhLDApfSwKaDpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBi
+IT0ic3RyaW5nIil0aHJvdyBILmIoUC5MMyhiLG51bGwsbnVsbCkpCnJldHVybiBhK2J9LApUYzpmdW5j
+dGlvbihhLGIpe3ZhciB0PWIubGVuZ3RoLHM9YS5sZW5ndGgKaWYodD5zKXJldHVybiExCnJldHVybiBi
+PT09dGhpcy5HKGEscy10KX0sCmk3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMKYz1QLmpCKGIsYyxh
+Lmxlbmd0aCkKdD1hLnN1YnN0cmluZygwLGIpCnM9YS5zdWJzdHJpbmcoYykKcmV0dXJuIHQrZCtzfSwK
+UWk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKCFILm9rKGMpKUgudmgoSC50TChjKSkKaWYodHlwZW9m
+IGMhPT0ibnVtYmVyIilyZXR1cm4gYy5KKCkKaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRF
+KGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWMrYi5sZW5ndGgKaWYodD5hLmxlbmd0aClyZXR1cm4h
+MQpyZXR1cm4gYj09PWEuc3Vic3RyaW5nKGMsdCl9LApuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMu
+UWkoYSxiLDApfSwKTmo6ZnVuY3Rpb24oYSxiLGMpe2lmKCFILm9rKGIpKUgudmgoSC50TChiKSkKaWYo
+Yz09bnVsbCljPWEubGVuZ3RoCmlmKHR5cGVvZiBiIT09Im51bWJlciIpcmV0dXJuIGIuSigpCmlmKGI8
+MCl0aHJvdyBILmIoUC54KGIsbnVsbCkpCmlmKGI+Yyl0aHJvdyBILmIoUC54KGIsbnVsbCkpCmlmKGM+
+YS5sZW5ndGgpdGhyb3cgSC5iKFAueChjLG51bGwpKQpyZXR1cm4gYS5zdWJzdHJpbmcoYixjKX0sCkc6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5OaihhLGIsbnVsbCl9LApoYzpmdW5jdGlvbihhKXtyZXR1
+cm4gYS50b0xvd2VyQ2FzZSgpfSwKYlM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9YS50cmltKCkscD1x
+Lmxlbmd0aAppZihwPT09MClyZXR1cm4gcQppZih0aGlzLlcocSwwKT09PTEzMyl7dD1KLm1tKHEsMSkK
+aWYodD09PXApcmV0dXJuIiJ9ZWxzZSB0PTAKcz1wLTEKcj10aGlzLm0ocSxzKT09PTEzMz9KLmMxKHEs
+cyk6cAppZih0PT09MCYmcj09PXApcmV0dXJuIHEKcmV0dXJuIHEuc3Vic3RyaW5nKHQscil9LApJeDpm
+dW5jdGlvbihhLGIpe3ZhciB0LHMKaWYoMD49YilyZXR1cm4iIgppZihiPT09MXx8YS5sZW5ndGg9PT0w
+KXJldHVybiBhCmlmKGIhPT1iPj4+MCl0aHJvdyBILmIoQy5FcSkKZm9yKHQ9YSxzPSIiOyEwOyl7aWYo
+KGImMSk9PT0xKXM9dCtzCmI9Yj4+PjEKaWYoYj09PTApYnJlYWsKdCs9dH1yZXR1cm4gc30sClhVOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdAppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEu
+bGVuZ3RoLG51bGwsbnVsbCkpCnQ9YS5pbmRleE9mKGIsYykKcmV0dXJuIHR9LApPWTpmdW5jdGlvbihh
+LGIpe3JldHVybiB0aGlzLlhVKGEsYiwwKX0sClBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmlmKGM9
+PW51bGwpYz1hLmxlbmd0aAplbHNlIGlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAs
+YS5sZW5ndGgsbnVsbCxudWxsKSkKdD1iLmxlbmd0aApzPWEubGVuZ3RoCmlmKGMrdD5zKWM9cy10CnJl
+dHVybiBhLmxhc3RJbmRleE9mKGIsYyl9LApjbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlBrKGEs
+YixudWxsKX0sCklzOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1hLmxlbmd0aAppZihjPnQpdGhyb3cgSC5i
+KFAuVEUoYywwLHQsbnVsbCxudWxsKSkKcmV0dXJuIEgubTIoYSxiLGMpfSwKdGc6ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gdGhpcy5JcyhhLGIsMCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKZ2lPOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTAscj0wO3I8dDsrK3Ipe3M9NTM2ODcwOTEx
+JnMrYS5jaGFyQ29kZUF0KHIpCnM9NTM2ODcwOTExJnMrKCg1MjQyODcmcyk8PDEwKQpzXj1zPj42fXM9
+NTM2ODcwOTExJnMrKCg2NzEwODg2MyZzKTw8MykKc149cz4+MTEKcmV0dXJuIDUzNjg3MDkxMSZzKygo
+MTYzODMmcyk8PDE1KX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24o
+YSxiKXtILlNjKGIpCmlmKGI+PWEubGVuZ3RofHwhMSl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4g
+YVtiXX0sCiRpdlg6MSwKJGlxVToxfQpILnFqLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLmEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBDLnhCLm0odGhpcy5hLEguU2Mo
+YikpfX0KSC5iUS5wcm90b3R5cGU9e30KSC5hTC5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFy
+IHQ9dGhpcwpyZXR1cm4gbmV3IEguYTcodCx0LmdBKHQpLEguTGgodCkuQygiYTc8YUwuRT4iKSl9LApI
+OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhpcyxwPXEuZ0EocSkKaWYoYi5sZW5ndGghPT0wKXtp
+ZihwPT09MClyZXR1cm4iIgp0PUguZChxLkUoMCwwKSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAu
+YTQocSkpCmZvcihzPXQscj0xO3I8cDsrK3Ipe3M9cytiK0guZChxLkUoMCxyKSkKaWYocCE9PXEuZ0Eo
+cSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfWVsc2V7Zm9y
+KHI9MCxzPSIiO3I8cDsrK3Ipe3MrPUguZChxLkUoMCxyKSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5i
+KFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfX0sCmV2OmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMoImEyKGFMLkUpIikuYihiKSl9fQpILm5ILnByb3Rv
+dHlwZT17CmdVRDpmdW5jdGlvbigpe3ZhciB0PUouSG0odGhpcy5hKSxzPXRoaXMuYwppZihzPT1udWxs
+fHxzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQXM6ZnVuY3Rpb24oKXt2YXIgdD1KLkhtKHRoaXMuYSks
+cz10aGlzLmIKaWYocz50KXJldHVybiB0CnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscz1K
+LkhtKHRoaXMuYSkscj10aGlzLmIKaWYocj49cylyZXR1cm4gMAp0PXRoaXMuYwppZih0PT1udWxsfHx0
+Pj1zKXJldHVybiBzLXIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5ITigpCnJldHVybiB0
+LXJ9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5nQXMoKStiCmlmKGI+PTApe3Q9cy5n
+VUQoKQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiBILnBZKHQpCnQ9cj49dH1lbHNlIHQ9ITAK
+aWYodCl0aHJvdyBILmIoUC5DZihiLHMsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5BTShzLmEs
+cil9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rp
+b24oKXt2YXIgdCxzPXRoaXMscj1zLmEscT1KLlU2KHIpLHA9cS5nQShyKQppZihzLmIhPT1wKXRocm93
+IEguYihQLmE0KHIpKQp0PXMuYwppZih0Pj1wKXtzLnNJKG51bGwpCnJldHVybiExfXMuc0kocS5FKHIs
+dCkpOysrcy5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0s
+CiRpQW46MX0KSC5BOC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmEp
+fSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5BTSh0aGlzLmEsYikpfX0KSC5VNS5w
+cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlNPKEouSVQodGhpcy5hKSx0aGlz
+LmIsdGhpcy4kdGkuQygiU088MT4iKSl9fQpILlNPLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIg
+dCxzCmZvcih0PXRoaXMuYSxzPXRoaXMuYjt0LkYoKTspaWYoSC5vVChzLiQxKHQuZ2woKSkpKXJldHVy
+biEwCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLmdsKCl9fQpILlNVLnByb3Rv
+dHlwZT17fQpILlJlLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe0guTGgodGhpcykuQygiUmUu
+RSIpLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgYW4gdW5tb2RpZmlhYmxlIGxpc3Qi
+KSl9fQpILlhDLnByb3RvdHlwZT17fQpILnd2LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXt2YXIg
+dD10aGlzLl9oYXNoQ29kZQppZih0IT1udWxsKXJldHVybiB0CnQ9NTM2ODcwOTExJjY2NDU5NypKLmhm
+KHRoaXMuYSkKdGhpcy5faGFzaENvZGU9dApyZXR1cm4gdH0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuJ1N5
+bWJvbCgiJytILmQodGhpcy5hKSsnIiknfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVy
+biExCnJldHVybiBiIGluc3RhbmNlb2YgSC53diYmdGhpcy5hPT1iLmF9LAokaUdEOjF9CkguUEQucHJv
+dG90eXBlPXt9CkguV1UucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0s
+Clk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdC5kLmIoYikKdC5jaFsxXS5iKGMpCnJl
+dHVybiBILmRjKCl9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigi
+X19wcm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6
+ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4KcmV0dXJuIHRoaXMucVAoYil9LApxUDpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0gueShhKV19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
+LHEscD1ILkxoKHRoaXMpCnAuQygifigxLDIpIikuYihiKQp0PXRoaXMuYwpmb3Iocz10Lmxlbmd0aCxw
+PXAuY2hbMV0scj0wO3I8czsrK3Ipe3E9dFtyXQpiLiQyKHEscC5iKHRoaXMucVAocSkpKX19fQpILkxJ
+LnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdH0sCmduZDpmdW5j
+dGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwppZihwLmM9PT0xKXJldHVybiBDLmRuCnQ9cC5kCnM9dC5s
+ZW5ndGgtcC5lLmxlbmd0aC1wLmYKaWYocz09PTApcmV0dXJuIEMuZG4Kcj1bXQpmb3IocT0wO3E8czsr
+K3Epe2lmKHE+PXQubGVuZ3RoKXJldHVybiBILk9IKHQscSkKci5wdXNoKHRbcV0pfXJldHVybiBKLnpD
+KHIpfSwKZ1ZtOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbSxsPXRoaXMKaWYobC5jIT09MCly
+ZXR1cm4gQy5DTQp0PWwuZQpzPXQubGVuZ3RoCnI9bC5kCnE9ci5sZW5ndGgtcy1sLmYKaWYocz09PTAp
+cmV0dXJuIEMuQ00KcD1uZXcgSC5ONSh1LmVvKQpmb3Iobz0wO288czsrK28pe2lmKG8+PXQubGVuZ3Ro
+KXJldHVybiBILk9IKHQsbykKbj10W29dCm09cStvCmlmKG08MHx8bT49ci5sZW5ndGgpcmV0dXJuIEgu
+T0gocixtKQpwLlkoMCxuZXcgSC53dihuKSxyW21dKX1yZXR1cm4gbmV3IEguUEQocCx1LmdGKX0sCiRp
+dlE6MX0KSC5Dai5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0CkgueShhKQp0PXRoaXMu
+YQp0LmI9dC5iKyIkIitILmQoYSkKQy5ObS5pKHRoaXMuYixhKQpDLk5tLmkodGhpcy5jLGIpOysrdC5h
+fSwKJFM6MTZ9CkguWnIucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1u
+ZXcgUmVnRXhwKHIuYSkuZXhlYyhhKQppZihxPT1udWxsKXJldHVybgp0PU9iamVjdC5jcmVhdGUobnVs
+bCkKcz1yLmIKaWYocyE9PS0xKXQuYXJndW1lbnRzPXFbcysxXQpzPXIuYwppZihzIT09LTEpdC5hcmd1
+bWVudHNFeHByPXFbcysxXQpzPXIuZAppZihzIT09LTEpdC5leHByPXFbcysxXQpzPXIuZQppZihzIT09
+LTEpdC5tZXRob2Q9cVtzKzFdCnM9ci5mCmlmKHMhPT0tMSl0LnJlY2VpdmVyPXFbcysxXQpyZXR1cm4g
+dH19CkguVzAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmIKaWYodD09bnVsbCly
+ZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVy
+cm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIit0KyInIG9uIG51bGwifX0KSC5hei5wcm90b3R5cGU9ewp3
+OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBm
+b3VuZDogJyIscT1zLmIKaWYocT09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHMu
+YSkKdD1zLmMKaWYodD09bnVsbClyZXR1cm4gcitxKyInICgiK0guZChzLmEpKyIpIgpyZXR1cm4gcitx
+KyInIG9uICciK3QrIicgKCIrSC5kKHMuYSkrIikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5sZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAiK3R9fQpI
+LkFtLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe2lmKHUuYlUuYyhhKSlpZihhLiR0aHJvd25Kc0Vy
+cm9yPT1udWxsKWEuJHRocm93bkpzRXJyb3I9dGhpcy5hCnJldHVybiBhfSwKJFM6NH0KSC5YTy5wcm90
+b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5iCmlmKHMhPW51bGwpcmV0dXJuIHMKcz10
+aGlzLmEKdD1zIT09bnVsbCYmdHlwZW9mIHM9PT0ib2JqZWN0Ij9zLnN0YWNrOm51bGwKcmV0dXJuIHRo
+aXMuYj10PT1udWxsPyIiOnR9LAokaUd6OjF9CkguVHAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2
+YXIgdD10aGlzLmNvbnN0cnVjdG9yLHM9dD09bnVsbD9udWxsOnQubmFtZQpyZXR1cm4iQ2xvc3VyZSAn
+IitILk5RKHM9PW51bGw/InVua25vd24iOnMpKyInIn0sCiRpRUg6MSwKZ1FsOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXN9LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpILmxjLnByb3RvdHlwZT17fQpILnp4LnBy
+b3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy4kc3RhdGljX25hbWUKaWYodD09bnVsbCly
+ZXR1cm4iQ2xvc3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRob2QiCnJldHVybiJDbG9zdXJlICciK0gu
+TlEodCkrIicifX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKaWYo
+Yj09bnVsbClyZXR1cm4hMQppZih0PT09YilyZXR1cm4hMAppZighKGIgaW5zdGFuY2VvZiBILnJUKSly
+ZXR1cm4hMQpyZXR1cm4gdC5hPT09Yi5hJiZ0LmI9PT1iLmImJnQuYz09PWIuY30sCmdpTzpmdW5jdGlv
+bihhKXt2YXIgdCxzPXRoaXMuYwppZihzPT1udWxsKXQ9SC5lUSh0aGlzLmEpCmVsc2UgdD10eXBlb2Yg
+cyE9PSJvYmplY3QiP0ouaGYocyk6SC5lUShzKQpyZXR1cm4odF5ILmVRKHRoaXMuYikpPj4+MH0sCnc6
+ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpdD10aGlzLmEKcmV0dXJuIkNsb3N1cmUg
+JyIrSC5kKHRoaXMuZCkrIicgb2YgIisoIkluc3RhbmNlIG9mICciK0guZChILk0odCkpKyInIil9fQpI
+LkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJ1bnRpbWVFcnJvcjogIitILmQodGhp
+cy5hKX19Ckgua1kucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iQXNzZXJ0aW9uIGZhaWxl
+ZDogIitQLnAodGhpcy5hKX19CkguTjUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuYX0sCmdWOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBILmk1KHRoaXMsSC5MaCh0aGlzKS5DKCJpNTwx
+PiIpKX0sCng0OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYodHlwZW9mIGE9PSJzdHJpbmciKXt0PXRoaXMu
+YgppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLlh1KHQsYSl9ZWxzZXtzPXRoaXMuQ1goYSkK
+cmV0dXJuIHN9fSwKQ1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuITEK
+cmV0dXJuIHRoaXMuRmgodGhpcy5CdCh0LEouaGYoYSkmMHgzZmZmZmZmKSxhKT49MH0sCnE6ZnVuY3Rp
+b24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PXAuYgppZih0
+PT1udWxsKXJldHVybgpzPXAuajIodCxiKQpyPXM9PW51bGw/bnVsbDpzLmIKcmV0dXJuIHJ9ZWxzZSBp
+Zih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1iKXtxPXAuYwppZihxPT1udWxsKXJl
+dHVybgpzPXAuajIocSxiKQpyPXM9PW51bGw/bnVsbDpzLmIKcmV0dXJuIHJ9ZWxzZSByZXR1cm4gcC5h
+YShiKX0sCmFhOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLmQKaWYocj09bnVsbClyZXR1cm4KdD10
+aGlzLkJ0KHIsSi5oZihhKSYweDNmZmZmZmYpCnM9dGhpcy5GaCh0LGEpCmlmKHM8MClyZXR1cm4KcmV0
+dXJuIHRbc10uYn0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMsbT1ILkxo
+KG4pCm0uZC5iKGIpCm0uY2hbMV0uYihjKQppZih0eXBlb2YgYj09InN0cmluZyIpe3Q9bi5iCm4uRUgo
+dD09bnVsbD9uLmI9bi56SygpOnQsYixjKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgz
+ZmZmZmZmKT09PWIpe3M9bi5jCm4uRUgocz09bnVsbD9uLmM9bi56SygpOnMsYixjKX1lbHNle3I9bi5k
+CmlmKHI9PW51bGwpcj1uLmQ9bi56SygpCnE9Si5oZihiKSYweDNmZmZmZmYKcD1uLkJ0KHIscSkKaWYo
+cD09bnVsbCluLkVJKHIscSxbbi5IbihiLGMpXSkKZWxzZXtvPW4uRmgocCxiKQppZihvPj0wKXBbb10u
+Yj1jCmVsc2UgcC5wdXNoKG4uSG4oYixjKSl9fX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhp
+cwpILkxoKHIpLkMoIn4oMSwyKSIpLmIoYikKdD1yLmUKcz1yLnIKZm9yKDt0IT1udWxsOyl7Yi4kMih0
+LmEsdC5iKQppZihzIT09ci5yKXRocm93IEguYihQLmE0KHIpKQp0PXQuY319LApFSDpmdW5jdGlvbihh
+LGIsYyl7dmFyIHQscz10aGlzLHI9SC5MaChzKQpyLmQuYihiKQpyLmNoWzFdLmIoYykKdD1zLmoyKGEs
+YikKaWYodD09bnVsbClzLkVJKGEsYixzLkhuKGIsYykpCmVsc2UgdC5iPWN9LAprczpmdW5jdGlvbigp
+e3RoaXMucj10aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9
+SC5MaChzKSxxPW5ldyBILmRiKHIuZC5iKGEpLHIuY2hbMV0uYihiKSkKaWYocy5lPT1udWxsKXMuZT1z
+LmY9cQplbHNle3Q9cy5mCnEuZD10CnMuZj10LmM9cX0rK3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpm
+dW5jdGlvbihhLGIpe3ZhciB0LHMKaWYoYT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7
+czx0OysrcylpZihKLlJNKGFbc10uYSxiKSlyZXR1cm4gcwpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7
+cmV0dXJuIFAubk8odGhpcyl9LApqMjpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gYVtiXX0sCkVJOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlv
+bihhLGIpe2RlbGV0ZSBhW2JdfSwKWHU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1u
+dWxsfSwKeks6ZnVuY3Rpb24oKXt2YXIgdD0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHM9T2JqZWN0LmNy
+ZWF0ZShudWxsKQp0aGlzLkVJKHMsdCxzKQp0aGlzLnJuKHMsdCkKcmV0dXJuIHN9LAokaUZvOjF9Ckgu
+ZGIucHJvdG90eXBlPXt9CkguaTUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+YS5hfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPW5ldyBILk42KHQsdC5yLHRoaXMuJHRp
+LkMoIk42PDE+IikpCnMuYz10LmUKcmV0dXJuIHN9fQpILk42LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9u
+KCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5hCmlmKHQuYiE9PXMu
+cil0aHJvdyBILmIoUC5hNChzKSkKZWxzZXtzPXQuYwppZihzPT1udWxsKXt0LnNxWShudWxsKQpyZXR1
+cm4hMX1lbHNle3Quc3FZKHMuYSkKdC5jPXQuYy5jCnJldHVybiEwfX19LApzcVk6ZnVuY3Rpb24oYSl7
+dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSC5kQy5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gdGhpcy5hKGEpfSwKJFM6NH0KSC53Ti5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
+LGIpe3JldHVybiB0aGlzLmEoYSxiKX0sCiRTOjQwfQpILlZYLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
+KGEpe3JldHVybiB0aGlzLmEoSC55KGEpKX0sCiRTOjMwfQpILlZSLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIlJlZ0V4cC8iK3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1bmN0aW9u
+KCl7dmFyIHQ9dGhpcyxzPXQuYwppZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0LmM9SC52
+NCh0LmEscy5tdWx0aWxpbmUsIXMuaWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITApfSwKZGQ6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzPXRoaXMuZ0hjKCkKcy5sYXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxsKXJldHVy
+bgpyZXR1cm4gbmV3IEguRUsodCl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90b3R5cGU9ewpxOmZ1
+bmN0aW9uKGEsYil7dmFyIHQKSC5TYyhiKQp0PXRoaXMuYgppZihiPj10Lmxlbmd0aClyZXR1cm4gSC5P
+SCh0LGIpCnJldHVybiB0W2JdfSwKJGlPZDoxLAokaWliOjF9CkguS1cucHJvdG90eXBlPXsKZ2t6OmZ1
+bmN0aW9uKGEpe3JldHVybiBuZXcgSC5QYih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlBiLnByb3Rv
+dHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHIs
+cSxwPXRoaXMsbz1wLmIKaWYobz09bnVsbClyZXR1cm4hMQp0PXAuYwppZih0PD1vLmxlbmd0aCl7cz1w
+LmEKcj1zLlVaKG8sdCkKaWYociE9bnVsbCl7cC5kPXIKbz1yLmIKdD1vLmluZGV4CnE9dCtvWzBdLmxl
+bmd0aAppZih0PT09cSl7aWYocy5iLnVuaWNvZGUpe289cC5jCnQ9bysxCnM9cC5iCmlmKHQ8cy5sZW5n
+dGgpe289Si5yWShzKS5tKHMsbykKaWYobz49NTUyOTYmJm88PTU2MzE5KXtvPUMueEIubShzLHQpCm89
+bz49NTYzMjAmJm88PTU3MzQzfWVsc2Ugbz0hMX1lbHNlIG89ITF9ZWxzZSBvPSExCnE9KG8/cSsxOnEp
+KzF9cC5jPXEKcmV0dXJuITB9fXAuYj1wLmQ9bnVsbApyZXR1cm4hMX0sCiRpQW46MX0KSC50US5wcm90
+b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiIT09MClILnZoKFAueChiLG51bGwpKQpy
+ZXR1cm4gdGhpcy5jfSwKJGlPZDoxfQpILnVuLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1
+cm4gbmV3IEguU2QodGhpcy5hLHRoaXMuYix0aGlzLmMpfX0KSC5TZC5wcm90b3R5cGU9ewpGOmZ1bmN0
+aW9uKCl7dmFyIHQscyxyPXRoaXMscT1yLmMscD1yLmIsbz1wLmxlbmd0aCxuPXIuYSxtPW4ubGVuZ3Ro
+CmlmKHErbz5tKXtyLmQ9bnVsbApyZXR1cm4hMX10PW4uaW5kZXhPZihwLHEpCmlmKHQ8MCl7ci5jPW0r
+MQpyLmQ9bnVsbApyZXR1cm4hMX1zPXQrbwpyLmQ9bmV3IEgudFEodCxwKQpyLmM9cz09PXIuYz9zKzE6
+cwpyZXR1cm4hMH0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCiRpQW46MX0KSC5FVC5wcm90
+b3R5cGU9eyRpRVQ6MSwkaUFTOjF9CkguYjAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGEubGVuZ3RofSwKJGlYajoxfQpILkRnLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIp
+Ckgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0guSWcoYykK
+SC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpY1g6MSwKJGl6TToxfQpILlBnLnByb3RvdHlwZT17
+Clk6ZnVuY3Rpb24oYSxiLGMpe0guU2MoYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpY1g6
+MSwKJGl6TToxfQpILnhqLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixh
+LGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZEUucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gu
+U2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5aQS5wcm90b3R5cGU9ewpxOmZ1
+bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILndmLnBy
+b3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4g
+YVtiXX19CkguUHEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5s
+ZW5ndGgpCnJldHVybiBhW2JdfX0KSC5lRS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4g
+YS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJu
+IGFbYl19fQpILlY2LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6
+ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sCiRpVjY6
+MSwKJGluNjoxfQpILlJHLnByb3RvdHlwZT17fQpILlZQLnByb3RvdHlwZT17fQpILldCLnByb3RvdHlw
+ZT17fQpILlpHLnByb3RvdHlwZT17fQpILkpjLnByb3RvdHlwZT17CkM6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEguY0Uodi50eXBlVW5pdmVyc2UsdGhpcyxhKX0sCktxOmZ1bmN0aW9uKGEpe3JldHVybiBILnY1KHYu
+dHlwZVVuaXZlcnNlLHRoaXMsYSl9fQpILkcucHJvdG90eXBlPXt9CkgudTkucHJvdG90eXBlPXsKdzpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfX0KSC5oei5wcm90b3R5cGU9e30KSC5pTS5wcm90b3R5cGU9
+e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz10LmEKdC5hPW51
+bGwKcy4kMCgpfSwKJFM6MTJ9ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp0
+aGlzLmEuYT11Lk0uYihhKQp0PXRoaXMuYgpzPXRoaXMuYwp0LmZpcnN0Q2hpbGQ/dC5yZW1vdmVDaGls
+ZChzKTp0LmFwcGVuZENoaWxkKHMpfSwKJFM6NDF9ClAuVnMucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24o
+KXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuRnQucHJvdG90eXBlPXsKJDA6ZnVu
+Y3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuVzMucHJvdG90eXBlPXsK
+Q1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVvdXQhPW51bGwpc2VsZi5zZXRUaW1lb3V0KEgu
+dFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRocm93IEguYihQLkw0KCJgc2V0VGltZW91dCgp
+YCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYi4kMCgp
+fSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0KUC5QZi5wcm90b3R5cGU9ewp3MDpmdW5jdGlvbihhLGIpe3Zh
+ciB0CmlmKGE9PW51bGwpYT1uZXcgUC5uKCkKdD10aGlzLmEKaWYodC5hIT09MCl0aHJvdyBILmIoUC5Q
+VigiRnV0dXJlIGFscmVhZHkgY29tcGxldGVkIikpCnQuTmsoYSxiKX0sCnBtOmZ1bmN0aW9uKGEpe3Jl
+dHVybiB0aGlzLncwKGEsbnVsbCl9fQpQLlpmLnByb3RvdHlwZT17fQpQLkZlLnByb3RvdHlwZT17CkhS
+OmZ1bmN0aW9uKGEpe2lmKCh0aGlzLmMmMTUpIT09NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYo
+dS5hbC5iKHRoaXMuZCksYS5hLHUuY0osdS5LKX0sCkt3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZSxz
+PXUueixyPXUuSyxxPXRoaXMuJHRpLkMoIjIvIikscD10aGlzLmIuYgppZih1LlcuYyh0KSlyZXR1cm4g
+cS5iKHAucnAodCxhLmEsYS5iLHMscix1LmwpKQplbHNlIHJldHVybiBxLmIocC5idih1LnkuYih0KSxh
+LmEscyxyKSl9fQpQLnZzLnByb3RvdHlwZT17ClNxOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT10
+aGlzLiR0aQpxLktxKGMpLkMoIjEvKDIpIikuYihhKQp0PSQuWDMKaWYodCE9PUMuTlUpe2MuQygiQDww
+Lz4iKS5LcShxLmQpLkMoIjEoMikiKS5iKGEpCmlmKGIhPW51bGwpYj1QLlZIKGIsdCl9cz1uZXcgUC52
+cygkLlgzLGMuQygidnM8MD4iKSkKcj1iPT1udWxsPzE6Mwp0aGlzLnhmKG5ldyBQLkZlKHMscixhLGIs
+cS5DKCJAPDE+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHN9LApXNzpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLlNxKGEsbnVsbCxiKX0sCk9BOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LmJmLmIo
+bnVsbCkKdD10aGlzLiR0aQpzPSQuWDMKcj1uZXcgUC52cyhzLHQpCmlmKHMhPT1DLk5VKWE9UC5WSChh
+LHMpCnRoaXMueGYobmV3IFAuRmUociwyLG51bGwsYSx0LkMoIkA8MT4iKS5LcSh0LmQpLkMoIkZlPDEs
+Mj4iKSkpCnJldHVybiByfSwKeGY6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9cy5hCmlmKHI8PTEp
+e2EuYT11LnguYihzLmMpCnMuYz1hfWVsc2V7aWYocj09PTIpe3Q9dS5fLmIocy5jKQpyPXQuYQppZihy
+PDQpe3QueGYoYSkKcmV0dXJufXMuYT1yCnMuYz10LmN9UC5UayhudWxsLG51bGwscy5iLHUuTS5iKG5l
+dyBQLmRhKHMsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG89dGhpcyxuPXt9Cm4u
+YT1hCmlmKGE9PW51bGwpcmV0dXJuCnQ9by5hCmlmKHQ8PTEpe3M9dS54LmIoby5jKQpyPW8uYz1hCmlm
+KHMhPW51bGwpe2Zvcig7cT1yLmEscSE9bnVsbDtyPXEpO3IuYT1zfX1lbHNle2lmKHQ9PT0yKXtwPXUu
+Xy5iKG8uYykKdD1wLmEKaWYodDw0KXtwLmpRKGEpCnJldHVybn1vLmE9dApvLmM9cC5jfW4uYT1vLk44
+KGEpClAuVGsobnVsbCxudWxsLG8uYix1Lk0uYihuZXcgUC5vUShuLG8pKSl9fSwKYWg6ZnVuY3Rpb24o
+KXt2YXIgdD11LnguYih0aGlzLmMpCnRoaXMuYz1udWxsCnJldHVybiB0aGlzLk44KHQpfSwKTjg6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEscz1udWxsO3QhPW51bGw7cz10LHQ9cil7cj10LmEKdC5h
+PXN9cmV0dXJuIHN9LApISDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMscj1zLiR0aQpyLkMoIjEvIiku
+YihhKQppZihyLkMoImI4PDE+IikuYyhhKSlpZihyLmMoYSkpUC5BOShhLHMpCmVsc2UgUC5rMyhhLHMp
+CmVsc2V7dD1zLmFoKCkKci5kLmIoYSkKcy5hPTQKcy5jPWEKUC5IWihzLHQpfX0sClpMOmZ1bmN0aW9u
+KGEsYil7dmFyIHQscz10aGlzCnUubC5iKGIpCnQ9cy5haCgpCnMuYT04CnMuYz1uZXcgUC5DdyhhLGIp
+ClAuSFoocyx0KX0sClhmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LiR0aQpzLkMoIjEvIikuYihh
+KQppZihzLkMoImI4PDE+IikuYyhhKSl7dC5jVShhKQpyZXR1cm59dC5hPTEKUC5UayhudWxsLG51bGws
+dC5iLHUuTS5iKG5ldyBQLnJIKHQsYSkpKX0sCmNVOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LiR0
+aQpzLkMoImI4PDE+IikuYihhKQppZihzLmMoYSkpe2lmKGEuZ0FUKCkpe3QuYT0xClAuVGsobnVsbCxu
+dWxsLHQuYix1Lk0uYihuZXcgUC5LRih0LGEpKSl9ZWxzZSBQLkE5KGEsdCkKcmV0dXJufVAuazMoYSx0
+KX0sCk5rOmZ1bmN0aW9uKGEsYil7dGhpcy5hPTEKUC5UayhudWxsLG51bGwsdGhpcy5iLHUuTS5iKG5l
+dyBQLlpMKHRoaXMsYSxiKSkpfSwKJGliODoxfQpQLmRhLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
+UC5IWih0aGlzLmEsdGhpcy5iKX0sCiRTOjB9ClAub1EucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQ
+LkhaKHRoaXMuYix0aGlzLmEuYSl9LAokUzowfQpQLnBWLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3ZhciB0PXRoaXMuYQp0LmE9MAp0LkhIKGEpfSwKJFM6MTJ9ClAuVTcucHJvdG90eXBlPXsKJDI6ZnVu
+Y3Rpb24oYSxiKXt1LmwuYihiKQp0aGlzLmEuWkwoYSxiKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0
+aGlzLiQyKGEsbnVsbCl9LAokQzoiJDIiLAokRDpmdW5jdGlvbigpe3JldHVybltudWxsXX0sCiRTOjM1
+fQpQLnZyLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwK
+JFM6MH0KUC5ySC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYSxzPXQuJHRpLmQu
+Yih0aGlzLmIpLHI9dC5haCgpCnQuYT00CnQuYz1zClAuSFoodCxyKX0sCiRTOjB9ClAuS0YucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5
+cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJv
+dG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLG09bnVsbAp0cnl7cj1u
+LmMKbT1yLmIuYi56eih1LmZPLmIoci5kKSx1LnopfWNhdGNoKHEpe3Q9SC5SdShxKQpzPUgudHMocSkK
+aWYobi5kKXtyPXUubi5iKG4uYS5hLmMpLmEKcD10CnA9cj09bnVsbD9wPT1udWxsOnI9PT1wCnI9cH1l
+bHNlIHI9ITEKcD1uLmIKaWYocilwLmI9dS5uLmIobi5hLmEuYykKZWxzZSBwLmI9bmV3IFAuQ3codCxz
+KQpwLmE9ITAKcmV0dXJufWlmKHUuYy5jKG0pKXtpZihtIGluc3RhbmNlb2YgUC52cyYmbS5hPj00KXtp
+ZihtLmE9PT04KXtyPW4uYgpyLmI9dS5uLmIobS5jKQpyLmE9ITB9cmV0dXJufW89bi5hLmEKcj1uLmIK
+ci5iPW0uVzcobmV3IFAualoobyksdS56KQpyLmE9ITF9fSwKJFM6Mn0KUC5qWi5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJFM6MzR9ClAucnEucHJvdG90eXBlPXsKJDA6ZnVu
+Y3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMKdHJ5e3I9bS5iCnE9ci4kdGkKcD1xLmQKbz1w
+LmIobS5jKQptLmEuYj1yLmIuYi5idihxLkMoIjIvKDEpIikuYihyLmQpLG8scS5DKCIyLyIpLHApfWNh
+dGNoKG4pe3Q9SC5SdShuKQpzPUgudHMobikKcj1tLmEKci5iPW5ldyBQLkN3KHQscykKci5hPSEwfX0s
+CiRTOjJ9ClAuUlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9
+dGhpcwp0cnl7dD11Lm4uYihsLmEuYS5jKQpxPWwuYwppZihILm9UKHEuSFIodCkpJiZxLmUhPW51bGwp
+e3A9bC5iCnAuYj1xLkt3KHQpCnAuYT0hMX19Y2F0Y2gobyl7cz1ILlJ1KG8pCnI9SC50cyhvKQpxPXUu
+bi5iKGwuYS5hLmMpCnA9cS5hCm49cwptPWwuYgppZihwPT1udWxsP249PW51bGw6cD09PW4pbS5iPXEK
+ZWxzZSBtLmI9bmV3IFAuQ3cocyxyKQptLmE9ITB9fSwKJFM6Mn0KUC5PTS5wcm90b3R5cGU9e30KUC5x
+aC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcyxxPXt9LHA9bmV3IFAudnMo
+JC5YMyx1LmZKKQpxLmE9MAp0PUguTGgocikKcz10LkMoIn4oMSkiKS5iKG5ldyBQLkI1KHEscikpCnUu
+TS5iKG5ldyBQLlBJKHEscCkpClcuSkUoci5hLHIuYixzLCExLHQuZCkKcmV0dXJuIHB9fQpQLkI1LnBy
+b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe0guTGgodGhpcy5iKS5kLmIoYSk7Kyt0aGlzLmEuYX0sCiRT
+OmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5iKS5DKCJjOCgxKSIpfX0KUC5QSS5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYi5ISCh0aGlzLmEuYSl9LAokUzowfQpQLk1PLnByb3RvdHlwZT17
+fQpQLmtULnByb3RvdHlwZT17fQpQLkN3LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIEgu
+ZCh0aGlzLmEpfSwKJGlYUzoxfQpQLm0wLnByb3RvdHlwZT17JGlKQjoxfQpQLnBLLnByb3RvdHlwZT17
+CiQwOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLmEscj1zLmEKcz1yPT1udWxsP3MuYT1uZXcgUC5uKCk6
+cgpyPXRoaXMuYgppZihyPT1udWxsKXRocm93IEguYihzKQp0PUguYihzKQp0LnN0YWNrPXIudygwKQp0
+aHJvdyB0fSwKJFM6MH0KUC5KaS5wcm90b3R5cGU9ewpiSDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1u
+dWxsCnUuTS5iKGEpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMCgpCnJldHVybn1QLlQ4KHEscSx0aGlz
+LGEsdS5IKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIocSxxLHRoaXMsdCx1LmwuYihz
+KSl9fSwKRGw6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPW51bGwKYy5DKCJ+KDApIikuYihhKQpj
+LmIoYikKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQxKGIpCnJldHVybn1QLnl2KHEscSx0aGlzLGEsYix1
+LkgsYyl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQLkwyKHEscSx0aGlzLHQsdS5sLmIocykp
+fX0sClJUOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmhqKHRoaXMsYi5DKCIwKCkiKS5iKGEpLGIp
+fSwKR1k6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlZwKHRoaXMsdS5NLmIoYSkpfSwKUHk6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gbmV3IFAuT1IodGhpcyxiLkMoIn4oMCkiKS5iKGEpLGIpfSwKcTpmdW5jdGlv
+bihhLGIpe3JldHVybn0sCnp6OmZ1bmN0aW9uKGEsYil7Yi5DKCIwKCkiKS5iKGEpCmlmKCQuWDM9PT1D
+Lk5VKXJldHVybiBhLiQwKCkKcmV0dXJuIFAuVDgobnVsbCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0
+aW9uKGEsYixjLGQpe2MuQygiQDwwPiIpLktxKGQpLkMoIjEoMikiKS5iKGEpCmQuYihiKQppZigkLlgz
+PT09Qy5OVSlyZXR1cm4gYS4kMShiKQpyZXR1cm4gUC55dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0s
+CnJwOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXtkLkMoIkA8MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMyki
+KS5iKGEpCmUuYihiKQpmLmIoYykKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4g
+UC5ReChudWxsLG51bGwsdGhpcyxhLGIsYyxkLGUsZil9fQpQLmhqLnByb3RvdHlwZT17CiQwOmZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuYS56eih0aGlzLmIsdGhpcy5jKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJu
+IHRoaXMuYy5DKCIwKCkiKX19ClAuVnAucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
+cy5hLmJIKHRoaXMuYil9LAokUzoyfQpQLk9SLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0
+PXRoaXMuYwpyZXR1cm4gdGhpcy5hLkRsKHRoaXMuYix0LmIoYSksdCl9LAokUzpmdW5jdGlvbigpe3Jl
+dHVybiB0aGlzLmMuQygifigwKSIpfX0KUC5iNi5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFy
+IHQ9dGhpcyxzPW5ldyBQLmxtKHQsdC5yLEguTGgodCkuQygibG08MT4iKSkKcy5jPXQuZQpyZXR1cm4g
+c30sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAp0ZzpmdW5jdGlvbihhLGIpe3ZhciB0LHMK
+aWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3Q9dGhpcy5iCmlmKHQ9PW51bGwp
+cmV0dXJuITEKcmV0dXJuIHUuSi5iKHRbYl0pIT1udWxsfWVsc2V7cz10aGlzLlBSKGIpCnJldHVybiBz
+fX0sClBSOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZAppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0
+aGlzLkRGKHRbdGhpcy5OKGEpXSxhKT49MH0sCmk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpI
+LkxoKHIpLmQuYihiKQppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19wcm90b19fIil7dD1yLmIK
+cmV0dXJuIHIuYlEodD09bnVsbD9yLmI9UC5UMigpOnQsYil9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJl
+ciImJihiJjEwNzM3NDE4MjMpPT09Yil7cz1yLmMKcmV0dXJuIHIuYlEocz09bnVsbD9yLmM9UC5UMigp
+OnMsYil9ZWxzZSByZXR1cm4gci5CNyhiKX0sCkI3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMK
+SC5MaChxKS5kLmIoYSkKdD1xLmQKaWYodD09bnVsbCl0PXEuZD1QLlQyKCkKcz1xLk4oYSkKcj10W3Nd
+CmlmKHI9PW51bGwpdFtzXT1bcS55byhhKV0KZWxzZXtpZihxLkRGKHIsYSk+PTApcmV0dXJuITEKci5w
+dXNoKHEueW8oYSkpfXJldHVybiEwfSwKUjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKaWYodHlwZW9m
+IGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpcmV0dXJuIHQuTCh0LmIsYikKZWxzZSBpZih0eXBl
+b2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09YilyZXR1cm4gdC5MKHQuYyxiKQplbHNlIHJl
+dHVybiB0LnFnKGIpfSwKcWc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD10aGlzLG89cC5kCmlmKG89
+PW51bGwpcmV0dXJuITEKdD1wLk4oYSkKcz1vW3RdCnI9cC5ERihzLGEpCmlmKHI8MClyZXR1cm4hMQpx
+PXMuc3BsaWNlKHIsMSlbMF0KaWYoMD09PXMubGVuZ3RoKWRlbGV0ZSBvW3RdCnAuR1MocSkKcmV0dXJu
+ITB9LApiUTpmdW5jdGlvbihhLGIpe0guTGgodGhpcykuZC5iKGIpCmlmKHUuSi5iKGFbYl0pIT1udWxs
+KXJldHVybiExCmFbYl09dGhpcy55byhiKQpyZXR1cm4hMH0sCkw6ZnVuY3Rpb24oYSxiKXt2YXIgdApp
+ZihhPT1udWxsKXJldHVybiExCnQ9dS5KLmIoYVtiXSkKaWYodD09bnVsbClyZXR1cm4hMQp0aGlzLkdT
+KHQpCmRlbGV0ZSBhW2JdCnJldHVybiEwfSwKUzpmdW5jdGlvbigpe3RoaXMucj0xMDczNzQxODIzJnRo
+aXMucisxfSwKeW86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9bmV3IFAuYm4oSC5MaChzKS5kLmIo
+YSkpCmlmKHMuZT09bnVsbClzLmU9cy5mPXIKZWxzZXt0PXMuZgpyLmM9dApzLmY9dC5iPXJ9KytzLmEK
+cy5TKCkKcmV0dXJuIHJ9LApHUzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9YS5jLHI9YS5iCmlmKHM9
+PW51bGwpdC5lPXIKZWxzZSBzLmI9cgppZihyPT1udWxsKXQuZj1zCmVsc2Ugci5jPXM7LS10LmEKdC5T
+KCl9LApOOmZ1bmN0aW9uKGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4MjN9LApERjpmdW5jdGlvbihh
+LGIpe3ZhciB0LHMKaWYoYT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0Oysrcylp
+ZihKLlJNKGFbc10uYSxiKSlyZXR1cm4gcwpyZXR1cm4tMX19ClAuYm4ucHJvdG90eXBlPXt9ClAubG0u
+cHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0
+PXRoaXMscz10LmEKaWYodC5iIT09cy5yKXRocm93IEguYihQLmE0KHMpKQplbHNle3M9dC5jCmlmKHM9
+PW51bGwpe3Quc2oobnVsbCkKcmV0dXJuITF9ZWxzZXt0LnNqKHQuJHRpLmQuYihzLmEpKQp0LmM9dC5j
+LmIKcmV0dXJuITB9fX0sCnNqOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5kLmIoYSl9LAokaUFu
+OjF9ClAubVcucHJvdG90eXBlPXt9ClAuTFUucHJvdG90eXBlPXskaWNYOjEsJGl6TToxfQpQLmxELnBy
+b3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEguekso
+YSkuQygiYTc8bEQuRT4iKSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucShhLGIpfSwKSzpm
+dW5jdGlvbihhLGIpe3ZhciB0LHMKSC56SyhhKS5DKCJ+KGxELkUpIikuYihiKQp0PXRoaXMuZ0EoYSkK
+Zm9yKHM9MDtzPHQ7KytzKXtiLiQxKHRoaXMucShhLHMpKQppZih0IT09dGhpcy5nQShhKSl0aHJvdyBI
+LmIoUC5hNChhKSl9fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgueksoYSkKcmV0dXJuIG5ldyBI
+LkE4KGEsdC5LcShjKS5DKCIxKGxELkUpIikuYihiKSx0LkMoIkA8bEQuRT4iKS5LcShjKS5DKCJBODwx
+LDI+IikpfSwKZHU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKSC56SyhhKS5DKCJsRC5FIikuYihkKQpQ
+LmpCKGIsYyx0aGlzLmdBKGEpKQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxkKX0sCnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAuR0EucHJvdG90
+eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRoaXMuYi5hKz0iLCAi
+CnMuYT0hMQpzPXRoaXMuYgp0PXMuYSs9SC5kKGEpCnMuYT10KyI6ICIKcy5hKz1ILmQoYil9LAokUzox
+fQpQLllrLnByb3RvdHlwZT17Cks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkguTGgodGhpcykuQygifihZ
+ay5LLFlrLlYpIikuYihiKQpmb3IodD1KLklUKHRoaXMuZ1YoKSk7dC5GKCk7KXtzPXQuZ2woKQpiLiQy
+KHMsdGhpcy5xKDAscykpfX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMuZ1YoKSl9LAp3
+OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKJGlaMDoxfQpQLktQLnByb3RvdHlwZT17Clk6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdC5kLmIoYikKdC5jaFsxXS5iKGMpCnRocm93
+IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5IHVubW9kaWZpYWJsZSBtYXAiKSl9fQpQLlBuLnByb3RvdHlw
+ZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLnEoMCxiKX0sClk6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0PUguTGgodGhpcykKdGhpcy5hLlkoMCx0LmQuYihiKSx0LmNoWzFdLmIoYykpfSwKSzpmdW5j
+dGlvbihhLGIpe3RoaXMuYS5LKDAsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5iKGIpKX0sCmdBOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nQSh0KX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+aih0aGlzLmEpfSwKJGlaMDoxfQpQLkdqLnByb3RvdHlwZT17fQpQLmxmLnByb3RvdHlwZT17Cnc6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0iKX19ClAuVmoucHJvdG90eXBlPXskaWNYOjEs
+JGl4dToxfQpQLlh2LnByb3RvdHlwZT17CkZWOmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9Si5JVChI
+LkxoKHRoaXMpLkMoImNYPDE+IikuYihiKSk7dC5GKCk7KXRoaXMuaSgwLHQuZ2woKSl9LAp3OmZ1bmN0
+aW9uKGEpe3JldHVybiBQLldFKHRoaXMsInsiLCJ9Iil9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1Q
+LnJqKHRoaXMsdGhpcy5yLEguTGgodGhpcykuZCkKaWYoIXMuRigpKXJldHVybiIiCmlmKGI9PT0iIil7
+dD0iIgpkbyB0Kz1ILmQocy5kKQp3aGlsZShzLkYoKSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5GKCk7
+KXQ9dCtiK0guZChzLmQpfXJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGljWDoxLAokaXh1
+OjF9ClAublkucHJvdG90eXBlPXt9ClAuV1kucHJvdG90eXBlPXt9ClAuUlUucHJvdG90eXBlPXt9ClAu
+dXcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5iCmlmKHM9PW51bGwpcmV0
+dXJuIHRoaXMuYy5xKDAsYikKZWxzZSBpZih0eXBlb2YgYiE9InN0cmluZyIpcmV0dXJuCmVsc2V7dD1z
+W2JdCnJldHVybiB0eXBlb2YgdD09InVuZGVmaW5lZCI/dGhpcy5mYihiKTp0fX0sCmdBOmZ1bmN0aW9u
+KGEpe3JldHVybiB0aGlzLmI9PW51bGw/dGhpcy5jLmE6dGhpcy5DZigpLmxlbmd0aH0sCmdWOmZ1bmN0
+aW9uKCl7aWYodGhpcy5iPT1udWxsKXt2YXIgdD10aGlzLmMKcmV0dXJuIG5ldyBILmk1KHQsSC5MaCh0
+KS5DKCJpNTwxPiIpKX1yZXR1cm4gbmV3IFAuaTgodGhpcyl9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dCxzLHI9dGhpcwppZihyLmI9PW51bGwpci5jLlkoMCxiLGMpCmVsc2UgaWYoci54NChiKSl7dD1yLmIK
+dFtiXT1jCnM9ci5hCmlmKHM9PW51bGw/dCE9bnVsbDpzIT09dClzW2JdPW51bGx9ZWxzZSByLlhLKCku
+WSgwLGIsYyl9LAp4NDpmdW5jdGlvbihhKXtpZih0aGlzLmI9PW51bGwpcmV0dXJuIHRoaXMuYy54NChh
+KQpyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuYSxhKX0sCks6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMKdS5jQS5iKGIpCmlmKHAuYj09bnVsbClyZXR1
+cm4gcC5jLksoMCxiKQp0PXAuQ2YoKQpmb3Iocz0wO3M8dC5sZW5ndGg7KytzKXtyPXRbc10KcT1wLmJb
+cl0KaWYodHlwZW9mIHE9PSJ1bmRlZmluZWQiKXtxPVAuUWUocC5hW3JdKQpwLmJbcl09cX1iLiQyKHIs
+cSkKaWYodCE9PXAuYyl0aHJvdyBILmIoUC5hNChwKSl9fSwKQ2Y6ZnVuY3Rpb24oKXt2YXIgdD11Lmou
+Yih0aGlzLmMpCmlmKHQ9PW51bGwpdD10aGlzLmM9SC5WTShPYmplY3Qua2V5cyh0aGlzLmEpLHUucykK
+cmV0dXJuIHR9LApYSzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbz10aGlzCmlmKG8uYj09bnVsbCly
+ZXR1cm4gby5jCnQ9UC5GbCh1Lk4sdS56KQpzPW8uQ2YoKQpmb3Iocj0wO3E9cy5sZW5ndGgscjxxOysr
+cil7cD1zW3JdCnQuWSgwLHAsby5xKDAscCkpfWlmKHE9PT0wKUMuTm0uaShzLG51bGwpCmVsc2UgQy5O
+bS5zQShzLDApCm8uYT1vLmI9bnVsbApyZXR1cm4gby5jPXR9LApmYjpmdW5jdGlvbihhKXt2YXIgdApp
+ZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuYSxhKSlyZXR1cm4KdD1Q
+LlFlKHRoaXMuYVthXSkKcmV0dXJuIHRoaXMuYlthXT10fX0KUC5pOC5wcm90b3R5cGU9ewpnQTpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQ9
+dGhpcy5hCmlmKHQuYj09bnVsbCl0PXQuZ1YoKS5FKDAsYikKZWxzZXt0PXQuQ2YoKQppZihiPDB8fGI+
+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsYikKdD10W2JdfXJldHVybiB0fSwKZ2t6OmZ1bmN0aW9uKGEp
+e3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpe3Q9dC5nVigpCnQ9dC5na3oodCl9ZWxzZXt0PXQuQ2Yo
+KQp0PW5ldyBKLm0xKHQsdC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX1yZXR1cm4gdH19ClAuQ1Yu
+cHJvdG90eXBlPXsKeXI6ZnVuY3Rpb24oYSxhMCxhMSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixp
+LGgsZyxmLGUsZCxjLGI9IkludmFsaWQgYmFzZTY0IGVuY29kaW5nIGxlbmd0aCAiCmExPVAuakIoYTAs
+YTEsYS5sZW5ndGgpCnQ9JC5WNygpCmZvcihzPWEwLHI9cyxxPW51bGwscD0tMSxvPS0xLG49MDtzPGEx
+O3M9bSl7bT1zKzEKbD1DLnhCLlcoYSxzKQppZihsPT09Mzcpe2s9bSsyCmlmKGs8PWExKXtqPUgub28o
+Qy54Qi5XKGEsbSkpCmk9SC5vbyhDLnhCLlcoYSxtKzEpKQpoPWoqMTYraS0oaSYyNTYpCmlmKGg9PT0z
+NyloPS0xCm09a31lbHNlIGg9LTF9ZWxzZSBoPWwKaWYoMDw9aCYmaDw9MTI3KXtpZihoPDB8fGg+PXQu
+bGVuZ3RoKXJldHVybiBILk9IKHQsaCkKZz10W2hdCmlmKGc+PTApe2g9Qy54Qi5tKCJBQkNERUZHSElK
+S0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvIixnKQpp
+ZihoPT09bCljb250aW51ZQpsPWh9ZWxzZXtpZihnPT09LTEpe2lmKHA8MCl7Zj1xPT1udWxsP251bGw6
+cS5hLmxlbmd0aAppZihmPT1udWxsKWY9MApwPWYrKHMtcikKbz1zfSsrbgppZihsPT09NjEpY29udGlu
+dWV9bD1ofWlmKGchPT0tMil7aWYocT09bnVsbClxPW5ldyBQLlJuKCIiKQpxLmErPUMueEIuTmooYSxy
+LHMpCnEuYSs9SC5MdyhsKQpyPW0KY29udGludWV9fXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2
+NCBkYXRhIixhLHMpKX1pZihxIT1udWxsKXtmPXEuYSs9Qy54Qi5OaihhLHIsYTEpCmU9Zi5sZW5ndGgK
+aWYocD49MClQLnhNKGEsbyxhMSxwLG4sZSkKZWxzZXtkPUMuam4uelkoZS0xLDQpKzEKaWYoZD09PTEp
+dGhyb3cgSC5iKFAucnIoYixhLGExKSkKZm9yKDtkPDQ7KXtmKz0iPSIKcS5hPWY7KytkfX1mPXEuYQpy
+ZXR1cm4gQy54Qi5pNyhhLGEwLGExLGYuY2hhckNvZGVBdCgwKT09MD9mOmYpfWM9YTEtYTAKaWYocD49
+MClQLnhNKGEsbyxhMSxwLG4sYykKZWxzZXtkPUMuam4uelkoYyw0KQppZihkPT09MSl0aHJvdyBILmIo
+UC5ycihiLGEsYTEpKQppZihkPjEpYT1DLnhCLmk3KGEsYTEsYTEsZD09PTI/Ij09IjoiPSIpfXJldHVy
+biBhfX0KUC5VOC5wcm90b3R5cGU9e30KUC5Vay5wcm90b3R5cGU9e30KUC53SS5wcm90b3R5cGU9e30K
+UC5aaS5wcm90b3R5cGU9e30KUC5ieS5wcm90b3R5cGU9ewpwVzpmdW5jdGlvbihhLGIsYyl7dmFyIHQK
+dS5lcC5iKGMpCnQ9UC5CUyhiLHRoaXMuZ0hlKCkuYSkKcmV0dXJuIHR9LApnSGU6ZnVuY3Rpb24oKXty
+ZXR1cm4gQy5BM319ClAuTXgucHJvdG90eXBlPXt9ClAudTUucHJvdG90eXBlPXsKZ1pFOmZ1bmN0aW9u
+KCl7cmV0dXJuIEMuUWt9fQpQLkUzLnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj1Q
+LmpCKDAsbnVsbCxhLmxlbmd0aCkscT1yLTAKaWYocT09PTApcmV0dXJuIG5ldyBVaW50OEFycmF5KDAp
+CnQ9bmV3IFVpbnQ4QXJyYXkocSozKQpzPW5ldyBQLlJ3KHQpCmlmKHMuR3goYSwwLHIpIT09cilzLk82
+KEouYTYoYSxyLTEpLDApCnJldHVybiBuZXcgVWludDhBcnJheSh0LnN1YmFycmF5KDAsSC5yTSgwLHMu
+Yix0Lmxlbmd0aCkpKX19ClAuUncucHJvdG90eXBlPXsKTzY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRo
+aXMscj1zLmMscT1zLmIscD1xKzEsbz1yLmxlbmd0aAppZigoYiY2NDUxMik9PT01NjMyMCl7dD02NTUz
+NisoKGEmMTAyMyk8PDEwKXxiJjEwMjMKcy5iPXAKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09
+MjQwfHQ+Pj4xOApxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHApCnJbcF09MTI4fHQ+Pj4x
+MiY2MwpwPXMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09MTI4fHQ+Pj42JjYzCnMu
+Yj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHApCnJbcF09MTI4fHQmNjMKcmV0dXJuITB9ZWxzZXtz
+LmI9cAppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0yMjR8YT4+PjEyCnE9cy5iPXArMQppZihw
+Pj1vKXJldHVybiBILk9IKHIscCkKcltwXT0xMjh8YT4+PjYmNjMKcy5iPXErMQppZihxPj1vKXJldHVy
+biBILk9IKHIscSkKcltxXT0xMjh8YSY2MwpyZXR1cm4hMX19LApHeDpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQscyxyLHEscCxvLG4sbT10aGlzCmlmKGIhPT1jJiYoQy54Qi5tKGEsYy0xKSY2NDUxMik9PT01NTI5
+NiktLWMKZm9yKHQ9bS5jLHM9dC5sZW5ndGgscj1iO3I8YzsrK3Ipe3E9Qy54Qi5XKGEscikKaWYocTw9
+MTI3KXtwPW0uYgppZihwPj1zKWJyZWFrCm0uYj1wKzEKdFtwXT1xfWVsc2UgaWYoKHEmNjQ1MTIpPT09
+NTUyOTYpe2lmKG0uYiszPj1zKWJyZWFrCm89cisxCmlmKG0uTzYocSxDLnhCLlcoYSxvKSkpcj1vfWVs
+c2UgaWYocTw9MjA0Nyl7cD1tLmIKbj1wKzEKaWYobj49cylicmVhawptLmI9bgppZihwPj1zKXJldHVy
+biBILk9IKHQscCkKdFtwXT0xOTJ8cT4+PjYKbS5iPW4rMQp0W25dPTEyOHxxJjYzfWVsc2V7cD1tLmIK
+aWYocCsyPj1zKWJyZWFrCm49bS5iPXArMQppZihwPj1zKXJldHVybiBILk9IKHQscCkKdFtwXT0yMjR8
+cT4+PjEyCnA9bS5iPW4rMQppZihuPj1zKXJldHVybiBILk9IKHQsbikKdFtuXT0xMjh8cT4+PjYmNjMK
+bS5iPXArMQppZihwPj1zKXJldHVybiBILk9IKHQscCkKdFtwXT0xMjh8cSY2M319cmV0dXJuIHJ9fQpQ
+LkdZLnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbAp1LkwuYihh
+KQp0PVAua3koITEsYSwwLG51bGwpCmlmKHQhPW51bGwpcmV0dXJuIHQKcz1QLmpCKDAsbnVsbCxKLkht
+KGEpKQpyPVAud0coYSwwLHMpCmlmKHI+MCl7cT1QLkhNKGEsMCxyKQppZihyPT09cylyZXR1cm4gcQpw
+PW5ldyBQLlJuKHEpCm89cgpuPSExfWVsc2V7bz0wCnA9bnVsbApuPSEwfWlmKHA9PW51bGwpcD1uZXcg
+UC5SbigiIikKbT1uZXcgUC5ieighMSxwKQptLmM9bgptLk1FKGEsbyxzKQppZihtLmU+MCl7SC52aChQ
+LnJyKCJVbmZpbmlzaGVkIFVURi04IG9jdGV0IHNlcXVlbmNlIixhLHMpKQpwLmErPUguTHcoNjU1MzMp
+Cm0uZj1tLmU9bS5kPTB9bD1wLmEKcmV0dXJuIGwuY2hhckNvZGVBdCgwKT09MD9sOmx9fQpQLmJ6LnBy
+b3RvdHlwZT17Ck1FOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaD10
+aGlzLGc9IkJhZCBVVEYtOCBlbmNvZGluZyAweCIKdS5MLmIoYSkKdD1oLmQKcz1oLmUKcj1oLmYKaC5m
+PWguZT1oLmQ9MAokbGFiZWwwJDA6Zm9yKHE9Si5VNihhKSxwPWguYixvPWI7ITA7bz1qKXskbGFiZWwx
+JDE6aWYocz4wKXtkb3tpZihvPT09YylicmVhayAkbGFiZWwwJDAKbj1xLnEoYSxvKQppZih0eXBlb2Yg
+biE9PSJudW1iZXIiKXJldHVybiBuLnpNKCkKaWYoKG4mMTkyKSE9PTEyOCl7bT1QLnJyKGcrQy5qbi5X
+WihuLDE2KSxhLG8pCnRocm93IEguYihtKX1lbHNle3Q9KHQ8PDZ8biY2Myk+Pj4wOy0tczsrK299fXdo
+aWxlKHM+MCkKbT1yLTEKaWYobTwwfHxtPj00KXJldHVybiBILk9IKEMuR2IsbSkKaWYodDw9Qy5HYltt
+XSl7bT1QLnJyKCJPdmVybG9uZyBlbmNvZGluZyBvZiAweCIrQy5qbi5XWih0LDE2KSxhLG8tci0xKQp0
+aHJvdyBILmIobSl9aWYodD4xMTE0MTExKXttPVAucnIoIkNoYXJhY3RlciBvdXRzaWRlIHZhbGlkIFVu
+aWNvZGUgcmFuZ2U6IDB4IitDLmpuLldaKHQsMTYpLGEsby1yLTEpCnRocm93IEguYihtKX1pZighaC5j
+fHx0IT09NjUyNzkpcC5hKz1ILkx3KHQpCmguYz0hMX1mb3IobT1vPGM7bTspe2w9UC53RyhhLG8sYykK
+aWYobD4wKXtoLmM9ITEKaz1vK2wKcC5hKz1QLkhNKGEsbyxrKQppZihrPT09YylicmVha31lbHNlIGs9
+bwpqPWsrMQpuPXEucShhLGspCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4uSigpCmlmKG48
+MCl7aT1QLnJyKCJOZWdhdGl2ZSBVVEYtOCBjb2RlIHVuaXQ6IC0weCIrQy5qbi5XWigtbiwxNiksYSxq
+LTEpCnRocm93IEguYihpKX1lbHNle2lmKChuJjIyNCk9PT0xOTIpe3Q9biYzMQpzPTEKcj0xCmNvbnRp
+bnVlICRsYWJlbDAkMH1pZigobiYyNDApPT09MjI0KXt0PW4mMTUKcz0yCnI9Mgpjb250aW51ZSAkbGFi
+ZWwwJDB9aWYoKG4mMjQ4KT09PTI0MCYmbjwyNDUpe3Q9biY3CnM9MwpyPTMKY29udGludWUgJGxhYmVs
+MCQwfWk9UC5ycihnK0Muam4uV1oobiwxNiksYSxqLTEpCnRocm93IEguYihpKX19YnJlYWsgJGxhYmVs
+MCQwfWlmKHM+MCl7aC5kPXQKaC5lPXMKaC5mPXJ9fX0KUC5XRi5wcm90b3R5cGU9ewokMjpmdW5jdGlv
+bihhLGIpe3ZhciB0LHMscgp1LmZvLmIoYSkKdD10aGlzLmIKcz10aGlzLmEKdC5hKz1zLmEKcj10LmEr
+PUguZChhLmEpCnQuYT1yKyI6ICIKdC5hKz1QLnAoYikKcy5hPSIsICJ9LAokUzoyN30KUC5hMi5wcm90
+b3R5cGU9e30KUC5pUC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJu
+ITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLmlQJiZ0aGlzLmE9PT1iLmEmJiEwfSwKZ2lPOmZ1bmN0aW9u
+KGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4odF5DLmpuLndHKHQsMzApKSYxMDczNzQxODIzfSwKdzpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzLHM9UC5HcShILnRKKHQpKSxyPVAuaDAoSC5OUyh0KSkscT1QLmgwKEgu
+akEodCkpLHA9UC5oMChILktMKHQpKSxvPVAuaDAoSC5jaCh0KSksbj1QLmgwKEguSmQodCkpLG09UC5W
+eChILm8xKHQpKSxsPXMrIi0iK3IrIi0iK3ErIiAiK3ArIjoiK28rIjoiK24rIi4iK20KcmV0dXJuIGx9
+fQpQLkNQLnByb3RvdHlwZT17fQpQLlhTLnByb3RvdHlwZT17fQpQLkM2LnByb3RvdHlwZT17Cnc6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQhPW51bGwpcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIr
+UC5wKHQpCnJldHVybiJBc3NlcnRpb24gZmFpbGVkIn19ClAubi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3JldHVybiJUaHJvdyBvZiBudWxsLiJ9fQpQLnUucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXty
+ZXR1cm4iSW52YWxpZCBhcmd1bWVudCIrKCF0aGlzLmE/IihzKSI6IiIpfSwKZ3U6ZnVuY3Rpb24oKXty
+ZXR1cm4iIn0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD10aGlzLG89cC5jLG49byE9bnVsbD8i
+ICgiK28rIikiOiIiCm89cC5kCnQ9bz09bnVsbD8iIjoiOiAiK0guZChvKQpzPXAuZ1ooKStuK3QKaWYo
+IXAuYSlyZXR1cm4gcwpyPXAuZ3UoKQpxPVAucChwLmIpCnJldHVybiBzK3IrIjogIitxfX0KUC5iSi5w
+cm90b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7
+dmFyIHQscyxyPXRoaXMuZQppZihyPT1udWxsKXtyPXRoaXMuZgp0PXIhPW51bGw/IjogTm90IGxlc3Mg
+dGhhbiBvciBlcXVhbCB0byAiK0guZChyKToiIn1lbHNle3M9dGhpcy5mCmlmKHM9PW51bGwpdD0iOiBO
+b3QgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICIrSC5kKHIpCmVsc2UgaWYocz5yKXQ9IjogTm90IGlu
+IHJhbmdlICIrSC5kKHIpKyIuLiIrSC5kKHMpKyIsIGluY2x1c2l2ZSIKZWxzZSB0PXM8cj8iOiBWYWxp
+ZCB2YWx1ZSByYW5nZSBpcyBlbXB0eSI6IjogT25seSB2YWxpZCB2YWx1ZSBpcyAiK0guZChyKX1yZXR1
+cm4gdH19ClAuZVkucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApn
+dTpmdW5jdGlvbigpe3ZhciB0LHM9SC5TYyh0aGlzLmIpCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0
+dXJuIHMuSigpCmlmKHM8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSIKdD10aGlz
+LmYKaWYodD09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVybiI6IGluZGV4IHNo
+b3VsZCBiZSBsZXNzIHRoYW4gIitILmQodCl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5mfX0K
+UC5tcC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzLGs9
+e30saj1uZXcgUC5SbigiIikKay5hPSIiCmZvcih0PWwuYyxzPXQubGVuZ3RoLHI9MCxxPSIiLHA9IiI7
+cjxzOysrcixwPSIsICIpe289dFtyXQpqLmE9cStwCnE9ai5hKz1QLnAobykKay5hPSIsICJ9bC5kLkso
+MCxuZXcgUC5XRihrLGopKQpuPVAucChsLmEpCm09ai53KDApCnQ9Ik5vU3VjaE1ldGhvZEVycm9yOiBt
+ZXRob2Qgbm90IGZvdW5kOiAnIitILmQobC5iLmEpKyInXG5SZWNlaXZlcjogIituKyJcbkFyZ3VtZW50
+czogWyIrbSsiXSIKcmV0dXJuIHR9fQpQLnViLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IlVuc3VwcG9ydGVkIG9wZXJhdGlvbjogIit0aGlzLmF9fQpQLmRzLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0IT1udWxsPyJVbmltcGxlbWVudGVkRXJyb3I6ICIrdDoi
+VW5pbXBsZW1lbnRlZEVycm9yIn19ClAubGoucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4i
+QmFkIHN0YXRlOiAiK3RoaXMuYX19ClAuVVYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10
+aGlzLmEKaWYodD09bnVsbClyZXR1cm4iQ29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJh
+dGlvbi4iCnJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9uOiAiK1Au
+cCh0KSsiLiJ9fQpQLms1LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIk91dCBvZiBNZW1v
+cnkifSwKJGlYUzoxfQpQLktZLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlN0YWNrIE92
+ZXJmbG93In0sCiRpWFM6MX0KUC5jLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5h
+CnJldHVybiB0PT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSBkdXJpbmcgaXRzIGluaXRpYWxp
+emF0aW9uIjoiUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrdCsiJyBkdXJpbmcgaXRzIGluaXRpYWxp
+emF0aW9uIn19ClAuQ0QucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iRXhjZXB0aW9uOiAi
+K3RoaXMuYX19ClAuYUUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsayxqLGksaD10aGlzLmEsZz1oIT1udWxsJiYiIiE9PWg/IkZvcm1hdEV4Y2VwdGlvbjogIitILmQo
+aCk6IkZvcm1hdEV4Y2VwdGlvbiIsZj10aGlzLmMsZT10aGlzLmIKaWYodHlwZW9mIGU9PSJzdHJpbmci
+KXtpZihmIT1udWxsKWg9ZjwwfHxmPmUubGVuZ3RoCmVsc2UgaD0hMQppZihoKWY9bnVsbAppZihmPT1u
+dWxsKXt0PWUubGVuZ3RoPjc4P0MueEIuTmooZSwwLDc1KSsiLi4uIjplCnJldHVybiBnKyJcbiIrdH1m
+b3Iocz0xLHI9MCxxPSExLHA9MDtwPGY7KytwKXtvPUMueEIuVyhlLHApCmlmKG89PT0xMCl7aWYociE9
+PXB8fCFxKSsrcwpyPXArMQpxPSExfWVsc2UgaWYobz09PTEzKXsrK3MKcj1wKzEKcT0hMH19Zz1zPjE/
+ZysoIiAoYXQgbGluZSAiK3MrIiwgY2hhcmFjdGVyICIrKGYtcisxKSsiKVxuIik6ZysoIiAoYXQgY2hh
+cmFjdGVyICIrKGYrMSkrIilcbiIpCm49ZS5sZW5ndGgKZm9yKHA9ZjtwPG47KytwKXtvPUMueEIubShl
+LHApCmlmKG89PT0xMHx8bz09PTEzKXtuPXAKYnJlYWt9fWlmKG4tcj43OClpZihmLXI8NzUpe209cis3
+NQpsPXIKaz0iIgpqPSIuLi4ifWVsc2V7aWYobi1mPDc1KXtsPW4tNzUKbT1uCmo9IiJ9ZWxzZXtsPWYt
+MzYKbT1mKzM2Cmo9Ii4uLiJ9az0iLi4uIn1lbHNle209bgpsPXIKaz0iIgpqPSIifWk9Qy54Qi5Oaihl
+LGwsbSkKcmV0dXJuIGcraytpK2orIlxuIitDLnhCLkl4KCIgIixmLWwray5sZW5ndGgpKyJeXG4ifWVs
+c2UgcmV0dXJuIGYhPW51bGw/ZysoIiAoYXQgb2Zmc2V0ICIrSC5kKGYpKyIpIik6Z319ClAuRUgucHJv
+dG90eXBlPXt9ClAuS04ucHJvdG90eXBlPXt9ClAuY1gucHJvdG90eXBlPXsKZXY6ZnVuY3Rpb24oYSxi
+KXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5VNSh0aGlzLHQuQygiYTIoY1guRSkiKS5iKGIp
+LHQuQygiVTU8Y1guRT4iKSl9LApnQTpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuZ2t6KHRoaXMpCmZv
+cih0PTA7cy5GKCk7KSsrdApyZXR1cm4gdH0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5na3oo
+dGhpcykuRigpfSwKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5na3oodGhpcykKaWYoIXMuRigp
+KXRocm93IEguYihILldwKCkpCnQ9cy5nbCgpCmlmKHMuRigpKXRocm93IEguYihILmRVKCkpCnJldHVy
+biB0fSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpQLmsxKGIsImluZGV4IikKZm9yKHQ9dGhpcy5n
+a3oodGhpcykscz0wO3QuRigpOyl7cj10LmdsKCkKaWYoYj09PXMpcmV0dXJuIHI7KytzfXRocm93IEgu
+YihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGwscykpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5FUCh0
+aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5cGU9e30KUC56TS5wcm90b3R5cGU9eyRpY1g6MX0KUC5a
+MC5wcm90b3R5cGU9e30KUC5jOC5wcm90b3R5cGU9ewpnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFAuay5w
+cm90b3R5cGUuZ2lPLmNhbGwodGhpcyx0aGlzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIm51bGwifX0K
+UC5GSy5wcm90b3R5cGU9e30KUC5rLnByb3RvdHlwZT17Y29uc3RydWN0b3I6UC5rLCRpazoxLApETjpm
+dW5jdGlvbihhLGIpe3JldHVybiB0aGlzPT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUSh0
+aGlzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkluc3RhbmNlIG9mICciK0guZChILk0odGhpcykpKyIn
+In0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmIoYikKdGhyb3cgSC5iKFAubHIodGhpcyxiLmdXYSgpLGIu
+Z25kKCksYi5nVm0oKSkpfSwKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy53KHRoaXMpfX0K
+UC5PZC5wcm90b3R5cGU9e30KUC5pYi5wcm90b3R5cGU9eyRpT2Q6MX0KUC54dS5wcm90b3R5cGU9e30K
+UC5Hei5wcm90b3R5cGU9e30KUC5xVS5wcm90b3R5cGU9eyRpdlg6MX0KUC5Sbi5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
+cy5hCnJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGlCTDoxfQpQLkdELnByb3RvdHlwZT17
+fQpQLm4xLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5mLmIoYSkKSC55
+KGIpCnQ9Si5yWShiKS5PWShiLCI9IikKaWYodD09PS0xKXtpZihiIT09IiIpYS5ZKDAsUC5rdShiLDAs
+Yi5sZW5ndGgsdGhpcy5hLCEwKSwiIil9ZWxzZSBpZih0IT09MCl7cz1DLnhCLk5qKGIsMCx0KQpyPUMu
+eEIuRyhiLHQrMSkKcT10aGlzLmEKYS5ZKDAsUC5rdShzLDAscy5sZW5ndGgscSwhMCksUC5rdShyLDAs
+ci5sZW5ndGgscSwhMCkpfXJldHVybiBhfSwKJFM6MjZ9ClAuY1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
+b24oYSxiKXt0aHJvdyBILmIoUC5ycigiSWxsZWdhbCBJUHY0IGFkZHJlc3MsICIrYSx0aGlzLmEsYikp
+fSwKJFM6MjN9ClAuVkMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aHJvdyBILmIoUC5ycigi
+SWxsZWdhbCBJUHY2IGFkZHJlc3MsICIrYSx0aGlzLmEsYikpfSwKJDE6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuJDIoYSxudWxsKX0sCiRTOjIyfQpQLnRwLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
+dmFyIHQKaWYoYi1hPjQpdGhpcy5hLiQyKCJhbiBJUHY2IHBhcnQgY2FuIG9ubHkgY29udGFpbiBhIG1h
+eGltdW0gb2YgNCBoZXggZGlnaXRzIixhKQp0PVAuUUEoQy54Qi5Oaih0aGlzLmIsYSxiKSxudWxsLDE2
+KQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PDB8fHQ+NjU1MzUpdGhpcy5h
+LiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2Ugb2YgYDB4MC4uMHhGRkZGYCIsYSkKcmV0
+dXJuIHR9LAokUzoxOH0KUC5Ebi5wcm90b3R5cGU9ewpna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
+fSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiIiCmlmKEMueEIu
+bih0LCJbIikpcmV0dXJuIEMueEIuTmoodCwxLHQubGVuZ3RoLTEpCnJldHVybiB0fSwKZ3RwOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuZAppZih0PT1udWxsKXJldHVybiBQLndLKHRoaXMuYSkKcmV0dXJuIHR9
+LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYKcmV0dXJuIHQ9PW51bGw/IiI6dH0sCmdLYTpmdW5j
+dGlvbigpe3ZhciB0PXRoaXMucgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKbm06ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwp1LlguYihudWxsKQp1LmEuYihiKQp0PWwuYQpzPXQ9PT0i
+ZmlsZSIKcj1sLmIKcT1sLmQKcD1sLmMKaWYoIShwIT1udWxsKSlwPXIubGVuZ3RoIT09MHx8cSE9bnVs
+bHx8cz8iIjpudWxsCm89bC5lCmlmKCFzKW49cCE9bnVsbCYmby5sZW5ndGghPT0wCmVsc2Ugbj0hMApp
+ZihuJiYhQy54Qi5uKG8sIi8iKSlvPSIvIitvCmlmKGIhPW51bGwpbT1QLmxlKG51bGwsMCwwLGIpCmVs
+c2UgbT1sLmYKcmV0dXJuIG5ldyBQLkRuKHQscixwLHEsbyxtLGwucil9LApnRmo6ZnVuY3Rpb24oKXt2
+YXIgdCxzPXRoaXMueAppZihzIT1udWxsKXJldHVybiBzCnQ9dGhpcy5lCmlmKHQubGVuZ3RoIT09MCYm
+Qy54Qi5XKHQsMCk9PT00Nyl0PUMueEIuRyh0LDEpCnM9dD09PSIiP0MueEQ6UC5BRihuZXcgSC5BOChI
+LlZNKHQuc3BsaXQoIi8iKSx1LnMpLHUuZE8uYihQLlBIKCkpLHUuZG8pLHUuTikKdGhpcy5zbzYocykK
+cmV0dXJuIHN9LApnaFk6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMKaWYocy5RPT1udWxsKXt0PXMuZgpz
+LnNSSChuZXcgUC5HaihQLldYKHQ9PW51bGw/IiI6dCksdS5UKSl9cmV0dXJuIHMuUX0sCkpoOmZ1bmN0
+aW9uKGEsYil7dmFyIHQscyxyLHEscCxvCmZvcih0PTAscz0wO0MueEIuUWkoYiwiLi4vIixzKTspe3Mr
+PTM7Kyt0fXI9Qy54Qi5jbihhLCIvIikKd2hpbGUoITApe2lmKCEocj4wJiZ0PjApKWJyZWFrCnE9Qy54
+Qi5QayhhLCIvIixyLTEpCmlmKHE8MClicmVhawpwPXItcQpvPXAhPT0yCmlmKCFvfHxwPT09MylpZihD
+LnhCLm0oYSxxKzEpPT09NDYpbz0hb3x8Qy54Qi5tKGEscSsyKT09PTQ2CmVsc2Ugbz0hMQplbHNlIG89
+ITEKaWYobylicmVhazstLXQKcj1xfXJldHVybiBDLnhCLmk3KGEscisxLG51bGwsQy54Qi5HKGIscy0z
+KnQpKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24o
+YSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPW51bGwKaWYoYS5nRmkoKS5sZW5ndGghPT0w
+KXt0PWEuZ0ZpKCkKaWYoYS5nY2ooKSl7cz1hLmdrdSgpCnI9YS5nSmYoYSkKcT1hLmd4QSgpP2EuZ3Rw
+KGEpOmp9ZWxzZXtxPWoKcj1xCnM9IiJ9cD1QLnhlKGEuZ0lpKGEpKQpvPWEuZ1FEKCk/YS5ndFAoKTpq
+fWVsc2V7dD1rLmEKaWYoYS5nY2ooKSl7cz1hLmdrdSgpCnI9YS5nSmYoYSkKcT1QLndCKGEuZ3hBKCk/
+YS5ndHAoYSk6aix0KQpwPVAueGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UCgpOmp9ZWxzZXtzPWsu
+YgpyPWsuYwpxPWsuZAppZihhLmdJaShhKT09PSIiKXtwPWsuZQpvPWEuZ1FEKCk/YS5ndFAoKTprLmZ9
+ZWxzZXtpZihhLmd0VCgpKXA9UC54ZShhLmdJaShhKSkKZWxzZXtuPWsuZQppZihuLmxlbmd0aD09PTAp
+aWYocj09bnVsbClwPXQubGVuZ3RoPT09MD9hLmdJaShhKTpQLnhlKGEuZ0lpKGEpKQplbHNlIHA9UC54
+ZSgiLyIrYS5nSWkoYSkpCmVsc2V7bT1rLkpoKG4sYS5nSWkoYSkpCmw9dC5sZW5ndGg9PT0wCmlmKCFs
+fHxyIT1udWxsfHxDLnhCLm4obiwiLyIpKXA9UC54ZShtKQplbHNlIHA9UC53RihtLCFsfHxyIT1udWxs
+KX19bz1hLmdRRCgpP2EuZ3RQKCk6an19fXJldHVybiBuZXcgUC5Ebih0LHMscixxLHAsbyxhLmdaOCgp
+P2EuZ0thKCk6ail9LApnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jIT1udWxsfSwKZ3hBOmZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuZCE9bnVsbH0sCmdRRDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmYhPW51
+bGx9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yIT1udWxsfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0
+dXJuIEMueEIubih0aGlzLmUsIi8iKX0sCnQ0OmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMscT1yLmEK
+aWYocSE9PSIiJiZxIT09ImZpbGUiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUg
+cGF0aCBmcm9tIGEgIitILmQocSkrIiBVUkkiKSkKcT1yLmYKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0
+aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEg
+cXVlcnkgY29tcG9uZW50IikpCnE9ci5yCmlmKChxPT1udWxsPyIiOnEpIT09IiIpdGhyb3cgSC5iKFAu
+TDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNv
+bXBvbmVudCIpKQp0PSQud1EoKQppZihILm9UKHQpKXE9UC5tbihyKQplbHNle2lmKHIuYyE9bnVsbCYm
+ci5nSmYocikhPT0iIilILnZoKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBw
+YXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0eSIpKQpzPXIuZ0ZqKCkKUC5rRShzLCEx
+KQpxPVAudmcoQy54Qi5uKHIuZSwiLyIpPyIvIjoiIixzLCIvIikKcT1xLmNoYXJDb2RlQXQoMCk9PTA/
+cTpxfXJldHVybiBxfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9cS55CmlmKHA9PW51
+bGwpe3A9cS5hCnQ9cC5sZW5ndGghPT0wP3ArIjoiOiIiCnM9cS5jCnI9cz09bnVsbAppZighcnx8cD09
+PSJmaWxlIil7cD10KyIvLyIKdD1xLmIKaWYodC5sZW5ndGghPT0wKXA9cCt0KyJAIgppZighcilwKz1z
+CnQ9cS5kCmlmKHQhPW51bGwpcD1wKyI6IitILmQodCl9ZWxzZSBwPXQKcCs9cS5lCnQ9cS5mCmlmKHQh
+PW51bGwpcD1wKyI/Iit0CnQ9cS5yCmlmKHQhPW51bGwpcD1wKyIjIit0CnA9cS55PXAuY2hhckNvZGVB
+dCgwKT09MD9wOnB9cmV0dXJuIHB9LApETjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzCmlmKGI9
+PW51bGwpcmV0dXJuITEKaWYocj09PWIpcmV0dXJuITAKaWYodS53LmMoYikpaWYoci5hPT1iLmdGaSgp
+KWlmKHIuYyE9bnVsbD09PWIuZ2NqKCkpaWYoci5iPT1iLmdrdSgpKWlmKHIuZ0pmKHIpPT1iLmdKZihi
+KSlpZihyLmd0cChyKT09Yi5ndHAoYikpaWYoci5lPT09Yi5nSWkoYikpe3Q9ci5mCnM9dD09bnVsbApp
+Zighcz09PWIuZ1FEKCkpe2lmKHMpdD0iIgppZih0PT09Yi5ndFAoKSl7dD1yLnIKcz10PT1udWxsCmlm
+KCFzPT09Yi5nWjgoKSl7aWYocyl0PSIiCnQ9dD09PWIuZ0thKCl9ZWxzZSB0PSExfWVsc2UgdD0hMX1l
+bHNlIHQ9ITF9ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQpl
+bHNlIHQ9ITEKZWxzZSB0PSExCnJldHVybiB0fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuegpy
+ZXR1cm4gdD09bnVsbD90aGlzLno9Qy54Qi5naU8odGhpcy53KDApKTp0fSwKc282OmZ1bmN0aW9uKGEp
+e3RoaXMueD11LmkuYihhKX0sCnNSSDpmdW5jdGlvbihhKXt0aGlzLlE9dS5mLmIoYSl9LAokaWlEOjEs
+CmdGaTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+ZX19ClAuZTEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKFAucnIoIkludmFsaWQg
+cG9ydCIsdGhpcy5hLHRoaXMuYisxKSl9LAokUzoxN30KUC5OWS5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXt2YXIgdD0iSWxsZWdhbCBwYXRoIGNoYXJhY3RlciAiCkgueShhKQppZihKLnpsKGEsIi8iKSlp
+Zih0aGlzLmEpdGhyb3cgSC5iKFAueFkodCthKSkKZWxzZSB0aHJvdyBILmIoUC5MNCh0K2EpKX0sCiRT
+OjE3fQpQLlJaLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBQLmVQKEMuWkosYSxDLnhN
+LCExKX0sCiRTOjZ9ClAuTUUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmIs
+cz10aGlzLmEKdC5hKz1zLmEKcy5hPSImIgpzPXQuYSs9SC5kKFAuZVAoQy5GMyxhLEMueE0sITApKQpp
+ZihiIT1udWxsJiZiLmxlbmd0aCE9PTApe3QuYT1zKyI9Igp0LmErPUguZChQLmVQKEMuRjMsYixDLnhN
+LCEwKSl9fSwKJFM6MTl9ClAueTUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgu
+eShhKQppZihiPT1udWxsfHx0eXBlb2YgYj09InN0cmluZyIpdGhpcy5hLiQyKGEsSC55KGIpKQplbHNl
+IGZvcih0PUouSVQodS5SLmIoYikpLHM9dGhpcy5hO3QuRigpOylzLiQyKGEsSC55KHQuZ2woKSkpfSwK
+JFM6MTZ9ClAuUEUucHJvdG90eXBlPXsKZ2xSOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89
+bnVsbCxuPXAuYwppZihuIT1udWxsKXJldHVybiBuCm49cC5iCmlmKDA+PW4ubGVuZ3RoKXJldHVybiBI
+Lk9IKG4sMCkKdD1wLmEKbj1uWzBdKzEKcz1DLnhCLlhVKHQsIj8iLG4pCnI9dC5sZW5ndGgKaWYocz49
+MCl7cT1QLnVPKHQscysxLHIsQy5WQywhMSkKcj1zfWVsc2UgcT1vCnJldHVybiBwLmM9bmV3IFAucWUo
+ImRhdGEiLG8sbyxvLFAudU8odCxuLHIsQy5XZCwhMSkscSxvKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQs
+cz10aGlzLmIKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywwKQp0PXRoaXMuYQpyZXR1cm4gc1sw
+XT09PS0xPyJkYXRhOiIrdDp0fX0KUC5xMy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IFVpbnQ4QXJyYXkoOTYpfSwKJFM6MjB9ClAueUkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxi
+KXt2YXIgdD10aGlzLmEKaWYoYT49dC5sZW5ndGgpcmV0dXJuIEguT0godCxhKQp0PXRbYV0KSi5DTSh0
+LDAsOTYsYikKcmV0dXJuIHR9LAokUzoyMX0KUC5jNi5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHQscyxyLHEKZm9yKHQ9Yi5sZW5ndGgscz1hLmxlbmd0aCxyPTA7cjx0Oysrcil7cT1DLnhC
+LlcoYixyKV45NgppZihxPj1zKXJldHVybiBILk9IKGEscSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBl
+PXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5X
+KGIsMSkscj1hLmxlbmd0aDt0PD1zOysrdCl7cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguT0go
+YSxxKQphW3FdPWN9fX0KUC5VZi5wcm90b3R5cGU9ewpnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5j
+PjB9LApneEE6ZnVuY3Rpb24oKXt2YXIgdCxzCmlmKHRoaXMuYz4wKXt0PXRoaXMuZAppZih0eXBlb2Yg
+dCE9PSJudW1iZXIiKXJldHVybiB0LmgoKQpzPXRoaXMuZQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJl
+dHVybiBILnBZKHMpCnM9dCsxPHMKdD1zfWVsc2UgdD0hMQpyZXR1cm4gdH0sCmdRRDpmdW5jdGlvbigp
+e3ZhciB0PXRoaXMuZgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDx0
+aGlzLnJ9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6ZnVu
+Y3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiZmlsZSIpfSwKZ3ZoOmZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubih0aGlzLmEsImh0dHAiKX0sCmdxQjpmdW5jdGlv
+bigpe3JldHVybiB0aGlzLmI9PT01JiZDLnhCLm4odGhpcy5hLCJodHRwcyIpfSwKZ3RUOmZ1bmN0aW9u
+KCl7cmV0dXJuIEMueEIuUWkodGhpcy5hLCIvIix0aGlzLmUpfSwKZ0ZpOmZ1bmN0aW9uKCl7dmFyIHQs
+cz10aGlzLHI9InBhY2thZ2UiLHE9cy5iCmlmKHE8PTApcmV0dXJuIiIKdD1zLngKaWYodCE9bnVsbCly
+ZXR1cm4gdAppZihzLmd2aCgpKXE9cy54PSJodHRwIgplbHNlIGlmKHMuZ3FCKCkpe3MueD0iaHR0cHMi
+CnE9Imh0dHBzIn1lbHNlIGlmKHMuZ053KCkpe3MueD0iZmlsZSIKcT0iZmlsZSJ9ZWxzZSBpZihxPT09
+NyYmQy54Qi5uKHMuYSxyKSl7cy54PXIKcT1yfWVsc2V7cT1DLnhCLk5qKHMuYSwwLHEpCnMueD1xfXJl
+dHVybiBxfSwKZ2t1OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5jLHM9dGhpcy5iKzMKcmV0dXJuIHQ+cz9D
+LnhCLk5qKHRoaXMuYSxzLHQtMSk6IiJ9LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVy
+biB0PjA/Qy54Qi5Oaih0aGlzLmEsdCx0aGlzLmQpOiIifSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciB0LHM9
+dGhpcwppZihzLmd4QSgpKXt0PXMuZAppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LmgoKQpy
+ZXR1cm4gUC5RQShDLnhCLk5qKHMuYSx0KzEscy5lKSxudWxsLG51bGwpfWlmKHMuZ3ZoKCkpcmV0dXJu
+IDgwCmlmKHMuZ3FCKCkpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4g
+Qy54Qi5Oaih0aGlzLmEsdGhpcy5lLHRoaXMuZil9LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYs
+cz10aGlzLnIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5KKCkKcmV0dXJuIHQ8cz9DLnhC
+Lk5qKHRoaXMuYSx0KzEscyk6IiJ9LApnS2E6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLnIscz10aGlzLmEK
+cmV0dXJuIHQ8cy5sZW5ndGg/Qy54Qi5HKHMsdCsxKToiIn0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHMs
+cj10aGlzLmUscT10aGlzLmYscD10aGlzLmEKaWYoQy54Qi5RaShwLCIvIixyKSl7aWYodHlwZW9mIHIh
+PT0ibnVtYmVyIilyZXR1cm4gci5oKCk7KytyfWlmKHI9PXEpcmV0dXJuIEMueEQKdD1ILlZNKFtdLHUu
+cykKcz1yCndoaWxlKCEwKXtpZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQppZih0eXBl
+b2YgcSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCmlmKCEoczxxKSlicmVhawppZihDLnhCLm0ocCxz
+KT09PTQ3KXtDLk5tLmkodCxDLnhCLk5qKHAscixzKSkKcj1zKzF9KytzfUMuTm0uaSh0LEMueEIuTmoo
+cCxyLHEpKQpyZXR1cm4gUC5BRih0LHUuTil9LApnaFk6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYKaWYo
+dHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5KKCkKaWYodD49dGhpcy5yKXJldHVybiBDLldPCnJl
+dHVybiBuZXcgUC5HaihQLldYKHRoaXMuZ3RQKCkpLHUuVCl9LAprWDpmdW5jdGlvbihhKXt2YXIgdCxz
+PXRoaXMuZAppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLmgoKQp0PXMrMQpyZXR1cm4gdCth
+Lmxlbmd0aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEsYSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9
+dGhpcyxzPXQucixyPXQuYQppZihzPj1yLmxlbmd0aClyZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54
+Qi5OaihyLDAscyksdC5iLHQuYyx0LmQsdC5lLHQuZixzLHQueCl9LApubTpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHMscixxLHAsbyxuLG0sbCxrLGosaT10aGlzLGg9bnVsbAp1LlguYihudWxsKQp1LmEuYihiKQp0
+PWkuZ0ZpKCkKcz10PT09ImZpbGUiCnI9aS5jCnE9cj4wP0MueEIuTmooaS5hLGkuYiszLHIpOiIiCnA9
+aS5neEEoKT9pLmd0cChpKTpoCnI9aS5jCmlmKHI+MClvPUMueEIuTmooaS5hLHIsaS5kKQplbHNlIG89
+cS5sZW5ndGghPT0wfHxwIT1udWxsfHxzPyIiOmgKcj1pLmEKbj1pLmYKbT1DLnhCLk5qKHIsaS5lLG4p
+CmlmKCFzKWw9byE9bnVsbCYmbS5sZW5ndGghPT0wCmVsc2UgbD0hMAppZihsJiYhQy54Qi5uKG0sIi8i
+KSltPSIvIittCmlmKGIhPW51bGwpaz1QLmxlKGgsMCwwLGIpCmVsc2V7bD1pLnIKaWYodHlwZW9mIG4h
+PT0ibnVtYmVyIilyZXR1cm4gbi5KKCkKaz1uPGw/Qy54Qi5OaihyLG4rMSxsKTpofW49aS5yCmo9bjxy
+Lmxlbmd0aD9DLnhCLkcocixuKzEpOmgKcmV0dXJuIG5ldyBQLkRuKHQscSxvLHAsbSxrLGopfSwKWkk6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXtpZihhIGlu
+c3RhbmNlb2YgUC5VZilyZXR1cm4gdGhpcy51MSh0aGlzLGEpCnJldHVybiB0aGlzLlJlKCkubVMoYSl9
+LAp1MTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPWIuYgpp
+ZihlPjApcmV0dXJuIGIKdD1iLmMKaWYodD4wKXtzPWEuYgppZihzPD0wKXJldHVybiBiCmlmKGEuZ053
+KCkpcj1iLmUhPWIuZgplbHNlIGlmKGEuZ3ZoKCkpcj0hYi5rWCgiODAiKQplbHNlIHI9IWEuZ3FCKCl8
+fCFiLmtYKCI0NDMiKQppZihyKXtxPXMrMQpwPUMueEIuTmooYS5hLDAscSkrQy54Qi5HKGIuYSxlKzEp
+CmU9Yi5kCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCm89Yi5lCmlmKHR5cGVvZiBv
+IT09Im51bWJlciIpcmV0dXJuIG8uaCgpCm49Yi5mCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJu
+IG4uaCgpCnJldHVybiBuZXcgUC5VZihwLHMsdCtxLGUrcSxvK3EsbitxLGIucitxLGEueCl9ZWxzZSBy
+ZXR1cm4gdGhpcy5SZSgpLm1TKGIpfW09Yi5lCmU9Yi5mCmlmKG09PWUpe3Q9Yi5yCmlmKHR5cGVvZiBl
+IT09Im51bWJlciIpcmV0dXJuIGUuSigpCmlmKGU8dCl7cz1hLmYKaWYodHlwZW9mIHMhPT0ibnVtYmVy
+IilyZXR1cm4gcy5ITigpCnE9cy1lCnJldHVybiBuZXcgUC5VZihDLnhCLk5qKGEuYSwwLHMpK0MueEIu
+RyhiLmEsZSksYS5iLGEuYyxhLmQsYS5lLGUrcSx0K3EsYS54KX1lPWIuYQppZih0PGUubGVuZ3RoKXtz
+PWEucgpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLkcoZSx0KSxhLmIsYS5jLGEu
+ZCxhLmUsYS5mLHQrKHMtdCksYS54KX1yZXR1cm4gYS5OOSgpfXQ9Yi5hCmlmKEMueEIuUWkodCwiLyIs
+bSkpe3M9YS5lCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSE4oKQppZih0eXBlb2YgbSE9
+PSJudW1iZXIiKXJldHVybiBILnBZKG0pCnE9cy1tCnA9Qy54Qi5OaihhLmEsMCxzKStDLnhCLkcodCxt
+KQppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpyZXR1cm4gbmV3IFAuVWYocCxhLmIs
+YS5jLGEuZCxzLGUrcSxiLnIrcSxhLngpfWw9YS5lCms9YS5mCmlmKGw9PWsmJmEuYz4wKXtmb3IoO0Mu
+eEIuUWkodCwiLi4vIixtKTspe2lmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0uaCgpCm0rPTN9
+aWYodHlwZW9mIGwhPT0ibnVtYmVyIilyZXR1cm4gbC5ITigpCmlmKHR5cGVvZiBtIT09Im51bWJlciIp
+cmV0dXJuIEgucFkobSkKcT1sLW0rMQpwPUMueEIuTmooYS5hLDAsbCkrIi8iK0MueEIuRyh0LG0pCmlm
+KHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCnJldHVybiBuZXcgUC5VZihwLGEuYixhLmMs
+YS5kLGwsZStxLGIucitxLGEueCl9aj1hLmEKZm9yKGk9bDtDLnhCLlFpKGosIi4uLyIsaSk7KXtpZih0
+eXBlb2YgaSE9PSJudW1iZXIiKXJldHVybiBpLmgoKQppKz0zfWg9MAp3aGlsZSghMCl7aWYodHlwZW9m
+IG0hPT0ibnVtYmVyIilyZXR1cm4gbS5oKCkKZz1tKzMKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1
+cm4gSC5wWShlKQppZighKGc8PWUmJkMueEIuUWkodCwiLi4vIixtKSkpYnJlYWs7KytoCm09Z31mPSIi
+CndoaWxlKCEwKXtpZih0eXBlb2YgayE9PSJudW1iZXIiKXJldHVybiBrLm9zKCkKaWYodHlwZW9mIGkh
+PT0ibnVtYmVyIilyZXR1cm4gSC5wWShpKQppZighKGs+aSkpYnJlYWs7LS1rCmlmKEMueEIubShqLGsp
+PT09NDcpe2lmKGg9PT0wKXtmPSIvIgpicmVha30tLWgKZj0iLyJ9fWlmKGs9PT1pJiZhLmI8PTAmJiFD
+LnhCLlFpKGosIi8iLGwpKXttLT1oKjMKZj0iIn1xPWstbStmLmxlbmd0aApyZXR1cm4gbmV3IFAuVWYo
+Qy54Qi5OaihqLDAsaykrZitDLnhCLkcodCxtKSxhLmIsYS5jLGEuZCxsLGUrcSxiLnIrcSxhLngpfSwK
+dDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMKaWYocC5iPj0wJiYhcC5nTncoKSl0aHJvdyBI
+LmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrSC5kKHAuZ0ZpKCkpKyIg
+VVJJIikpCnQ9cC5mCnM9cC5hCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ8
+cy5sZW5ndGgpe2lmKHQ8cC5yKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0
+aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiKSkKdGhyb3cgSC5iKFAuTDQoIkNhbm5v
+dCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNvbXBvbmVudCIp
+KX1yPSQud1EoKQppZihILm9UKHIpKXQ9UC5tbihwKQplbHNle3E9cC5kCmlmKHR5cGVvZiBxIT09Im51
+bWJlciIpcmV0dXJuIEgucFkocSkKaWYocC5jPHEpSC52aChQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIG5v
+bi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBhdXRob3JpdHkiKSkKdD1D
+LnhCLk5qKHMscC5lLHQpfXJldHVybiB0fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMueQpyZXR1
+cm4gdD09bnVsbD90aGlzLnk9Qy54Qi5naU8odGhpcy5hKTp0fSwKRE46ZnVuY3Rpb24oYSxiKXtpZihi
+PT1udWxsKXJldHVybiExCmlmKHRoaXM9PT1iKXJldHVybiEwCnJldHVybiB1LncuYyhiKSYmdGhpcy5h
+PT09Yi53KDApfSwKUmU6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9bnVsbCxyPXQuZ0ZpKCkscT10Lmdr
+dSgpLHA9dC5jPjA/dC5nSmYodCk6cyxvPXQuZ3hBKCk/dC5ndHAodCk6cyxuPXQuYSxtPXQuZixsPUMu
+eEIuTmoobix0LmUsbSksaz10LnIKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5KKCkKbT1t
+PGs/dC5ndFAoKTpzCnJldHVybiBuZXcgUC5EbihyLHEscCxvLGwsbSxrPG4ubGVuZ3RoP3QuZ0thKCk6
+cyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokaWlEOjF9ClAucWUucHJvdG90eXBlPXt9
+ClcucUUucHJvdG90eXBlPXt9ClcuR2gucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3Ry
+aW5nKGEpfSwKJGlHaDoxfQpXLmZZLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmlu
+ZyhhKX19ClcubkIucHJvdG90eXBlPXskaW5COjF9ClcuQXoucHJvdG90eXBlPXskaUF6OjF9ClcuUVAu
+cHJvdG90eXBlPXskaVFQOjF9ClcubngucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
+bGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
+LmlkLnByb3RvdHlwZT17fQpXLlFGLnByb3RvdHlwZT17fQpXLk5oLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcuSUIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
+cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0guZChhLndpZHRo
+KSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiEx
+CnJldHVybiB1LnEuYyhiKSYmYS5sZWZ0PT09Yi5sZWZ0JiZhLnRvcD09PWIudG9wJiZhLndpZHRoPT09
+Yi53aWR0aCYmYS5oZWlnaHQ9PT1iLmhlaWdodH0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gVy5yRShD
+LkNELmdpTyhhLmxlZnQpLEMuQ0QuZ2lPKGEudG9wKSxDLkNELmdpTyhhLndpZHRoKSxDLkNELmdpTyhh
+LmhlaWdodCkpfSwKJGl0bjoxfQpXLm43LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBh
+Lmxlbmd0aH19Clcud3oucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5n
+dGh9LApxOmZ1bmN0aW9uKGEsYil7dmFyIHQKSC5TYyhiKQp0PXRoaXMuYQppZihiPDB8fGI+PXQubGVu
+Z3RoKXJldHVybiBILk9IKHQsYikKcmV0dXJuIHRoaXMuJHRpLmQuYih0W2JdKX0sClk6ZnVuY3Rpb24o
+YSxiLGMpe3RoaXMuJHRpLmQuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBsaXN0Iikp
+fX0KVy5jdi5wcm90b3R5cGU9ewpnUWc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmk3KGEpfSwKZ0Q6
+ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLkk0KGEpfSwKc0Q6ZnVuY3Rpb24oYSxiKXt2YXIgdAp1Llgu
+YihiKQp0PXRoaXMuZ0QoYSkKdC5WMSgwKQp0LkZWKDAsYil9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBh
+LmxvY2FsTmFtZX0sCnRuOmZ1bmN0aW9uKGEpe3ZhciB0PSEhYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVk
+CmlmKHQpYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkKCkKZWxzZSBhLnNjcm9sbEludG9WaWV3KCl9LApy
+NjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscQppZihjPT1udWxsKXtpZihkPT1udWxsKXt0PSQu
+bHQKaWYodD09bnVsbCl7dD1ILlZNKFtdLHUubSkKcz1uZXcgVy52RCh0KQpDLk5tLmkodCxXLlR3KG51
+bGwpKQpDLk5tLmkodCxXLkJsKCkpCiQubHQ9cwpkPXN9ZWxzZSBkPXR9dD0kLkVVCmlmKHQ9PW51bGwp
+e3Q9bmV3IFcuS28oZCkKJC5FVT10CmM9dH1lbHNle3QuYT1kCmM9dH19ZWxzZSBpZihkIT1udWxsKXRo
+cm93IEguYihQLnhZKCJ2YWxpZGF0b3IgY2FuIG9ubHkgYmUgcGFzc2VkIGlmIHRyZWVTYW5pdGl6ZXIg
+aXMgbnVsbCIpKQppZigkLnhvPT1udWxsKXt0PWRvY3VtZW50CnM9dC5pbXBsZW1lbnRhdGlvbi5jcmVh
+dGVIVE1MRG9jdW1lbnQoIiIpCiQueG89cwokLkJPPXMuY3JlYXRlUmFuZ2UoKQpzPSQueG8uY3JlYXRl
+RWxlbWVudCgiYmFzZSIpCnUuRi5iKHMpCnMuaHJlZj10LmJhc2VVUkkKJC54by5oZWFkLmFwcGVuZENo
+aWxkKHMpfXQ9JC54bwppZih0LmJvZHk9PW51bGwpe3M9dC5jcmVhdGVFbGVtZW50KCJib2R5IikKdC5i
+b2R5PXUuWS5iKHMpfXQ9JC54bwppZih1LlkuYyhhKSlyPXQuYm9keQplbHNle3I9dC5jcmVhdGVFbGVt
+ZW50KGEudGFnTmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0dWFs
+RnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdOYW1l
+KSl7JC5CTy5zZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVu
+dChiKX1lbHNle3IuaW5uZXJIVE1MPWIKcT0kLnhvLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpmb3Io
+O3Q9ci5maXJzdENoaWxkLHQhPW51bGw7KXEuYXBwZW5kQ2hpbGQodCl9dD0kLnhvLmJvZHkKaWYocj09
+bnVsbD90IT1udWxsOnIhPT10KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkKcmV0
+dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApzaGY6
+ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29udGVu
+dD1udWxsCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuQ3Eo
+YSwiY2xpY2siLCExLHUuUSl9LAokaWN2OjEsCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1l
+fX0KVy5Ddi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmModS5BLmIoYSkpfSwK
+JFM6NDR9ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rpb24o
+YSxiLGMsZCl7dS5VLmIoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9uKGEs
+YixjKXtyZXR1cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJu
+IGEuYWRkRXZlbnRMaXN0ZW5lcihiLEgudFIodS5VLmIoYyksMSksZCl9LAokaUQwOjF9ClcuVDUucHJv
+dG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVu
+Z3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlZi
+LnByb3RvdHlwZT17fQpXLk83LnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBh
+Lm9wZW4oYixjLCEwKX0sCiRpTzc6MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Ro
+aXMuYS5zZXRSZXF1ZXN0SGVhZGVyKEgueShhKSxILnkoYikpfSwKJFM6MTB9ClcuaEgucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscAp1LnAuYihhKQp0PXRoaXMuYQpzPXQuc3RhdHVz
+CmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMudEIoKQpyPXM+PTIwMCYmczwzMDAKcT1zPjMw
+NyYmczw0MDAKcz1yfHxzPT09MHx8cz09PTMwNHx8cQpwPXRoaXMuYgppZihzKXtwLiR0aS5DKCIxLyIp
+LmIodCkKcz1wLmEKaWYocy5hIT09MClILnZoKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIp
+KQpzLlhmKHQpfWVsc2UgcC5wbShhKX0sCiRTOjI0fQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnByb3Rv
+dHlwZT17JGlTZzoxfQpXLnU4LnByb3RvdHlwZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2luIiBp
+biBhKXJldHVybiBhLm9yaWdpbgpyZXR1cm4gSC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9zdCl9
+LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaXU4OjF9ClcuQWoucHJvdG90eXBlPXsk
+aUFqOjF9ClcuZTcucHJvdG90eXBlPXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hp
+bGROb2Rlcy5sZW5ndGgKaWYocz09PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+
+MSl0aHJvdyBILmIoUC5QVigiTW9yZSB0aGFuIG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0Q2hp
+bGR9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxCnUuZWguYihiKQp0PWIuYQpzPXRoaXMuYQpp
+Zih0IT09cylmb3Iocj10LmNoaWxkTm9kZXMubGVuZ3RoLHE9MDtxPHI7KytxKXMuYXBwZW5kQ2hpbGQo
+dC5maXJzdENoaWxkKQpyZXR1cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5iKGMpCnQ9
+dGhpcy5hCnM9dC5jaGlsZE5vZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxiKQp0
+LnJlcGxhY2VDaGlsZChjLHNbYl0pfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5jaGlsZE5v
+ZGVzCnJldHVybiBuZXcgVy5XOSh0LHQubGVuZ3RoLEgueksodCkuQygiVzk8R20uRT4iKSl9LApnQTpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNoaWxkTm9kZXMubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
+e3ZhciB0CkguU2MoYikKdD10aGlzLmEuY2hpbGROb2RlcwppZihiPDB8fGI+PXQubGVuZ3RoKXJldHVy
+biBILk9IKHQsYikKcmV0dXJuIHRbYl19fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEpe3Zh
+ciB0PWEucGFyZW50Tm9kZQppZih0IT1udWxsKXQucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlvbihh
+KXt2YXIgdApmb3IoO3Q9YS5maXJzdENoaWxkLHQhPW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LAp3OmZ1
+bmN0aW9uKGEpe3ZhciB0PWEubm9kZVZhbHVlCnJldHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwKJGl1
+SDoxfQpXLkJILnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVu
+Y3Rpb24oYSxiKXtILlNjKGIpCmlmKGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2Yo
+YixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEuYihj
+KQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIp
+KX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0
+dXJuIGFbYl19LAokaVhqOjEsCiRpY1g6MSwKJGl6TToxfQpXLlNOLnByb3RvdHlwZT17fQpXLmV3LnBy
+b3RvdHlwZT17JGlldzoxfQpXLmxwLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxl
+bmd0aH19ClcuVGIucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZigiY3Jl
+YXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlz
+LkRXKGEsYixjLGQpCnQ9Vy5VOSgiPHRhYmxlPiIrSC5kKGIpKyI8L3RhYmxlPiIsYyxkKQpzPWRvY3Vt
+ZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpzLnRvU3RyaW5nCnQudG9TdHJpbmcKbmV3IFcuZTco
+cykuRlYoMCxuZXcgVy5lNyh0KSkKcmV0dXJuIHN9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0aW9u
+KGEsYixjLGQpe3ZhciB0LHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRv
+dy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3Jl
+YXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixj
+LGQpCnQudG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnIudG9TdHJpbmcKdD1uZXcgVy5l
+NyhyKQpxPXQuZ3I4KHQpCnMudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBX
+LmU3KHEpKQpyZXR1cm4gc319ClcuQlQucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
+IHQscyxyCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5
+cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFn
+bWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9TdHJpbmcK
+dD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnMudG9TdHJpbmcKci50b1N0cmluZwpuZXcgVy5lNyhzKS5G
+VigwLG5ldyBXLmU3KHIpKQpyZXR1cm4gc319ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciB0LHMKYS50ZXh0Q29udGVudD1udWxsCnQ9YS5jb250ZW50CnQudG9TdHJpbmcKSi5iVCh0
+KQpzPXRoaXMucjYoYSxiLG51bGwsYykKYS5jb250ZW50LmFwcGVuZENoaWxkKHMpfSwKWUM6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gdGhpcy5wayhhLGIsbnVsbCl9LAokaXlZOjF9ClcudzYucHJvdG90eXBlPXt9
+ClcuSzUucHJvdG90eXBlPXskaUs1OjEsJGl2NjoxfQpXLkNtLnByb3RvdHlwZT17JGlDbToxfQpXLkNR
+LnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJl
+Y3RhbmdsZSAoIitILmQoYS5sZWZ0KSsiLCAiK0guZChhLnRvcCkrIikgIitILmQoYS53aWR0aCkrIiB4
+ICIrSC5kKGEuaGVpZ2h0KX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1
+cm4gdS5xLmMoYikmJmEubGVmdD09PWIubGVmdCYmYS50b3A9PT1iLnRvcCYmYS53aWR0aD09PWIud2lk
+dGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFcuckUoQy5DRC5n
+aU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRvcCksQy5DRC5naU8oYS53aWR0aCksQy5DRC5naU8oYS5oZWln
+aHQpKX19ClcucmgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpm
+dW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5D
+ZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5i
+KGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3Qu
+IikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpy
+ZXR1cm4gYVtiXX0sCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuRDkucHJvdG90eXBlPXsKSzpmdW5j
+dGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5ELmIoYikKZm9yKHQ9dGhpcy5nVigpLHM9dC5sZW5ndGgs
+cj10aGlzLmEscT0wO3E8dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK3Epe3A9dFtx
+XQpiLiQyKHAsci5nZXRBdHRyaWJ1dGUocCkpfX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10
+aGlzLmEuYXR0cmlidXRlcyxvPUguVk0oW10sdS5zKQpmb3IodD1wLmxlbmd0aCxzPXUuaDkscj0wO3I8
+dDsrK3Ipe2lmKHI+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscikKcT1zLmIocFtyXSkKaWYocS5uYW1l
+c3BhY2VVUkk9PW51bGwpQy5ObS5pKG8scS5uYW1lKX1yZXR1cm4gb319ClcuaTcucHJvdG90eXBlPXsK
+cTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuZ2V0QXR0cmlidXRlKEgueShiKSl9LApZOmZ1bmN0
+aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0cmlidXRlKGIsYyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5nVigpLmxlbmd0aH19ClcuU3kucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0
+aGlzLmEuYS5nZXRBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oSC55KGIpKSl9LApZOmZ1bmN0aW9uKGEs
+YixjKXt0aGlzLmEuYS5zZXRBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oYiksYyl9LApLOmZ1bmN0aW9u
+KGEsYil7dGhpcy5hLksoMCxuZXcgVy5LUyh0aGlzLHUuRC5iKGIpKSl9LApnVjpmdW5jdGlvbigpe3Zh
+ciB0PUguVk0oW10sdS5zKQp0aGlzLmEuSygwLG5ldyBXLkEzKHRoaXMsdCkpCnJldHVybiB0fSwKZ0E6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGh9LAprOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cj1ILlZNKGEuc3BsaXQoIi0iKSx1LnMpCmZvcih0PTE7dDxyLmxlbmd0aDsrK3Qpe3M9clt0XQppZihz
+Lmxlbmd0aD4wKUMuTm0uWShyLHQsc1swXS50b1VwcGVyQ2FzZSgpK0ouS1YocywxKSl9cmV0dXJuIEMu
+Tm0uSChyLCIiKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscApmb3IodD1hLmxlbmd0aCxzPTAs
+cj0iIjtzPHQ7KytzKXtxPWFbc10KcD1xLnRvTG93ZXJDYXNlKCkKcj0ocSE9PXAmJnM+MD9yKyItIjpy
+KStwfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfX0KVy5LUy5wcm90b3R5cGU9ewokMjpmdW5j
+dGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKXRoaXMuYi4kMih0aGlzLmEuayhDLnhCLkco
+YSw1KSksYil9LAokUzoxMH0KVy5BMy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclko
+YSkubihhLCJkYXRhLSIpKUMuTm0uaSh0aGlzLmIsdGhpcy5hLmsoQy54Qi5HKGEsNSkpKX0sCiRTOjEw
+fQpXLkk0LnByb3RvdHlwZT17ClA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPVAuTHModS5OKQpmb3Io
+dD10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1KLlQw
+KHRbcl0pCmlmKHEubGVuZ3RoIT09MClwLmkoMCxxKX1yZXR1cm4gcH0sClg6ZnVuY3Rpb24oYSl7dGhp
+cy5hLmNsYXNzTmFtZT11LkMuYihhKS5IKDAsIiAiKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEuY2xhc3NMaXN0Lmxlbmd0aH0sClYxOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9IiJ9LAp0
+ZzpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5jbGFzc0xpc3QuY29udGFpbnMoYikKcmV0dXJuIHR9
+LAppOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdCxzPXQuY29udGFpbnMoYikKdC5h
+ZGQoYikKcmV0dXJuIXN9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdCxzPXQu
+Y29udGFpbnMoYikKdC5yZW1vdmUoYikKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe1cuVE4odGhp
+cy5hLHUuWC5iKGIpKX19ClcuRmsucHJvdG90eXBlPXt9ClcuUk8ucHJvdG90eXBlPXt9ClcuQ3EucHJv
+dG90eXBlPXt9ClcueEMucHJvdG90eXBlPXt9Clcudk4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+cmV0dXJuIHRoaXMuYS4kMSh1LkIuYihhKSl9LAokUzoyNX0KVy5KUS5wcm90b3R5cGU9ewpDWTpmdW5j
+dGlvbihhKXt2YXIgdAppZigkLm9yLmE9PT0wKXtmb3IodD0wO3Q8MjYyOysrdCkkLm9yLlkoMCxDLmNt
+W3RdLFcucFMoKSkKZm9yKHQ9MDt0PDEyOysrdCkkLm9yLlkoMCxDLkJJW3RdLFcuVjQoKSl9fSwKaTA6
+ZnVuY3Rpb24oYSl7cmV0dXJuICQuQU4oKS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0PSQub3IucSgwLEguZChXLnJTKGEpKSsiOjoiK2IpCmlmKHQ9PW51bGwpdD0kLm9yLnEoMCwi
+Kjo6IitiKQppZih0PT1udWxsKXJldHVybiExCnJldHVybiBILnhkKHQuJDQoYSxiLGMsdGhpcykpfSwK
+JGlrRjoxfQpXLkdtLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzkoYSx0
+aGlzLmdBKGEpLEgueksoYSkuQygiVzk8R20uRT4iKSl9fQpXLnZELnByb3RvdHlwZT17CmkwOmZ1bmN0
+aW9uKGEpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5VdihhKSl9LApFYjpmdW5jdGlvbihhLGIs
+Yyl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLkVnKGEsYixjKSl9LAokaWtGOjF9ClcuVXYucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuZS5iKGEpLmkwKHRoaXMuYSl9LAokUzoxNX0K
+Vy5FZy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5lLmIoYSkuRWIodGhpcy5hLHRo
+aXMuYix0aGlzLmMpfSwKJFM6MTV9ClcubTYucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiLGMsZCl7
+dmFyIHQscyxyCnRoaXMuYS5GVigwLGMpCnQ9Yi5ldigwLG5ldyBXLkVvKCkpCnM9Yi5ldigwLG5ldyBX
+LldrKCkpCnRoaXMuYi5GVigwLHQpCnI9dGhpcy5jCnIuRlYoMCxDLnhEKQpyLkZWKDAscyl9LAppMDpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7
+dmFyIHQ9dGhpcyxzPVcuclMoYSkscj10LmMKaWYoci50ZygwLEguZChzKSsiOjoiK2IpKXJldHVybiB0
+LmQuRHQoYykKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuIHQuZC5EdChjKQplbHNle3I9dC5i
+CmlmKHIudGcoMCxILmQocykrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCwiKjo6IitiKSly
+ZXR1cm4hMAplbHNlIGlmKHIudGcoMCxILmQocykrIjo6KiIpKXJldHVybiEwCmVsc2UgaWYoci50Zygw
+LCIqOjoqIikpcmV0dXJuITB9cmV0dXJuITF9LAokaWtGOjF9ClcuRW8ucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIUMuTm0udGcoQy5CSSxILnkoYSkpfSwKJFM6OH0KVy5Xay5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJLEgueShhKSl9LAokUzo4fQpXLmN0LnBy
+b3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtpZih0aGlzLmpGKGEsYixjKSlyZXR1cm4hMAppZihi
+PT09InRlbXBsYXRlIiYmYz09PSIiKXJldHVybiEwCmlmKGEuZ2V0QXR0cmlidXRlKCJ0ZW1wbGF0ZSIp
+PT09IiIpcmV0dXJuIHRoaXMuZS50ZygwLGIpCnJldHVybiExfX0KVy5JQS5wcm90b3R5cGU9ewokMTpm
+dW5jdGlvbihhKXtyZXR1cm4iVEVNUExBVEU6OiIrSC5kKEgueShhKSl9LAokUzo2fQpXLk93LnByb3Rv
+dHlwZT17CmkwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuZXcuYyhhKSlyZXR1cm4hMQp0PXUuZzcuYyhh
+KQppZih0JiZXLnJTKGEpPT09ImZvcmVpZ25PYmplY3QiKXJldHVybiExCmlmKHQpcmV0dXJuITAKcmV0
+dXJuITF9LApFYjpmdW5jdGlvbihhLGIsYyl7aWYoYj09PSJpcyJ8fEMueEIubihiLCJvbiIpKXJldHVy
+biExCnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24o
+KXt2YXIgdD10aGlzLHM9dC5jKzEscj10LmIKaWYoczxyKXt0LnNwKEoudzIodC5hLHMpKQp0LmM9cwpy
+ZXR1cm4hMH10LnNwKG51bGwpCnQuYz1yCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
+cy5kfSwKc3A6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KVy5kVy5w
+cm90b3R5cGU9eyRpRDA6MSwkaXY2OjF9Clcua0YucHJvdG90eXBlPXt9ClcubWsucHJvdG90eXBlPXsk
+aXkwOjF9ClcuS28ucHJvdG90eXBlPXsKUG46ZnVuY3Rpb24oYSl7bmV3IFcuZm0odGhpcykuJDIoYSxu
+dWxsKX0sCkVQOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClKLkx0KGEpCmVsc2UgYi5yZW1vdmVDaGls
+ZChhKX0sCkk0OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPSEwLG49bnVsbCxtPW51bGwKdHJ5
+e249Si5pZyhhKQptPW4uYS5nZXRBdHRyaWJ1dGUoImlzIikKdS5oLmIoYSkKdD1mdW5jdGlvbihjKXtp
+ZighKGMuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkpcmV0dXJuIHRydWUKdmFyIGw9
+Yy5jaGlsZE5vZGVzCmlmKGMubGFzdENoaWxkJiZjLmxhc3RDaGlsZCE9PWxbbC5sZW5ndGgtMV0pcmV0
+dXJuIHRydWUKaWYoYy5jaGlsZHJlbilpZighKGMuY2hpbGRyZW4gaW5zdGFuY2VvZiBIVE1MQ29sbGVj
+dGlvbnx8Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIE5vZGVMaXN0KSlyZXR1cm4gdHJ1ZQp2YXIgaz0wCmlm
+KGMuY2hpbGRyZW4paz1jLmNoaWxkcmVuLmxlbmd0aApmb3IodmFyIGo9MDtqPGs7aisrKXt2YXIgaT1j
+LmNoaWxkcmVuW2pdCmlmKGkuaWQ9PSdhdHRyaWJ1dGVzJ3x8aS5uYW1lPT0nYXR0cmlidXRlcyd8fGku
+aWQ9PSdsYXN0Q2hpbGQnfHxpLm5hbWU9PSdsYXN0Q2hpbGQnfHxpLmlkPT0nY2hpbGRyZW4nfHxpLm5h
+bWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZhbHNlfShhKQpvPUgub1QodCk/ITA6IShh
+LmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApfWNhdGNoKHEpe0guUnUocSl9cz0iZWxl
+bWVudCB1bnByaW50YWJsZSIKdHJ5e3M9Si5qKGEpfWNhdGNoKHEpe0guUnUocSl9dHJ5e3I9Vy5yUyhh
+KQp0aGlzLmtSKHUuaC5iKGEpLGIsbyxzLHIsdS5HLmIobiksSC55KG0pKX1jYXRjaChxKXtpZihILlJ1
+KHEpIGluc3RhbmNlb2YgUC51KXRocm93IHEKZWxzZXt0aGlzLkVQKGEsYikKd2luZG93CnA9IlJlbW92
+aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5kKHMpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVk
+Iil3aW5kb3cuY29uc29sZS53YXJuKHApfX19LAprUjpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIg
+dCxzLHIscSxwLG8sbj10aGlzCmlmKGMpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZWxlbWVu
+dCBkdWUgdG8gY29ycnVwdGVkIGF0dHJpYnV0ZXMgb24gPCIrZCsiPiIKaWYodHlwZW9mIGNvbnNvbGUh
+PSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufWlmKCFuLmEuaTAoYSkpe24u
+RVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBlbGVtZW50IDwiK0guZChlKSsiPiBm
+cm9tICIrSC5kKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53
+YXJuKHQpCnJldHVybn1pZihnIT1udWxsKWlmKCFuLmEuRWIoYSwiaXMiLGcpKXtuLkVQKGEsYikKd2lu
+ZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24gPCIrSC5kKGUpKycgaXM9Iicr
+ZysnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHQp
+CnJldHVybn10PWYuZ1YoKQpzPUguVk0odC5zbGljZSgwKSxILnQ2KHQpLkMoImpkPDE+IikpCmZvcihy
+PWYuZ1YoKS5sZW5ndGgtMSx0PWYuYTtyPj0wOy0tcil7aWYocj49cy5sZW5ndGgpcmV0dXJuIEguT0go
+cyxyKQpxPXNbcl0KcD1uLmEKbz1KLmNIKHEpCkgueShxKQppZighcC5FYihhLG8sdC5nZXRBdHRyaWJ1
+dGUocSkpKXt3aW5kb3cKcD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBhdHRyaWJ1dGUgPCIrSC5kKGUpKyIg
+IitxKyc9IicrSC5kKHQuZ2V0QXR0cmlidXRlKHEpKSsnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0idW5k
+ZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApCnQucmVtb3ZlQXR0cmlidXRlKHEpfX1pZih1LmFX
+LmMoYSkpbi5QbihhLmNvbnRlbnQpfSwKJGlvbjoxfQpXLmZtLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9u
+KGEsYil7dmFyIHQscyxyLHEscD10aGlzLmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTpwLkk0KGEs
+YikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZhdWx0OnAuRVAoYSxi
+KX10PWEubGFzdENoaWxkCmZvcihwPXUuQTtudWxsIT10Oyl7cz1udWxsCnRyeXtzPXQucHJldmlvdXNT
+aWJsaW5nfWNhdGNoKHIpe0guUnUocikKcT1wLmIodCkKYS5yZW1vdmVDaGlsZChxKQp0PW51bGwKcz1h
+Lmxhc3RDaGlsZH1pZih0IT1udWxsKXRoaXMuJDIodCxhKQp0PXAuYihzKX19LAokUzoyOH0KVy5MZS5w
+cm90b3R5cGU9e30KVy5LNy5wcm90b3R5cGU9e30KVy5yQi5wcm90b3R5cGU9e30KVy5YVy5wcm90b3R5
+cGU9e30KVy5vYS5wcm90b3R5cGU9e30KUC5pSi5wcm90b3R5cGU9ewpWSDpmdW5jdGlvbihhKXt2YXIg
+dCxzPXRoaXMuYSxyPXMubGVuZ3RoCmZvcih0PTA7dDxyOysrdClpZihzW3RdPT09YSlyZXR1cm4gdApD
+Lk5tLmkocyxhKQpDLk5tLmkodGhpcy5iLG51bGwpCnJldHVybiByfSwKUHY6ZnVuY3Rpb24oYSl7dmFy
+IHQscyxyLHE9dGhpcyxwPXt9CmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoSC5sKGEpKXJldHVybiBhCmlm
+KHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEK
+aWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIG5ldyBEYXRlKGEuYSkKaWYodS5mdi5jKGEpKXRocm93
+IEguYihQLlNZKCJzdHJ1Y3R1cmVkIGNsb25lIG9mIFJlZ0V4cCIpKQppZih1LmM4LmMoYSkpcmV0dXJu
+IGEKaWYodS5kLmMoYSkpcmV0dXJuIGEKaWYodS5JLmMoYSkpcmV0dXJuIGEKdD11LmRELmMoYSl8fCEx
+CmlmKHQpcmV0dXJuIGEKaWYodS5HLmMoYSkpe3M9cS5WSChhKQp0PXEuYgppZihzPj10Lmxlbmd0aCly
+ZXR1cm4gSC5PSCh0LHMpCnI9cC5hPXRbc10KaWYociE9bnVsbClyZXR1cm4gcgpyPXt9CnAuYT1yCkMu
+Tm0uWSh0LHMscikKYS5LKDAsbmV3IFAubFIocCxxKSkKcmV0dXJuIHAuYX1pZih1LmouYyhhKSl7cz1x
+LlZIKGEpCnA9cS5iCmlmKHM+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscykKcj1wW3NdCmlmKHIhPW51
+bGwpcmV0dXJuIHIKcmV0dXJuIHEuZWsoYSxzKX1pZih1LmVILmMoYSkpe3M9cS5WSChhKQp0PXEuYgpp
+ZihzPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LHMpCnI9cC5iPXRbc10KaWYociE9bnVsbClyZXR1cm4g
+cgpyPXt9CnAuYj1yCkMuTm0uWSh0LHMscikKcS5pbShhLG5ldyBQLmpnKHAscSkpCnJldHVybiBwLmJ9
+dGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVrOmZ1bmN0
+aW9uKGEsYil7dmFyIHQscz1KLlU2KGEpLHI9cy5nQShhKSxxPW5ldyBBcnJheShyKQpDLk5tLlkodGhp
+cy5iLGIscSkKZm9yKHQ9MDt0PHI7Kyt0KUMuTm0uWShxLHQsdGhpcy5QdihzLnEoYSx0KSkpCnJldHVy
+biBxfX0KUC5sUi5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5hW2FdPXRoaXMuYi5Q
+dihiKX0sCiRTOjF9ClAuamcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYlthXT10
+aGlzLmIuUHYoYil9LAokUzoxfQpQLkJmLnByb3RvdHlwZT17CmltOmZ1bmN0aW9uKGEsYil7dmFyIHQs
+cyxyLHEKdS5iOC5iKGIpCmZvcih0PU9iamVjdC5rZXlzKGEpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ip
+e3E9dFtyXQpiLiQyKHEsYVtxXSl9fX0KUC5Bcy5wcm90b3R5cGU9ewpUOmZ1bmN0aW9uKGEpe3ZhciB0
+CkgueShhKQp0PSQuaEcoKS5iCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILnZoKEgudEwoYSkpCmlmKHQu
+dGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhhLCJ2YWx1ZSIsIk5vdCBhIHZhbGlkIGNsYXNz
+IHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5QKCkuSCgwLCIgIil9LApna3o6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9dGhpcy5QKCkKcmV0dXJuIFAucmoodCx0LnIsSC5MaCh0KS5kKX0sCmdBOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLlAoKS5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt0aGlzLlQoYikKcmV0
+dXJuIHRoaXMuUCgpLnRnKDAsYil9LAppOmZ1bmN0aW9uKGEsYil7dGhpcy5UKGIpCnJldHVybiBILnhk
+KHRoaXMuT1MobmV3IFAuR0UoYikpKX0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCnRoaXMuVChiKQp0
+PXRoaXMuUCgpCnM9dC5SKDAsYikKdGhpcy5YKHQpCnJldHVybiBzfSwKRlY6ZnVuY3Rpb24oYSxiKXt0
+aGlzLk9TKG5ldyBQLk43KHRoaXMsdS5YLmIoYikpKX0sClYxOmZ1bmN0aW9uKGEpe3RoaXMuT1MobmV3
+IFAudVEoKSl9LApPUzpmdW5jdGlvbihhKXt2YXIgdCxzCnUuY2guYihhKQp0PXRoaXMuUCgpCnM9YS4k
+MSh0KQp0aGlzLlgodCkKcmV0dXJuIHN9fQpQLkdFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Jl
+dHVybiB1LkMuYihhKS5pKDAsdGhpcy5hKX0sCiRTOjM3fQpQLk43LnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuYixzPUgudDYodCkKcmV0dXJuIHUuQy5iKGEpLkZWKDAsbmV3IEguQTgo
+dCxzLkMoInFVKDEpIikuYih0aGlzLmEuZ3VNKCkpLHMuQygiQTg8MSxxVT4iKSkpfSwKJFM6MTR9ClAu
+dVEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5DLmIoYSkKaWYoYS5hPjApe2EuYj1hLmM9YS5k
+PWEuZT1hLmY9bnVsbAphLmE9MAphLlMoKX1yZXR1cm59LAokUzoxNH0KUC5oRi5wcm90b3R5cGU9eyRp
+aEY6MX0KUC5QQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlouYihhKQp0PWZ1bmN0
+aW9uKGIsYyxkKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gYihjLGQsdGhpcyxBcnJheS5wcm90b3R5
+cGUuc2xpY2UuYXBwbHkoYXJndW1lbnRzKSl9fShQLlI0LGEsITEpClAuRG0odCwkLncoKSxhKQpyZXR1
+cm4gdH0sCiRTOjR9ClAuWW0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyB0aGlz
+LmEoYSl9LAokUzo0fQpQLk56LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5y
+NyhhKX0sCiRTOjMxfQpQLlFTLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5U
+eihhLHUuYW0pfSwKJFM6MzJ9ClAubnAucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
+dyBQLkU0KGEpfSwKJFM6MzN9ClAuRTQucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe2lmKHR5cGVv
+ZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBp
+cyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnJldHVybiBQLkw3KHRoaXMuYVtiXSl9LApZOmZ1bmN0aW9u
+KGEsYixjKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBILmIo
+UC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51bSIpKQp0aGlzLmFbYl09UC53WShjKX0s
+CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAu
+RTQmJnRoaXMuYT09PWIuYX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscwp0cnl7dD1TdHJpbmcodGhpcy5h
+KQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpCnQ9dGhpcy54YigwKQpyZXR1cm4gdH19LApWNzpmdW5j
+dGlvbihhLGIpe3ZhciB0LHM9dGhpcy5hCmlmKGI9PW51bGwpdD1udWxsCmVsc2V7dD1ILnQ2KGIpCnQ9
+UC5DSChuZXcgSC5BOChiLHQuQygiQCgxKSIpLmIoUC5pRygpKSx0LkMoIkE4PDEsQD4iKSksITAsdS56
+KX1yZXR1cm4gUC5MNyhzW2FdLmFwcGx5KHMsdCkpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfX0K
+UC5yNy5wcm90b3R5cGU9e30KUC5Uei5wcm90b3R5cGU9ewpjUDpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+LHM9YTwwfHxhPj10LmdBKHQpCmlmKHMpdGhyb3cgSC5iKFAuVEUoYSwwLHQuZ0EodCksbnVsbCxudWxs
+KSl9LApxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PSJudW1iZXIiJiZiPT09Qy5qbi55dShiKSl0
+aGlzLmNQKEguU2MoYikpCnJldHVybiB0aGlzLiR0aS5kLmIodGhpcy5VcigwLGIpKX0sClk6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0CnRoaXMuJHRpLmQuYihjKQp0PUMuam4ueXUoYikKaWYoYj09PXQpdGhpcy5j
+UChiKQp0aGlzLmU0KDAsYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5sZW5ndGgKaWYo
+dHlwZW9mIHQ9PT0ibnVtYmVyIiYmdD4+PjA9PT10KXJldHVybiB0CnRocm93IEguYihQLlBWKCJCYWQg
+SnNBcnJheSBsZW5ndGgiKSl9LAokaWNYOjEsCiRpek06MX0KUC5jby5wcm90b3R5cGU9e30KUC5uZC5w
+cm90b3R5cGU9eyRpbmQ6MX0KUC5LZS5wcm90b3R5cGU9ewpQOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEs
+cD10aGlzLmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpLG89UC5Mcyh1Lk4pCmlmKHA9PW51bGwpcmV0dXJu
+IG8KZm9yKHQ9cC5zcGxpdCgiICIpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQpp
+ZihxLmxlbmd0aCE9PTApby5pKDAscSl9cmV0dXJuIG99LApYOmZ1bmN0aW9uKGEpe3RoaXMuYS5zZXRB
+dHRyaWJ1dGUoImNsYXNzIixhLkgoMCwiICIpKX19ClAuZDUucHJvdG90eXBlPXsKZ0Q6ZnVuY3Rpb24o
+YSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5ZQyhhLGIpfSwKcjY6
+ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGQ9PW51bGwpe3Q9SC5WTShbXSx1Lm0p
+CmQ9bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQsVy5CbCgpKQpDLk5tLmko
+dCxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnM9JzxzdmcgdmVyc2lvbj0iMS4xIj4nK0guZChiKSsi
+PC9zdmc+Igp0PWRvY3VtZW50CnI9dC5ib2R5CnE9KHImJkMuUlkpLkFIKHIscyxjKQpwPXQuY3JlYXRl
+RG9jdW1lbnRGcmFnbWVudCgpCnEudG9TdHJpbmcKdD1uZXcgVy5lNyhxKQpvPXQuZ3I4KHQpCmZvcig7
+dD1vLmZpcnN0Q2hpbGQsdCE9bnVsbDspcC5hcHBlbmRDaGlsZCh0KQpyZXR1cm4gcH0sCmdWbDpmdW5j
+dGlvbihhKXtyZXR1cm4gbmV3IFcuQ3EoYSwiY2xpY2siLCExLHUuUSl9LAokaWQ1OjF9ClAubjYucHJv
+dG90eXBlPXskaWNYOjEsJGl6TToxLCRpQVM6MX0KVS5kMi5wcm90b3R5cGU9e30KVS5TZS5wcm90b3R5
+cGU9e30KVS51Ri5wcm90b3R5cGU9e30KVS5NbC5wcm90b3R5cGU9e30KVS55RC5wcm90b3R5cGU9e30K
+VS53Yi5wcm90b3R5cGU9e30KVC5HVi5wcm90b3R5cGU9e30KTC5lLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscixxLHAsbwp1LkIuYihhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpz
+PUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKTC5H
+ZSgpCmlmKHQhPT0iLyImJnQhPT1KLlQwKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4
+dENvbnRlbnQpKUwuRzcodCxzLHIsbmV3IEwuVlcodCxzLHIpKQpxPUoucUYoZG9jdW1lbnQucXVlcnlT
+ZWxlY3RvcigiLmFwcGx5LW1pZ3JhdGlvbiIpKQpwPXEuJHRpCm89cC5DKCJ+KDEpIikuYihuZXcgTC5v
+WigpKQp1Lk0uYihudWxsKQpXLkpFKHEuYSxxLmIsbywhMSxwLmQpfSwKJFM6MTN9CkwuVlcucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjB9Ckwub1ou
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5WLmIoYSkKTC50eSgiL2FwcGx5LW1pZ3JhdGlvbiIp
+Llc3KG5ldyBMLmpyKCksdS5QKS5PQShuZXcgTC5xbCgpKX0sCiRTOjV9CkwuanIucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5yLmIoYSkKdD1kb2N1bWVudC5ib2R5CnQuY2xhc3NMaXN0LnJl
+bW92ZSgicHJvcG9zZWQiKQp0LmNsYXNzTGlzdC5hZGQoImFwcGxpZWQiKX0sCiRTOjd9CkwucWwucHJv
+dG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJhcHBseSBtaWdyYXRpb24gZXJyb3I6ICIrSC5k
+KGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGFwcGx5IG1pZ3JhdGlvbiAoIitILmQoYSkrIiku
+Iil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLkwucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHQscyxyCnUuQi5iKGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9j
+YXRpb24uaHJlZikKcj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZih0Lmxlbmd0aD4xKUwuRzco
+dCxzLHIsbnVsbCkKZWxzZXtMLkJFKHQsUC5FRihbInJlZ2lvbnMiLCIiLCJuYXZpZ2F0aW9uQ29udGVu
+dCIsIiIsImVkaXRzIixbXV0sdS5OLHUueikpCkwuQlgoIiZuYnNwOyIsbnVsbCl9fSwKJFM6MTN9Ckwu
+V3gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9ImNvbGxhcHNlZCIKdS5WLmIo
+YSkKdD10aGlzLmEKcz1KLlJFKHQpCnI9dGhpcy5iCmlmKCFzLmdEKHQpLnRnKDAscSkpe3MuZ0QodCku
+aSgwLHEpCkouZFIocikuaSgwLHEpfWVsc2V7cy5nRCh0KS5SKDAscSkKSi5kUihyKS5SKDAscSl9fSwK
+JFM6NX0KTC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD1KLnFGKHUuaC5iKGEpKSxz
+PXQuJHRpLHI9cy5DKCJ+KDEpIikuYihuZXcgTC5kTigpKQp1Lk0uYihudWxsKQpXLkpFKHQuYSx0LmIs
+ciwhMSxzLmQpfSwKJFM6M30KTC5kTi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlYu
+YihhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQp0LnRvU3RyaW5n
+CkwudDIoYSx0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJwYXRo
+IikpKX0sCiRTOjV9CkwuSG8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUuaC5i
+KGEpCnQ9Si5xRihhKQpzPXQuJHRpCnI9cy5DKCJ+KDEpIikuYihuZXcgTC54eihhLHRoaXMuYSkpCnUu
+TS5iKG51bGwpClcuSkUodC5hLHQuYixyLCExLHMuZCl9LAokUzozfQpMLnh6LnByb3RvdHlwZT17CiQx
+OmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5iKGEpCnQ9dGhpcy5hCkwuaFgodGhpcy5iLFAuUUEodC5nZXRB
+dHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygib2Zmc2V0IikpLG51bGwsbnVs
+bCkpfSwKJFM6NX0KTC5JQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD1KLnFGKHUuaC5i
+KGEpKSxzPXQuJHRpCnMuQygifigxKSIpLmIoTC5IMCgpKQp1Lk0uYihudWxsKQpXLkpFKHQuYSx0LmIs
+TC5IMCgpLCExLHMuZCl9LAokUzozfQpMLkwxLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0
+CnUuci5iKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMClyZXR1cm4gYQplbHNlIHRocm93IEguYigiUmVx
+dWVzdCBmYWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzozOH0KTC5uVC5wcm90b3R5cGU9ewok
+MDpmdW5jdGlvbigpe0wuRnIodGhpcy5hLmEsdGhpcy5iLHRoaXMuYyl9LAokUzowfQpMLkJaLnByb3Rv
+dHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEuYSxudWxsLG51bGwpfSwKJFM6MH0KTC5GUS5w
+cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wucUooImhhbmRsZVBvc3RMaW5rQ2xpY2s6ICIrSC5k
+KGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIitILmQodGhpcy5hKSsiICgiK0guZChh
+KSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9CkwuR0gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7dS5oLmIoYSkKJC56QigpLnRvU3RyaW5nCnUudS5iKCQub3coKS5xKDAsImhsanMiKSkuVjcoImhp
+Z2hsaWdodEJsb2NrIixbYV0pfSwKJFM6M30KTC5EVC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
+YXIgdAp1LnIuYihhKQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDApe0wuVDEoVS55dShDLkN0LnBXKDAsYS5y
+ZXNwb25zZVRleHQsbnVsbCkpKQpMLnlYKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVudCIpfWVsc2Ug
+d2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9mICIrSC5kKHQpKX0sCiRTOjd9Ckwu
+ZUgucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2FkUmVnaW9uRXhwbGFuYXRpb246
+ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIitILmQodGhpcy5hKSsiICgi
+K0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9CkwuekQucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyPXRoaXMKdS5yLmIoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPXIu
+YQpMLkJFKHMsdS5hLmIoQy5DdC5wVygwLGEucmVzcG9uc2VUZXh0LG51bGwpKSkKdD1yLmIKTC5mRyh0
+LHIuYykKTC5CWChDLnhCLnRnKHMsIj8iKT9DLnhCLk5qKHMsMCxDLnhCLk9ZKHMsIj8iKSk6cyx0KQp0
+PXIuZAppZih0IT1udWxsKXQuJDAoKX1lbHNlIHdpbmRvdy5hbGVydCgiUmVxdWVzdCBmYWlsZWQ7IHN0
+YXR1cyBvZiAiK0guZCh0KSl9LAokUzo3fQpMLk9FLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
+TC5xSigibG9hZEZpbGU6ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIit0
+aGlzLmErIiAoIitILmQoYSkrIikuIil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLlRXLnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LnIuYihhKQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDAp
+e3M9Qy5DdC5wVygwLGEucmVzcG9uc2VUZXh0LG51bGwpCnI9ZG9jdW1lbnQucXVlcnlTZWxlY3Rvcigi
+Lm5hdi10cmVlIikKSi5sNShyLCIiKQpMLnRYKHIscyl9ZWxzZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3Qg
+ZmFpbGVkOyBzdGF0dXMgb2YgIitILmQodCkpfSwKJFM6N30KTC54ci5wcm90b3R5cGU9ewokMjpmdW5j
+dGlvbihhLGIpe0wucUooImxvYWROYXZpZ2F0aW9uVHJlZTogIitILmQoYSksYikKd2luZG93LmFsZXJ0
+KCJDb3VsZCBub3QgbG9hZCAiK3RoaXMuYSsiICgiK0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIs
+CiRTOjF9CkwuRUUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp1LlYuYihhKQp0PXRo
+aXMuYQpzPXRoaXMuYgpMLmFmKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSx0LHMsbmV3IEwuUUwodCxz
+KSkKTC5oWCh0aGlzLmMsdCl9LAokUzo1fQpMLlFMLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5G
+cih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsdGhpcy5hLHRoaXMuYil9LAokUzowfQpMLlZTLnByb3Rv
+dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHM9InNlbGVjdGVkLWZpbGUiCnUuaC5iKGEpCmEudG9T
+dHJpbmcKdD1KLlJFKGEpCmlmKGEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTco
+YSkpLk8oIm5hbWUiKSk9PT10aGlzLmEuYSl0LmdEKGEpLmkoMCxzKQplbHNlIHQuZ0QoYSkuUigwLHMp
+fSwKJFM6M30KTC5YQS5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuITB9LAppMDpm
+dW5jdGlvbihhKXtyZXR1cm4hMH0sCiRpa0Y6MX0KTS5sSS5wcm90b3R5cGU9ewpXTzpmdW5jdGlvbihh
+LGIpe3ZhciB0LHM9bnVsbApNLllGKCJhYnNvbHV0ZSIsSC5WTShbYixudWxsLG51bGwsbnVsbCxudWxs
+LG51bGwsbnVsbF0sdS5zKSkKdD10aGlzLmEKdD10LllyKGIpPjAmJiF0LmhLKGIpCmlmKHQpcmV0dXJu
+IGIKdD1ELlJYKCkKcmV0dXJuIHRoaXMucTcoMCx0LGIscyxzLHMscyxzLHMpfSwKdE06ZnVuY3Rpb24o
+YSl7dmFyIHQscyxyPVguQ0woYSx0aGlzLmEpCnIuSVYoKQp0PXIuZApzPXQubGVuZ3RoCmlmKHM9PT0w
+KXt0PXIuYgpyZXR1cm4gdD09bnVsbD8iLiI6dH1pZihzPT09MSl7dD1yLmIKcmV0dXJuIHQ9PW51bGw/
+Ii4iOnR9aWYoMD49cylyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCkMuTm0ubXYoci5lKQpyLklWKCkK
+cmV0dXJuIHIudygwKX0sCnE3OmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcsaCxpKXt2YXIgdD1ILlZNKFti
+LGMsZCxlLGYsZyxoLGldLHUucykKTS5ZRigiam9pbiIsdCkKcmV0dXJuIHRoaXMuSVAobmV3IEguVTUo
+dCx1LmJCLmIobmV3IE0uTWkoKSksdS5jYykpfSwKSVA6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxv
+LG4sbSxsCnUuWC5iKGEpCmZvcih0PWEuJHRpLHM9dC5DKCJhMihjWC5FKSIpLmIobmV3IE0ucTcoKSks
+cj1hLmdreihhKSx0PW5ldyBILlNPKHIscyx0LkMoIlNPPGNYLkU+IikpLHM9dGhpcy5hLHE9ITEscD0h
+MSxvPSIiO3QuRigpOyl7bj1yLmdsKCkKaWYocy5oSyhuKSYmcCl7bT1YLkNMKG4scykKbD1vLmNoYXJD
+b2RlQXQoMCk9PTA/bzpvCm89Qy54Qi5OaihsLDAscy5TcChsLCEwKSkKbS5iPW8KaWYocy5kcyhvKSlD
+Lk5tLlkobS5lLDAscy5nbUkoKSkKbz1tLncoMCl9ZWxzZSBpZihzLllyKG4pPjApe3A9IXMuaEsobikK
+bz1ILmQobil9ZWxzZXtpZighKG4ubGVuZ3RoPjAmJnMuVWQoblswXSkpKWlmKHEpbys9cy5nbUkoKQpv
+Kz1ILmQobil9cT1zLmRzKG4pfXJldHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpvfSwKbzU6ZnVuY3Rp
+b24oYSl7dmFyIHQKaWYoIXRoaXMueTMoYSkpcmV0dXJuIGEKdD1YLkNMKGEsdGhpcy5hKQp0LnJSKCkK
+cmV0dXJuIHQudygwKX0sCnkzOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrCmEudG9T
+dHJpbmcKdD10aGlzLmEKcz10LllyKGEpCmlmKHMhPT0wKXtpZih0PT09JC5LaygpKWZvcihyPTA7cjxz
+OysrcilpZihDLnhCLlcoYSxyKT09PTQ3KXJldHVybiEwCnE9cwpwPTQ3fWVsc2V7cT0wCnA9bnVsbH1m
+b3Iobz1uZXcgSC5xaihhKS5hLG49by5sZW5ndGgscj1xLG09bnVsbDtyPG47KytyLG09cCxwPWwpe2w9
+Qy54Qi5tKG8scikKaWYodC5yNChsKSl7aWYodD09PSQuS2soKSYmbD09PTQ3KXJldHVybiEwCmlmKHAh
+PW51bGwmJnQucjQocCkpcmV0dXJuITAKaWYocD09PTQ2KWs9bT09bnVsbHx8bT09PTQ2fHx0LnI0KG0p
+CmVsc2Ugaz0hMQppZihrKXJldHVybiEwfX1pZihwPT1udWxsKXJldHVybiEwCmlmKHQucjQocCkpcmV0
+dXJuITAKaWYocD09PTQ2KXQ9bT09bnVsbHx8dC5yNChtKXx8bT09PTQ2CmVsc2UgdD0hMQppZih0KXJl
+dHVybiEwCnJldHVybiExfSwKSFA6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89dGhpcyxuPSdV
+bmFibGUgdG8gZmluZCBhIHBhdGggdG8gIicKYj1vLldPKDAsYikKdD1vLmEKaWYodC5ZcihiKTw9MCYm
+dC5ZcihhKT4wKXJldHVybiBvLm81KGEpCmlmKHQuWXIoYSk8PTB8fHQuaEsoYSkpYT1vLldPKDAsYSkK
+aWYodC5ZcihhKTw9MCYmdC5ZcihiKT4wKXRocm93IEguYihYLkpUKG4rSC5kKGEpKyciIGZyb20gIicr
+SC5kKGIpKyciLicpKQpzPVguQ0woYix0KQpzLnJSKCkKcj1YLkNMKGEsdCkKci5yUigpCnE9cy5kCmlm
+KHEubGVuZ3RoPjAmJkouUk0ocVswXSwiLiIpKXJldHVybiByLncoMCkKcT1zLmIKcD1yLmIKaWYocSE9
+cClxPXE9PW51bGx8fHA9PW51bGx8fCF0Lk5jKHEscCkKZWxzZSBxPSExCmlmKHEpcmV0dXJuIHIudygw
+KQp3aGlsZSghMCl7cT1zLmQKaWYocS5sZW5ndGg+MCl7cD1yLmQKcT1wLmxlbmd0aD4wJiZ0Lk5jKHFb
+MF0scFswXSl9ZWxzZSBxPSExCmlmKCFxKWJyZWFrCkMuTm0uVzQocy5kLDApCkMuTm0uVzQocy5lLDEp
+CkMuTm0uVzQoci5kLDApCkMuTm0uVzQoci5lLDEpfXE9cy5kCmlmKHEubGVuZ3RoPjAmJkouUk0ocVsw
+XSwiLi4iKSl0aHJvdyBILmIoWC5KVChuK0guZChhKSsnIiBmcm9tICInK0guZChiKSsnIi4nKSkKcT11
+Lk4KQy5ObS5VRyhyLmQsMCxQLk84KHMuZC5sZW5ndGgsIi4uIixxKSkKQy5ObS5ZKHIuZSwwLCIiKQpD
+Lk5tLlVHKHIuZSwxLFAuTzgocy5kLmxlbmd0aCx0LmdtSSgpLHEpKQp0PXIuZApxPXQubGVuZ3RoCmlm
+KHE9PT0wKXJldHVybiIuIgppZihxPjEmJkouUk0oQy5ObS5ncloodCksIi4iKSl7dD1yLmQKaWYoMD49
+dC5sZW5ndGgpcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQp0PXIuZQpDLk5tLm12KHQpCkMuTm0ubXYo
+dCkKQy5ObS5pKHQsIiIpfXIuYj0iIgpyLklWKCkKcmV0dXJuIHIudygwKX19Ck0uTWkucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEgueShhKSE9bnVsbH0sCiRTOjh9Ck0ucTcucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEgueShhKSE9PSIifSwKJFM6OH0KTS5Oby5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXtILnkoYSkKcmV0dXJuIGE9PW51bGw/Im51bGwiOiciJythKyciJ30sCiRT
+OjZ9CkIuTHUucHJvdG90eXBlPXsKeFo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLllyKGEpCmlmKHM+
+MClyZXR1cm4gSi5sZChhLDAscykKaWYodGhpcy5oSyhhKSl7aWYoMD49YS5sZW5ndGgpcmV0dXJuIEgu
+T0goYSwwKQp0PWFbMF19ZWxzZSB0PW51bGwKcmV0dXJuIHR9LApOYzpmdW5jdGlvbihhLGIpe3JldHVy
+biBhPT1ifX0KWC5XRC5wcm90b3R5cGU9ewpJVjpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlzCndoaWxl
+KCEwKXt0PXIuZAppZighKHQubGVuZ3RoIT09MCYmSi5STShDLk5tLmdyWih0KSwiIikpKWJyZWFrCnQ9
+ci5kCmlmKDA+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKQy5ObS5tdihyLmUpfXQ9
+ci5lCnM9dC5sZW5ndGgKaWYocz4wKUMuTm0uWSh0LHMtMSwiIil9LApyUjpmdW5jdGlvbigpe3ZhciB0
+LHMscixxLHAsbyxuLG09dGhpcyxsPUguVk0oW10sdS5zKQpmb3IodD1tLmQscz10Lmxlbmd0aCxyPTAs
+cT0wO3E8dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK3Epe3A9dFtxXQpvPUouaWEo
+cCkKaWYoIShvLkROKHAsIi4iKXx8by5ETihwLCIiKSkpaWYoby5ETihwLCIuLiIpKWlmKGwubGVuZ3Ro
+PjApbC5wb3AoKQplbHNlICsrcgplbHNlIEMuTm0uaShsLHApfWlmKG0uYj09bnVsbClDLk5tLlVHKGws
+MCxQLk84KHIsIi4uIix1Lk4pKQppZihsLmxlbmd0aD09PTAmJm0uYj09bnVsbClDLk5tLmkobCwiLiIp
+Cm49UC5kSChsLmxlbmd0aCxuZXcgWC5xUihtKSwhMCx1Lk4pCnQ9bS5iCnQ9dCE9bnVsbCYmbC5sZW5n
+dGg+MCYmbS5hLmRzKHQpP20uYS5nbUkoKToiIgpILnQ2KG4pLmQuYih0KQppZighIW4uZml4ZWQkbGVu
+Z3RoKUgudmgoUC5MNCgiaW5zZXJ0IikpCm4uc3BsaWNlKDAsMCx0KQptLnNuSihsKQptLnNQaChuKQp0
+PW0uYgppZih0IT1udWxsJiZtLmE9PT0kLktrKCkpe3QudG9TdHJpbmcKbS5iPUgueXModCwiLyIsIlxc
+Iil9bS5JVigpfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcyxxPXIuYgpxPXEhPW51bGw/cToi
+Igpmb3IodD0wO3Q8ci5kLmxlbmd0aDsrK3Qpe3M9ci5lCmlmKHQ+PXMubGVuZ3RoKXJldHVybiBILk9I
+KHMsdCkKcz1xK0guZChzW3RdKQpxPXIuZAppZih0Pj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLHQpCnE9
+cytILmQocVt0XSl9cSs9SC5kKEMuTm0uZ3JaKHIuZSkpCnJldHVybiBxLmNoYXJDb2RlQXQoMCk9PTA/
+cTpxfSwKc25KOmZ1bmN0aW9uKGEpe3RoaXMuZD11LmkuYihhKX0sCnNQaDpmdW5jdGlvbihhKXt0aGlz
+LmU9dS5pLmIoYSl9fQpYLnFSLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
+YS5nbUkoKX0sCiRTOjM5fQpYLmR2LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlBhdGhF
+eGNlcHRpb246ICIrdGhpcy5hfX0KTy56TC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0
+aGlzLmdvYyh0aGlzKX19CkUuT0YucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIu
+dGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3Zh
+ciB0PWEubGVuZ3RoCnJldHVybiB0IT09MCYmQy54Qi5tKGEsdC0xKSE9PTQ3fSwKU3A6ZnVuY3Rpb24o
+YSxiKXtpZihhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKcmV0dXJuIDB9LApZ
+cjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiEx
+fSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuInBvc2l4In0sCmdtSTpmdW5jdGlvbigpe3JldHVybiIvIn19
+CkYucnUucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6
+ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3ZhciB0PWEubGVuZ3RoCmlm
+KHQ9PT0wKXJldHVybiExCmlmKEMueEIubShhLHQtMSkhPT00NylyZXR1cm4hMApyZXR1cm4gQy54Qi5U
+YyhhLCI6Ly8iKSYmdGhpcy5ZcihhKT09PXR9LApTcDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9
+YS5sZW5ndGgKaWYocD09PTApcmV0dXJuIDAKaWYoQy54Qi5XKGEsMCk9PT00NylyZXR1cm4gMQpmb3Io
+dD0wO3Q8cDsrK3Qpe3M9Qy54Qi5XKGEsdCkKaWYocz09PTQ3KXJldHVybiAwCmlmKHM9PT01OCl7aWYo
+dD09PTApcmV0dXJuIDAKcj1DLnhCLlhVKGEsIi8iLEMueEIuUWkoYSwiLy8iLHQrMSk/dCszOnQpCmlm
+KHI8PTApcmV0dXJuIHAKaWYoIWJ8fHA8ciszKXJldHVybiByCmlmKCFDLnhCLm4oYSwiZmlsZTovLyIp
+KXJldHVybiByCmlmKCFCLll1KGEscisxKSlyZXR1cm4gcgpxPXIrMwpyZXR1cm4gcD09PXE/cTpyKzR9
+fXJldHVybiAwfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlv
+bihhKXtyZXR1cm4gYS5sZW5ndGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3fSwKZ29jOmZ1bmN0aW9uKCl7
+cmV0dXJuInVybCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpMLklWLnByb3RvdHlwZT17ClVk
+OmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBh
+PT09NDd8fGE9PT05Mn0sCmRzOmZ1bmN0aW9uKGEpe3ZhciB0PWEubGVuZ3RoCmlmKHQ9PT0wKXJldHVy
+biExCnQ9Qy54Qi5tKGEsdC0xKQpyZXR1cm4hKHQ9PT00N3x8dD09PTkyKX0sClNwOmZ1bmN0aW9uKGEs
+Yil7dmFyIHQscyxyPWEubGVuZ3RoCmlmKHI9PT0wKXJldHVybiAwCnQ9Qy54Qi5XKGEsMCkKaWYodD09
+PTQ3KXJldHVybiAxCmlmKHQ9PT05Mil7aWYocjwyfHxDLnhCLlcoYSwxKSE9PTkyKXJldHVybiAxCnM9
+Qy54Qi5YVShhLCJcXCIsMikKaWYocz4wKXtzPUMueEIuWFUoYSwiXFwiLHMrMSkKaWYocz4wKXJldHVy
+biBzfXJldHVybiByfWlmKHI8MylyZXR1cm4gMAppZighQi5PUyh0KSlyZXR1cm4gMAppZihDLnhCLlco
+YSwxKSE9PTU4KXJldHVybiAwCnI9Qy54Qi5XKGEsMikKaWYoIShyPT09NDd8fHI9PT05MikpcmV0dXJu
+IDAKcmV0dXJuIDN9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0
+aW9uKGEpe3JldHVybiB0aGlzLllyKGEpPT09MX0sCk90OmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYT09
+PWIpcmV0dXJuITAKaWYoYT09PTQ3KXJldHVybiBiPT09OTIKaWYoYT09PTkyKXJldHVybiBiPT09NDcK
+aWYoKGFeYikhPT0zMilyZXR1cm4hMQp0PWF8MzIKcmV0dXJuIHQ+PTk3JiZ0PD0xMjJ9LApOYzpmdW5j
+dGlvbihhLGIpe3ZhciB0LHMscgppZihhPT1iKXJldHVybiEwCnQ9YS5sZW5ndGgKaWYodCE9PWIubGVu
+Z3RoKXJldHVybiExCmZvcihzPUouclkoYikscj0wO3I8dDsrK3IpaWYoIXRoaXMuT3QoQy54Qi5XKGEs
+cikscy5XKGIscikpKXJldHVybiExCnJldHVybiEwfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuIndpbmRv
+d3MifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIlxcIn19OyhmdW5jdGlvbiBhbGlhc2VzKCl7dmFyIHQ9
+Si52Qi5wcm90b3R5cGUKdC5VPXQudwp0LlNqPXQuZTcKdD1KLk1GLnByb3RvdHlwZQp0LnQ9dC53CnQ9
+UC5jWC5wcm90b3R5cGUKdC5HRz10LmV2CnQ9UC5rLnByb3RvdHlwZQp0LnhiPXQudwp0PVcuY3YucHJv
+dG90eXBlCnQuRFc9dC5yNgp0PVcubTYucHJvdG90eXBlCnQuakY9dC5FYgp0PVAuRTQucHJvdG90eXBl
+CnQuVXI9dC5xCnQuZTQ9dC5ZfSkoKTsoZnVuY3Rpb24gaW5zdGFsbFRlYXJPZmZzKCl7dmFyIHQ9aHVu
+a0hlbHBlcnMuX3N0YXRpY18xLHM9aHVua0hlbHBlcnMuX3N0YXRpY18wLHI9aHVua0hlbHBlcnMuaW5z
+dGFsbEluc3RhbmNlVGVhck9mZixxPWh1bmtIZWxwZXJzLmluc3RhbGxTdGF0aWNUZWFyT2ZmLHA9aHVu
+a0hlbHBlcnMuX2luc3RhbmNlXzF1CnQoUCwiRVgiLCJaViIsOSkKdChQLCJ5dCIsIm9BIiw5KQp0KFAs
+InFXIiwiQnoiLDkpCnMoUCwiVUkiLCJlTiIsMikKcihQLlBmLnByb3RvdHlwZSwiZ1lKIiwwLDEsbnVs
+bCxbIiQyIiwiJDEiXSxbIncwIiwicG0iXSwzNiwwKQp0KFAsIlBIIiwiTXQiLDYpCnEoVywicFMiLDQs
+bnVsbCxbIiQ0Il0sWyJ5VyJdLDExLDApCnEoVywiVjQiLDQsbnVsbCxbIiQ0Il0sWyJRVyJdLDExLDAp
+CnAoUC5Bcy5wcm90b3R5cGUsImd1TSIsIlQiLDYpCnQoUCwiaUciLCJ3WSIsNCkKdChQLCJ3MCIsIkw3
+Iiw0MikKcShMLCJYTiIsMSxudWxsLFsiJDIkcmVsYXRpdmVUbyIsIiQxIl0sWyJ0MiIsZnVuY3Rpb24o
+YSl7cmV0dXJuIEwudDIoYSxudWxsKX1dLDQzLDApCnQoTCwiSDAiLCJ1bSIsMjkpfSkoKTsoZnVuY3Rp
+b24gaW5oZXJpdGFuY2UoKXt2YXIgdD1odW5rSGVscGVycy5taXhpbixzPWh1bmtIZWxwZXJzLmluaGVy
+aXQscj1odW5rSGVscGVycy5pbmhlcml0TWFueQpzKFAuayxudWxsKQpyKFAuayxbSC5lbyxKLnZCLEou
+bTEsUC5uWSxQLmNYLEguYTcsUC5BbixILlNVLEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILlRwLEgu
+WnIsUC5YUyxILlhPLFAuWWssSC5kYixILk42LEguVlIsSC5FSyxILlBiLEgudFEsSC5TZCxILkpjLEgu
+RyxQLlczLFAuUGYsUC5GZSxQLnZzLFAuT00sUC5xaCxQLk1PLFAua1QsUC5DdyxQLm0wLFAuWHYsUC5i
+bixQLmxtLFAubEQsUC5LUCxQLmxmLFAuV1ksUC5VayxQLlJ3LFAuYnosUC5hMixQLmlQLFAuRkssUC5r
+NSxQLktZLFAuQ0QsUC5hRSxQLkVILFAuek0sUC5aMCxQLmM4LFAuT2QsUC5pYixQLkd6LFAucVUsUC5S
+bixQLkdELFAuRG4sUC5QRSxQLlVmLFcuaWQsVy5GayxXLkpRLFcuR20sVy52RCxXLm02LFcuT3csVy5X
+OSxXLmRXLFcua0YsVy5tayxXLktvLFAuaUosUC5FNCxQLm42LFUuZDIsVS5TZSxVLnVGLFUuTWwsVS55
+RCxVLndiLFQuR1YsTC5YQSxNLmxJLE8uekwsWC5XRCxYLmR2XSkKcihKLnZCLFtKLnlFLEouWUUsSi5N
+RixKLmpkLEoucUksSi5EcixILkVULFcuRDAsVy5BeixXLkxlLFcuTmgsVy5JQixXLm43LFcuZWEsVy5i
+cixXLlNnLFcudTgsVy5LNyxXLlhXLFAuaEZdKQpyKEouTUYsW0ouaUMsSi5rZCxKLmM1XSkKcyhKLlBv
+LEouamQpCnIoSi5xSSxbSi51cixKLlZBXSkKcyhQLkxVLFAublkpCnIoUC5MVSxbSC5YQyxXLnd6LFcu
+ZTddKQpzKEgucWosSC5YQykKcihQLmNYLFtILmJRLEguVTUsUC5tVyxILnVuXSkKcihILmJRLFtILmFM
+LEguaTUsUC54dV0pCnIoSC5hTCxbSC5uSCxILkE4LFAuaThdKQpzKEguU08sUC5BbikKcyhQLlJVLFAu
+UG4pCnMoUC5HaixQLlJVKQpzKEguUEQsUC5HaikKcyhILkxQLEguV1UpCnIoSC5UcCxbSC5DaixILkFt
+LEgubGMsSC5kQyxILndOLEguVlgsUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuZGEsUC5vUSxQLnBW
+LFAuVTcsUC52cixQLnJILFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUsUC5QSSxQLnBL
+LFAuaGosUC5WcCxQLk9SLFAuR0EsUC5XRixQLm4xLFAuY1MsUC5WQyxQLnRwLFAuZTEsUC5OWSxQLlJa
+LFAuTUUsUC55NSxQLnEzLFAueUksUC5jNixQLnFkLFcuQ3YsVy5iVSxXLmhILFcuS1MsVy5BMyxXLnZO
+LFcuVXYsVy5FZyxXLkVvLFcuV2ssVy5JQSxXLmZtLFAubFIsUC5qZyxQLkdFLFAuTjcsUC51USxQLlBD
+LFAuWW0sUC5OeixQLlFTLFAubnAsTC5lLEwuVlcsTC5vWixMLmpyLEwucWwsTC5MLEwuV3gsTC5BTyxM
+LmROLEwuSG8sTC54eixMLklDLEwuTDEsTC5uVCxMLkJaLEwuRlEsTC5HSCxMLkRULEwuZUgsTC56RCxM
+Lk9FLEwuVFcsTC54cixMLkVFLEwuUUwsTC5WUyxNLk1pLE0ucTcsTS5ObyxYLnFSXSkKcihQLlhTLFtI
+LlcwLEguYXosSC52VixILkVxLFAuQzYsSC51OSxQLm4sUC51LFAubXAsUC51YixQLmRzLFAubGosUC5V
+VixQLmNdKQpyKEgubGMsW0guengsSC5yVF0pCnMoSC5rWSxQLkM2KQpzKFAuaWwsUC5ZaykKcihQLmls
+LFtILk41LFAudXcsVy5EOSxXLlN5XSkKcyhILktXLFAubVcpCnMoSC5iMCxILkVUKQpyKEguYjAsW0gu
+UkcsSC5XQl0pCnMoSC5WUCxILlJHKQpzKEguRGcsSC5WUCkKcyhILlpHLEguV0IpCnMoSC5QZyxILlpH
+KQpyKEguUGcsW0gueGosSC5kRSxILlpBLEgud2YsSC5QcSxILmVFLEguVjZdKQpyKEgudTksW0guaHos
+SC5pTV0pCnMoUC5aZixQLlBmKQpzKFAuSmksUC5tMCkKcyhQLmI2LFAuWHYpCnMoUC5WaixQLldZKQpy
+KFAuVWssW1AuQ1YsUC5aaSxQLmJ5XSkKcyhQLndJLFAua1QpCnIoUC53SSxbUC5VOCxQLk14LFAuRTMs
+UC5HWV0pCnMoUC51NSxQLlppKQpyKFAuRkssW1AuQ1AsUC5LTl0pCnIoUC51LFtQLmJKLFAuZVldKQpz
+KFAucWUsUC5EbikKcihXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkKcihXLnVILFtXLmN2LFcubngs
+Vy5RRixXLkNRXSkKcihXLmN2LFtXLnFFLFAuZDVdKQpyKFcucUUsW1cuR2gsVy5mWSxXLm5CLFcuUVAs
+Vy5oNCxXLlNOLFcubHAsVy5UYixXLkl2LFcuQlQsVy55WV0pCnMoVy5vSixXLkxlKQpzKFcuVDUsVy5B
+eikKcyhXLlZiLFcuUUYpCnMoVy5PNyxXLndhKQpyKFcuZWEsW1cudzYsVy5ld10pCnMoVy5BaixXLnc2
+KQpzKFcuckIsVy5LNykKcyhXLkJILFcuckIpCnMoVy53NCxXLklCKQpzKFcub2EsVy5YVykKcyhXLnJo
+LFcub2EpCnMoVy5pNyxXLkQ5KQpzKFAuQXMsUC5WaikKcihQLkFzLFtXLkk0LFAuS2VdKQpzKFcuUk8s
+UC5xaCkKcyhXLkNxLFcuUk8pCnMoVy54QyxQLk1PKQpzKFcuY3QsVy5tNikKcyhQLkJmLFAuaUopCnIo
+UC5FNCxbUC5yNyxQLmNvXSkKcyhQLlR6LFAuY28pCnMoUC5uZCxQLmQ1KQpzKEIuTHUsTy56TCkKcihC
+Lkx1LFtFLk9GLEYucnUsTC5JVl0pCnQoSC5YQyxILlJlKQp0KEguUkcsUC5sRCkKdChILlZQLEguU1Up
+CnQoSC5XQixQLmxEKQp0KEguWkcsSC5TVSkKdChQLm5ZLFAubEQpCnQoUC5XWSxQLmxmKQp0KFAuUlUs
+UC5LUCkKdChXLkxlLFcuaWQpCnQoVy5LNyxQLmxEKQp0KFcuckIsVy5HbSkKdChXLlhXLFAubEQpCnQo
+Vy5vYSxXLkdtKQp0KFAuY28sUC5sRCl9KSgpCnZhciB2PXt0eXBlVW5pdmVyc2U6e2VDOm5ldyBNYXAo
+KSx0Ujp7fSxlVDp7fSx0UFY6e30sc0VBOltdfSxtYW5nbGVkR2xvYmFsTmFtZXM6e0tOOiJpbnQiLENQ
+OiJkb3VibGUiLEZLOiJudW0iLHFVOiJTdHJpbmciLGEyOiJib29sIixjODoiTnVsbCIsek06Ikxpc3Qi
+fSxtYW5nbGVkTmFtZXM6e30sZ2V0VHlwZUZyb21OYW1lOmdldEdsb2JhbEZyb21OYW1lLG1ldGFkYXRh
+OltdLHR5cGVzOlsiYzgoKSIsImM4KEAsQCkiLCJ+KCkiLCJjOChjdikiLCJAKEApIiwiYzgoQWopIiwi
+cVUocVUpIiwiYzgoTzcpIiwiYTIocVUpIiwifih+KCkpIiwiYzgocVUscVUpIiwiYTIoY3YscVUscVUs
+SlEpIiwiYzgoQCkiLCJjOChlYSkiLCJ+KHh1PHFVPikiLCJhMihrRikiLCJjOChxVSxAKSIsImM4KHFV
+KSIsIktOKEtOLEtOKSIsIn4ocVUscVUpIiwibjYoS04pIiwibjYoQCxAKSIsIn4ocVVbQF0pIiwifihx
+VSxLTikiLCJjOChldykiLCJAKGVhKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwiYzgoR0QsQCki
+LCJ+KHVILHVIKSIsIn4oQWopIiwiQChxVSkiLCJyNyhAKSIsIlR6PEA+KEApIiwiRTQoQCkiLCJ2czxA
+PihAKSIsImM4KEBbR3pdKSIsIn4oa1tHel0pIiwiYTIoeHU8cVU+KSIsIk83KE83KSIsInFVKEtOKSIs
+IkAoQCxxVSkiLCJjOCh+KCkpIiwiayhAKSIsIn4oQWp7cmVsYXRpdmVUbzpxVX0pIiwiYTIodUgpIl0s
+aW50ZXJjZXB0b3JzQnlUYWc6bnVsbCxsZWFmVGFnczpudWxsfQpILnhiKHYudHlwZVVuaXZlcnNlLEpT
+T04ucGFyc2UoJ3sicngiOiJlYSIsImU1IjoiZWEiLCJZMCI6ImQ1IiwiV3QiOiJkNSIsInYwIjoiZXci
+LCJNciI6InFFIiwiZUwiOiJxRSIsIkkwIjoidUgiLCJocyI6InVIIiwiWGciOiJRRiIsInljIjoiQWoi
+LCJ5NCI6Inc2IiwiYVAiOiJDbSIsInhjIjoibngiLCJrSiI6Im54IiwielUiOiJEZyIsImRmIjoiRVQi
+LCJ5RSI6eyJhMiI6W119LCJZRSI6eyJjOCI6W119LCJNRiI6eyJ2bSI6W119LCJpQyI6eyJ2bSI6W119
+LCJrZCI6eyJ2bSI6W119LCJjNSI6eyJFSCI6W10sInZtIjpbXX0sImpkIjp7InpNIjpbIjEiXSwiY1gi
+OlsiMSJdfSwiUG8iOnsiamQiOlsiMSJdLCJ6TSI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpb
+IjEiXX0sInFJIjp7IkNQIjpbXSwiRksiOltdfSwidXIiOnsiS04iOltdLCJDUCI6W10sIkZLIjpbXX0s
+IlZBIjp7IkNQIjpbXSwiRksiOltdfSwiRHIiOnsicVUiOltdLCJ2WCI6W119LCJxaiI6eyJSZSI6WyJL
+TiJdLCJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04iLCJSZS5FIjoi
+S04ifSwiYlEiOnsiY1giOlsiMSJdfSwiYUwiOnsiY1giOlsiMSJdfSwibkgiOnsiYUwiOlsiMSJdLCJj
+WCI6WyIxIl0sImFMLkUiOiIxIiwiY1guRSI6IjEifSwiYTciOnsiQW4iOlsiMSJdfSwiQTgiOnsiYUwi
+OlsiMiJdLCJjWCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJj
+WC5FIjoiMSJ9LCJTTyI6eyJBbiI6WyIxIl19LCJYQyI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0i
+OlsiMSJdLCJjWCI6WyIxIl19LCJ3diI6eyJHRCI6W119LCJQRCI6eyJHaiI6WyIxIiwiMiJdLCJSVSI6
+WyIxIiwiMiJdLCJQbiI6WyIxIiwiMiJdLCJLUCI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiV1Ui
+OnsiWjAiOlsiMSIsIjIiXX0sIkxQIjp7IldVIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJMSSI6
+eyJ2USI6W119LCJXMCI6eyJYUyI6W119LCJheiI6eyJYUyI6W119LCJ2ViI6eyJYUyI6W119LCJYTyI6
+eyJHeiI6W119LCJUcCI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119LCJ6eCI6eyJFSCI6W119LCJyVCI6
+eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119LCJONSI6eyJGbyI6WyIxIiwiMiJd
+LCJZayI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoiMSIsIllrLlYiOiIyIn0sImk1Ijp7
+ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiTjYiOnsiQW4iOlsiMSJdfSwiVlIiOnsid0wiOltdLCJ2WCI6
+W119LCJFSyI6eyJpYiI6W10sIk9kIjpbXX0sIktXIjp7ImNYIjpbImliIl0sImNYLkUiOiJpYiJ9LCJQ
+YiI6eyJBbiI6WyJpYiJdfSwidFEiOnsiT2QiOltdfSwidW4iOnsiY1giOlsiT2QiXSwiY1guRSI6Ik9k
+In0sIlNkIjp7IkFuIjpbIk9kIl19LCJFVCI6eyJBUyI6W119LCJiMCI6eyJYaiI6WyJAIl0sIkVUIjpb
+XSwiQVMiOltdfSwiRGciOnsibEQiOlsiQ1AiXSwiWGoiOlsiQCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10s
+IlNVIjpbIkNQIl0sIkFTIjpbXSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIktO
+Il0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpb
+IktOIl19LCJ4aiI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiU1Ui
+OlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04ifSwiZEUiOnsibEQiOlsiS04iXSwi
+ek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04i
+XSwibEQuRSI6IktOIn0sIlpBIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQi
+OltdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJ3ZiI6eyJsRCI6
+WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiU1UiOlsiS04iXSwiQVMiOltdLCJj
+WCI6WyJLTiJdLCJsRC5FIjoiS04ifSwiUHEiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsi
+QCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sImVF
+Ijp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJTVSI6WyJLTiJdLCJB
+UyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJWNiI6eyJuNiI6W10sImxEIjpbIktOIl0sInpN
+IjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0s
+ImxELkUiOiJLTiJ9LCJ1OSI6eyJYUyI6W119LCJoeiI6eyJYUyI6W119LCJpTSI6eyJYUyI6W119LCJa
+ZiI6eyJQZiI6WyIxIl19LCJ2cyI6eyJiOCI6WyIxIl19LCJDdyI6eyJYUyI6W119LCJtMCI6eyJKQiI6
+W119LCJKaSI6eyJKQiI6W119LCJiNiI6eyJYdiI6WyIxIl0sInh1IjpbIjEiXSwiY1giOlsiMSJdfSwi
+bG0iOnsiQW4iOlsiMSJdfSwibVciOnsiY1giOlsiMSJdfSwiTFUiOnsibEQiOlsiMSJdLCJ6TSI6WyIx
+Il0sImNYIjpbIjEiXX0sImlsIjp7IllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJa
+MCI6WyIxIiwiMiJdfSwiUG4iOnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBu
+IjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0s
+Inh1IjpbIjEiXSwiY1giOlsiMSJdfSwiWHYiOnsieHUiOlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZ
+ayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7
+ImFMIjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6
+WyJ6TTxLTj4iLCJxVSJdLCJVay5TIjoiek08S04+In0sIlU4Ijp7IndJIjpbInpNPEtOPiIsInFVIl19
+LCJaaSI6eyJVayI6WyJxVSIsInpNPEtOPiJdfSwiYnkiOnsiVWsiOlsiayIsInFVIl0sIlVrLlMiOiJr
+In0sIk14Ijp7IndJIjpbInFVIiwiayJdfSwidTUiOnsiVWsiOlsicVUiLCJ6TTxLTj4iXSwiVWsuUyI6
+InFVIn0sIkUzIjp7IndJIjpbInFVIiwiek08S04+Il19LCJHWSI6eyJ3SSI6WyJ6TTxLTj4iLCJxVSJd
+fSwiQ1AiOnsiRksiOltdfSwiQzYiOnsiWFMiOltdfSwibiI6eyJYUyI6W119LCJ1Ijp7IlhTIjpbXX0s
+ImJKIjp7IlhTIjpbXX0sImVZIjp7IlhTIjpbXX0sIm1wIjp7IlhTIjpbXX0sInViIjp7IlhTIjpbXX0s
+ImRzIjp7IlhTIjpbXX0sImxqIjp7IlhTIjpbXX0sIlVWIjp7IlhTIjpbXX0sIms1Ijp7IlhTIjpbXX0s
+IktZIjp7IlhTIjpbXX0sImMiOnsiWFMiOltdfSwiS04iOnsiRksiOltdfSwiek0iOnsiY1giOlsiMSJd
+fSwiaWIiOnsiT2QiOltdfSwieHUiOnsiY1giOlsiMSJdfSwicVUiOnsidlgiOltdfSwiUm4iOnsiQkwi
+OltdfSwiRG4iOnsiaUQiOltdfSwiVWYiOnsiaUQiOltdfSwicWUiOnsiaUQiOltdfSwicUUiOnsiY3Yi
+OltdLCJ1SCI6W10sIkQwIjpbXX0sIkdoIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJmWSI6eyJj
+diI6W10sInVIIjpbXSwiRDAiOltdfSwibkIiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlFQIjp7
+ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJueCI6eyJ1SCI6W10sIkQwIjpbXX0sIlFGIjp7InVIIjpb
+XSwiRDAiOltdfSwiSUIiOnsidG4iOlsiRksiXX0sInd6Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJj
+WCI6WyIxIl0sImxELkUiOiIxIn0sImN2Ijp7InVIIjpbXSwiRDAiOltdfSwiVDUiOnsiQXoiOltdfSwi
+aDQiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlZiIjp7InVIIjpbXSwiRDAiOltdfSwiTzciOnsi
+RDAiOltdfSwid2EiOnsiRDAiOltdfSwiQWoiOnsiZWEiOltdfSwiZTciOnsibEQiOlsidUgiXSwiek0i
+OlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIn0sInVIIjp7IkQwIjpbXX0sIkJIIjp7IkdtIjpb
+InVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUi
+OiJ1SCIsIkdtLkUiOiJ1SCJ9LCJTTiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZXciOnsiZWEi
+OltdfSwibHAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlRiIjp7ImN2IjpbXSwidUgiOltdLCJE
+MCI6W119LCJJdiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiQlQiOnsiY3YiOltdLCJ1SCI6W10s
+IkQwIjpbXX0sInlZIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ3NiI6eyJlYSI6W119LCJLNSI6
+eyJ2NiI6W10sIkQwIjpbXX0sIkNtIjp7IkQwIjpbXX0sIkNRIjp7InVIIjpbXSwiRDAiOltdfSwidzQi
+OnsidG4iOlsiRksiXX0sInJoIjp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhq
+IjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCIsIkdtLkUiOiJ1SCJ9LCJEOSI6eyJZayI6WyJx
+VSIsInFVIl0sIlowIjpbInFVIiwicVUiXX0sImk3Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUi
+LCJxVSJdLCJZay5LIjoicVUiLCJZay5WIjoicVUifSwiU3kiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6
+WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJJNCI6eyJsZiI6WyJxVSJdLCJ4dSI6
+WyJxVSJdLCJjWCI6WyJxVSJdfSwiUk8iOnsicWgiOlsiMSJdfSwiQ3EiOnsiUk8iOlsiMSJdLCJxaCI6
+WyIxIl19LCJKUSI6eyJrRiI6W119LCJ2RCI6eyJrRiI6W119LCJtNiI6eyJrRiI6W119LCJjdCI6eyJr
+RiI6W119LCJPdyI6eyJrRiI6W119LCJXOSI6eyJBbiI6WyIxIl19LCJkVyI6eyJ2NiI6W10sIkQwIjpb
+XX0sIm1rIjp7InkwIjpbXX0sIktvIjp7Im9uIjpbXX0sIkFzIjp7ImxmIjpbInFVIl0sInh1IjpbInFV
+Il0sImNYIjpbInFVIl19LCJyNyI6eyJFNCI6W119LCJUeiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwi
+RTQiOltdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sIm5kIjp7ImQ1IjpbXSwiY3YiOltdLCJ1SCI6W10s
+IkQwIjpbXX0sIktlIjp7ImxmIjpbInFVIl0sInh1IjpbInFVIl0sImNYIjpbInFVIl19LCJkNSI6eyJj
+diI6W10sInVIIjpbXSwiRDAiOltdfSwibjYiOnsiek0iOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJd
+fSwiWEEiOnsia0YiOltdfSwiT0YiOnsiTHUiOltdfSwicnUiOnsiTHUiOltdfSwiSVYiOnsiTHUiOltd
+fX0nKSkKSC5GRih2LnR5cGVVbml2ZXJzZSxKU09OLnBhcnNlKCd7ImJRIjoxLCJYQyI6MSwiTU8iOjEs
+ImtUIjoyLCJtVyI6MSwiTFUiOjEsImlsIjoyLCJWaiI6MSwiblkiOjEsIldZIjoxLCJjbyI6MX0nKSkK
+dmFyIHU9KGZ1bmN0aW9uIHJ0aWkoKXt2YXIgdD1ILk4wCnJldHVybntrOnQoIkdoIiksbjp0KCJDdyIp
+LEY6dCgibkIiKSxkOnQoIkF6IiksWTp0KCJRUCIpLGdGOnQoIlBEPEdELEA+IiksaDp0KCJjdiIpLGJV
+OnQoIlhTIiksQjp0KCJlYSIpLGFTOnQoIkQwIiksYzg6dCgiVDUiKSxaOnQoIkVIIiksYzp0KCJiODxA
+PiIpLHI6dCgiTzciKSxJOnQoIlNnIiksbzp0KCJ2USIpLGVoOnQoImNYPHVIPiIpLFg6dCgiY1g8cVU+
+IiksUjp0KCJjWDxAPiIpLGZBOnQoImpkPFNlPiIpLGJQOnQoImpkPHVGPiIpLG06dCgiamQ8a0Y+Iiks
+czp0KCJqZDxxVT4iKSxoaDp0KCJqZDx5RD4iKSxhSjp0KCJqZDx3Yj4iKSxiOnQoImpkPEA+IiksdDp0
+KCJqZDxLTj4iKSxlSDp0KCJ2bSIpLGc6dCgiYzUiKSxhVTp0KCJYajxAPiIpLGFtOnQoIlR6PEA+Iiks
+ZW86dCgiTjU8R0QsQD4iKSx1OnQoIkU0IiksZHo6dCgiaEYiKSxpOnQoInpNPHFVPiIpLGo6dCgiek08
+QD4iKSxMOnQoInpNPEtOPiIpLGY6dCgiWjA8cVUscVU+IiksYTp0KCJaMDxxVSxAPiIpLEc6dCgiWjA8
+QCxAPiIpLGR2OnQoIkE4PHFVLHFVPiIpLGRvOnQoIkE4PHFVLEA+IiksVjp0KCJBaiIpLGREOnQoIkVU
+IiksYm06dCgiVjYiKSxBOnQoInVIIiksZTp0KCJrRiIpLFA6dCgiYzgiKSxLOnQoImsiKSxwOnQoImV3
+IikscTp0KCJ0bjxGSz4iKSxmdjp0KCJ3TCIpLGV3OnQoIm5kIiksQzp0KCJ4dTxxVT4iKSxsOnQoIkd6
+IiksTjp0KCJxVSIpLGRHOnQoInFVKHFVKSIpLGc3OnQoImQ1IiksZm86dCgiR0QiKSxhVzp0KCJ5WSIp
+LHY6dCgiQVMiKSxnYzp0KCJuNiIpLGFrOnQoImtkIiksVDp0KCJHajxxVSxxVT4iKSx3OnQoImlEIiks
+Y2M6dCgiVTU8cVU+IiksZzQ6dCgiSzUiKSxjaTp0KCJ2NiIpLGcyOnQoIkNtIiksRTp0KCJaZjxPNz4i
+KSxoOTp0KCJDUSIpLGFjOnQoImU3IiksUTp0KCJDcTxBaj4iKSxTOnQoInd6PGN2PiIpLHg6dCgiRmU8
+QCxAPiIpLGFvOnQoInZzPE83PiIpLF86dCgidnM8QD4iKSxmSjp0KCJ2czxLTj4iKSxPOnQoIkpRIiks
+Sjp0KCJibiIpLGNKOnQoImEyIiksYWw6dCgiYTIoaykiKSxiQjp0KCJhMihxVSkiKSxiZjp0KCJhMihA
+KSIpLHo6dCgiQCIpLGZPOnQoIkAoKSIpLFU6dCgiQChlYSkiKSx5OnQoIkAoaykiKSxlcDp0KCJAKGss
+aykiKSxXOnQoIkAoayxHeikiKSxjaDp0KCJAKHh1PHFVPikiKSxkTzp0KCJAKHFVKSIpLGI4OnQoIkAo
+QCxAKSIpLEg6dCgifiIpLE06dCgifigpIiksYW46dCgifihldykiKSxEOnQoIn4ocVUscVUpIiksY0E6
+dCgifihxVSxAKSIpfX0pKCk7KGZ1bmN0aW9uIGNvbnN0YW50cygpe3ZhciB0PWh1bmtIZWxwZXJzLm1h
+a2VDb25zdExpc3QKQy5SWT1XLlFQLnByb3RvdHlwZQpDLkJaPVcuVmIucHJvdG90eXBlCkMuRHQ9Vy5P
+Ny5wcm90b3R5cGUKQy5Paz1KLnZCLnByb3RvdHlwZQpDLk5tPUouamQucHJvdG90eXBlCkMuam49Si51
+ci5wcm90b3R5cGUKQy5qTj1KLllFLnByb3RvdHlwZQpDLkNEPUoucUkucHJvdG90eXBlCkMueEI9Si5E
+ci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcudTgucHJvdG90eXBlCkMuTHQ9Vy5T
+Ti5wcm90b3R5cGUKQy5aUT1KLmlDLnByb3RvdHlwZQpDLkllPVcuVGIucHJvdG90eXBlCkMudkI9Si5r
+ZC5wcm90b3R5cGUKQy5vbD1XLks1LnByb3RvdHlwZQpDLnk4PW5ldyBQLlU4KCkKQy5oOT1uZXcgUC5D
+VigpCkMuTzQ9ZnVuY3Rpb24gZ2V0VGFnRmFsbGJhY2sobykgewogIHZhciBzID0gT2JqZWN0LnByb3Rv
+dHlwZS50b1N0cmluZy5jYWxsKG8pOwogIHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAtIDEp
+Owp9CkMuWXE9ZnVuY3Rpb24oKSB7CiAgdmFyIHRvU3RyaW5nRnVuY3Rpb24gPSBPYmplY3QucHJvdG90
+eXBlLnRvU3RyaW5nOwogIGZ1bmN0aW9uIGdldFRhZyhvKSB7CiAgICB2YXIgcyA9IHRvU3RyaW5nRnVu
+Y3Rpb24uY2FsbChvKTsKICAgIHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAtIDEpOwogIH0K
+ICBmdW5jdGlvbiBnZXRVbmtub3duVGFnKG9iamVjdCwgdGFnKSB7CiAgICBpZiAoL15IVE1MW0EtWl0u
+KkVsZW1lbnQkLy50ZXN0KHRhZykpIHsKICAgICAgdmFyIG5hbWUgPSB0b1N0cmluZ0Z1bmN0aW9uLmNh
+bGwob2JqZWN0KTsKICAgICAgaWYgKG5hbWUgPT0gIltvYmplY3QgT2JqZWN0XSIpIHJldHVybiBudWxs
+OwogICAgICByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIH0KICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93
+blRhZ0dlbmVyaWNCcm93c2VyKG9iamVjdCwgdGFnKSB7CiAgICBpZiAoc2VsZi5IVE1MRWxlbWVudCAm
+JiBvYmplY3QgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICBy
+ZXR1cm4gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZyk7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZv
+clRhZyh0YWcpIHsKICAgIGlmICh0eXBlb2Ygd2luZG93ID09ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVs
+bDsKICAgIGlmICh0eXBlb2Ygd2luZG93W3RhZ10gPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwog
+ICAgdmFyIGNvbnN0cnVjdG9yID0gd2luZG93W3RhZ107CiAgICBpZiAodHlwZW9mIGNvbnN0cnVjdG9y
+ICE9ICJmdW5jdGlvbiIpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlw
+ZTsKICB9CiAgZnVuY3Rpb24gZGlzY3JpbWluYXRvcih0YWcpIHsgcmV0dXJuIG51bGw7IH0KICB2YXIg
+aXNCcm93c2VyID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IjsKICByZXR1cm4gewogICAgZ2V0
+VGFnOiBnZXRUYWcsCiAgICBnZXRVbmtub3duVGFnOiBpc0Jyb3dzZXIgPyBnZXRVbmtub3duVGFnR2Vu
+ZXJpY0Jyb3dzZXIgOiBnZXRVbmtub3duVGFnLAogICAgcHJvdG90eXBlRm9yVGFnOiBwcm90b3R5cGVG
+b3JUYWcsCiAgICBkaXNjcmltaW5hdG9yOiBkaXNjcmltaW5hdG9yIH07Cn0KQy53Yj1mdW5jdGlvbihn
+ZXRUYWdGYWxsYmFjaykgewogIHJldHVybiBmdW5jdGlvbihob29rcykgewogICAgaWYgKHR5cGVvZiBu
+YXZpZ2F0b3IgIT0gIm9iamVjdCIpIHJldHVybiBob29rczsKICAgIHZhciB1YSA9IG5hdmlnYXRvci51
+c2VyQWdlbnQ7CiAgICBpZiAodWEuaW5kZXhPZigiRHVtcFJlbmRlclRyZWUiKSA+PSAwKSByZXR1cm4g
+aG9va3M7CiAgICBpZiAodWEuaW5kZXhPZigiQ2hyb21lIikgPj0gMCkgewogICAgICBmdW5jdGlvbiBj
+b25maXJtKHApIHsKICAgICAgICByZXR1cm4gdHlwZW9mIHdpbmRvdyA9PSAib2JqZWN0IiAmJiB3aW5k
+b3dbcF0gJiYgd2luZG93W3BdLm5hbWUgPT0gcDsKICAgICAgfQogICAgICBpZiAoY29uZmlybSgiV2lu
+ZG93IikgJiYgY29uZmlybSgiSFRNTEVsZW1lbnQiKSkgcmV0dXJuIGhvb2tzOwogICAgfQogICAgaG9v
+a3MuZ2V0VGFnID0gZ2V0VGFnRmFsbGJhY2s7CiAgfTsKfQpDLktVPWZ1bmN0aW9uKGhvb2tzKSB7CiAg
+aWYgKHR5cGVvZiBkYXJ0RXhwZXJpbWVudGFsRml4dXBHZXRUYWcgIT0gImZ1bmN0aW9uIikgcmV0dXJu
+IGhvb2tzOwogIGhvb2tzLmdldFRhZyA9IGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyhob29rcy5n
+ZXRUYWcpOwp9CkMuZlE9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFn
+OwogIHZhciBwcm90b3R5cGVGb3JUYWcgPSBob29rcy5wcm90b3R5cGVGb3JUYWc7CiAgZnVuY3Rpb24g
+Z2V0VGFnRml4ZWQobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIGlmICh0YWcgPT0gIkRv
+Y3VtZW50IikgewogICAgICBpZiAoISFvLnhtbFZlcnNpb24pIHJldHVybiAiIURvY3VtZW50IjsKICAg
+ICAgcmV0dXJuICIhSFRNTERvY3VtZW50IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAgfQogIGZ1bmN0
+aW9uIHByb3RvdHlwZUZvclRhZ0ZpeGVkKHRhZykgewogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSBy
+ZXR1cm4gbnVsbDsKICAgIHJldHVybiBwcm90b3R5cGVGb3JUYWcodGFnKTsKICB9CiAgaG9va3MuZ2V0
+VGFnID0gZ2V0VGFnRml4ZWQ7CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBlRm9yVGFn
+Rml4ZWQ7Cn0KQy5kaz1mdW5jdGlvbihob29rcykgewogIHZhciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2
+aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIiOwogIGlmICh1c2VyQWdl
+bnQuaW5kZXhPZigiRmlyZWZveCIpID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRhZyA9IGhv
+b2tzLmdldFRhZzsKICB2YXIgcXVpY2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQiOiAiRXZl
+bnQiLAogICAgIkRhdGFUcmFuc2ZlciI6ICJDbGlwYm9hcmQiLAogICAgIkdlb0dlb2xvY2F0aW9uIjog
+Ikdlb2xvY2F0aW9uIiwKICAgICJMb2NhdGlvbiI6ICIhTG9jYXRpb24iLAogICAgIldvcmtlck1lc3Nh
+Z2VFdmVudCI6ICJNZXNzYWdlRXZlbnQiLAogICAgIlhNTERvY3VtZW50IjogIiFEb2N1bWVudCJ9Owog
+IGZ1bmN0aW9uIGdldFRhZ0ZpcmVmb3gobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHJl
+dHVybiBxdWlja01hcFt0YWddIHx8IHRhZzsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRmlyZWZv
+eDsKfQpDLnhpPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0
+b3IgPT0gIm9iamVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5p
+bmRleE9mKCJUcmlkZW50LyIpID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRhZyA9IGhvb2tz
+LmdldFRhZzsKICB2YXIgcXVpY2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQiOiAiRXZlbnQi
+LAogICAgIkRhdGFUcmFuc2ZlciI6ICJDbGlwYm9hcmQiLAogICAgIkhUTUxEREVsZW1lbnQiOiAiSFRN
+TEVsZW1lbnQiLAogICAgIkhUTUxEVEVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhUTUxQaHJh
+c2VFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJQb3NpdGlvbiI6ICJHZW9wb3NpdGlvbiIKICB9
+OwogIGZ1bmN0aW9uIGdldFRhZ0lFKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICB2YXIg
+bmV3VGFnID0gcXVpY2tNYXBbdGFnXTsKICAgIGlmIChuZXdUYWcpIHJldHVybiBuZXdUYWc7CiAgICBp
+ZiAodGFnID09ICJPYmplY3QiKSB7CiAgICAgIGlmICh3aW5kb3cuRGF0YVZpZXcgJiYgKG8gaW5zdGFu
+Y2VvZiB3aW5kb3cuRGF0YVZpZXcpKSByZXR1cm4gIkRhdGFWaWV3IjsKICAgIH0KICAgIHJldHVybiB0
+YWc7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZ0lFKHRhZykgewogICAgdmFyIGNvbnN0cnVj
+dG9yID0gd2luZG93W3RhZ107CiAgICBpZiAoY29uc3RydWN0b3IgPT0gbnVsbCkgcmV0dXJuIG51bGw7
+CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRU
+YWdJRTsKICBob29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdJRTsKfQpDLmk3PWZ1
+bmN0aW9uKGhvb2tzKSB7IHJldHVybiBob29rczsgfQoKQy5DdD1uZXcgUC5ieSgpCkMuRXE9bmV3IFAu
+azUoKQpDLnhNPW5ldyBQLnU1KCkKQy5Raz1uZXcgUC5FMygpCkMuTlU9bmV3IFAuSmkoKQpDLkEzPW5l
+dyBQLk14KG51bGwpCkMuR2I9SC5WTSh0KFsxMjcsMjA0Nyw2NTUzNSwxMTE0MTExXSksdS50KQpDLmFr
+PUguVk0odChbMCwwLDMyNzc2LDMzNzkyLDEsMTAyNDAsMCwwXSksdS50KQpDLmNtPUguVk0odChbIio6
+OmNsYXNzIiwiKjo6ZGlyIiwiKjo6ZHJhZ2dhYmxlIiwiKjo6aGlkZGVuIiwiKjo6aWQiLCIqOjppbmVy
+dCIsIio6Oml0ZW1wcm9wIiwiKjo6aXRlbXJlZiIsIio6Oml0ZW1zY29wZSIsIio6OmxhbmciLCIqOjpz
+cGVsbGNoZWNrIiwiKjo6dGl0bGUiLCIqOjp0cmFuc2xhdGUiLCJBOjphY2Nlc3NrZXkiLCJBOjpjb29y
+ZHMiLCJBOjpocmVmbGFuZyIsIkE6Om5hbWUiLCJBOjpzaGFwZSIsIkE6OnRhYmluZGV4IiwiQTo6dGFy
+Z2V0IiwiQTo6dHlwZSIsIkFSRUE6OmFjY2Vzc2tleSIsIkFSRUE6OmFsdCIsIkFSRUE6OmNvb3JkcyIs
+IkFSRUE6Om5vaHJlZiIsIkFSRUE6OnNoYXBlIiwiQVJFQTo6dGFiaW5kZXgiLCJBUkVBOjp0YXJnZXQi
+LCJBVURJTzo6Y29udHJvbHMiLCJBVURJTzo6bG9vcCIsIkFVRElPOjptZWRpYWdyb3VwIiwiQVVESU86
+Om11dGVkIiwiQVVESU86OnByZWxvYWQiLCJCRE86OmRpciIsIkJPRFk6OmFsaW5rIiwiQk9EWTo6Ymdj
+b2xvciIsIkJPRFk6OmxpbmsiLCJCT0RZOjp0ZXh0IiwiQk9EWTo6dmxpbmsiLCJCUjo6Y2xlYXIiLCJC
+VVRUT046OmFjY2Vzc2tleSIsIkJVVFRPTjo6ZGlzYWJsZWQiLCJCVVRUT046Om5hbWUiLCJCVVRUT046
+OnRhYmluZGV4IiwiQlVUVE9OOjp0eXBlIiwiQlVUVE9OOjp2YWx1ZSIsIkNBTlZBUzo6aGVpZ2h0Iiwi
+Q0FOVkFTOjp3aWR0aCIsIkNBUFRJT046OmFsaWduIiwiQ09MOjphbGlnbiIsIkNPTDo6Y2hhciIsIkNP
+TDo6Y2hhcm9mZiIsIkNPTDo6c3BhbiIsIkNPTDo6dmFsaWduIiwiQ09MOjp3aWR0aCIsIkNPTEdST1VQ
+OjphbGlnbiIsIkNPTEdST1VQOjpjaGFyIiwiQ09MR1JPVVA6OmNoYXJvZmYiLCJDT0xHUk9VUDo6c3Bh
+biIsIkNPTEdST1VQOjp2YWxpZ24iLCJDT0xHUk9VUDo6d2lkdGgiLCJDT01NQU5EOjpjaGVja2VkIiwi
+Q09NTUFORDo6Y29tbWFuZCIsIkNPTU1BTkQ6OmRpc2FibGVkIiwiQ09NTUFORDo6bGFiZWwiLCJDT01N
+QU5EOjpyYWRpb2dyb3VwIiwiQ09NTUFORDo6dHlwZSIsIkRBVEE6OnZhbHVlIiwiREVMOjpkYXRldGlt
+ZSIsIkRFVEFJTFM6Om9wZW4iLCJESVI6OmNvbXBhY3QiLCJESVY6OmFsaWduIiwiREw6OmNvbXBhY3Qi
+LCJGSUVMRFNFVDo6ZGlzYWJsZWQiLCJGT05UOjpjb2xvciIsIkZPTlQ6OmZhY2UiLCJGT05UOjpzaXpl
+IiwiRk9STTo6YWNjZXB0IiwiRk9STTo6YXV0b2NvbXBsZXRlIiwiRk9STTo6ZW5jdHlwZSIsIkZPUk06
+Om1ldGhvZCIsIkZPUk06Om5hbWUiLCJGT1JNOjpub3ZhbGlkYXRlIiwiRk9STTo6dGFyZ2V0IiwiRlJB
+TUU6Om5hbWUiLCJIMTo6YWxpZ24iLCJIMjo6YWxpZ24iLCJIMzo6YWxpZ24iLCJINDo6YWxpZ24iLCJI
+NTo6YWxpZ24iLCJINjo6YWxpZ24iLCJIUjo6YWxpZ24iLCJIUjo6bm9zaGFkZSIsIkhSOjpzaXplIiwi
+SFI6OndpZHRoIiwiSFRNTDo6dmVyc2lvbiIsIklGUkFNRTo6YWxpZ24iLCJJRlJBTUU6OmZyYW1lYm9y
+ZGVyIiwiSUZSQU1FOjpoZWlnaHQiLCJJRlJBTUU6Om1hcmdpbmhlaWdodCIsIklGUkFNRTo6bWFyZ2lu
+d2lkdGgiLCJJRlJBTUU6OndpZHRoIiwiSU1HOjphbGlnbiIsIklNRzo6YWx0IiwiSU1HOjpib3JkZXIi
+LCJJTUc6OmhlaWdodCIsIklNRzo6aHNwYWNlIiwiSU1HOjppc21hcCIsIklNRzo6bmFtZSIsIklNRzo6
+dXNlbWFwIiwiSU1HOjp2c3BhY2UiLCJJTUc6OndpZHRoIiwiSU5QVVQ6OmFjY2VwdCIsIklOUFVUOjph
+Y2Nlc3NrZXkiLCJJTlBVVDo6YWxpZ24iLCJJTlBVVDo6YWx0IiwiSU5QVVQ6OmF1dG9jb21wbGV0ZSIs
+IklOUFVUOjphdXRvZm9jdXMiLCJJTlBVVDo6Y2hlY2tlZCIsIklOUFVUOjpkaXNhYmxlZCIsIklOUFVU
+OjppbnB1dG1vZGUiLCJJTlBVVDo6aXNtYXAiLCJJTlBVVDo6bGlzdCIsIklOUFVUOjptYXgiLCJJTlBV
+VDo6bWF4bGVuZ3RoIiwiSU5QVVQ6Om1pbiIsIklOUFVUOjptdWx0aXBsZSIsIklOUFVUOjpuYW1lIiwi
+SU5QVVQ6OnBsYWNlaG9sZGVyIiwiSU5QVVQ6OnJlYWRvbmx5IiwiSU5QVVQ6OnJlcXVpcmVkIiwiSU5Q
+VVQ6OnNpemUiLCJJTlBVVDo6c3RlcCIsIklOUFVUOjp0YWJpbmRleCIsIklOUFVUOjp0eXBlIiwiSU5Q
+VVQ6OnVzZW1hcCIsIklOUFVUOjp2YWx1ZSIsIklOUzo6ZGF0ZXRpbWUiLCJLRVlHRU46OmRpc2FibGVk
+IiwiS0VZR0VOOjprZXl0eXBlIiwiS0VZR0VOOjpuYW1lIiwiTEFCRUw6OmFjY2Vzc2tleSIsIkxBQkVM
+Ojpmb3IiLCJMRUdFTkQ6OmFjY2Vzc2tleSIsIkxFR0VORDo6YWxpZ24iLCJMSTo6dHlwZSIsIkxJOjp2
+YWx1ZSIsIkxJTks6OnNpemVzIiwiTUFQOjpuYW1lIiwiTUVOVTo6Y29tcGFjdCIsIk1FTlU6OmxhYmVs
+IiwiTUVOVTo6dHlwZSIsIk1FVEVSOjpoaWdoIiwiTUVURVI6OmxvdyIsIk1FVEVSOjptYXgiLCJNRVRF
+Ujo6bWluIiwiTUVURVI6OnZhbHVlIiwiT0JKRUNUOjp0eXBlbXVzdG1hdGNoIiwiT0w6OmNvbXBhY3Qi
+LCJPTDo6cmV2ZXJzZWQiLCJPTDo6c3RhcnQiLCJPTDo6dHlwZSIsIk9QVEdST1VQOjpkaXNhYmxlZCIs
+Ik9QVEdST1VQOjpsYWJlbCIsIk9QVElPTjo6ZGlzYWJsZWQiLCJPUFRJT046OmxhYmVsIiwiT1BUSU9O
+OjpzZWxlY3RlZCIsIk9QVElPTjo6dmFsdWUiLCJPVVRQVVQ6OmZvciIsIk9VVFBVVDo6bmFtZSIsIlA6
+OmFsaWduIiwiUFJFOjp3aWR0aCIsIlBST0dSRVNTOjptYXgiLCJQUk9HUkVTUzo6bWluIiwiUFJPR1JF
+U1M6OnZhbHVlIiwiU0VMRUNUOjphdXRvY29tcGxldGUiLCJTRUxFQ1Q6OmRpc2FibGVkIiwiU0VMRUNU
+OjptdWx0aXBsZSIsIlNFTEVDVDo6bmFtZSIsIlNFTEVDVDo6cmVxdWlyZWQiLCJTRUxFQ1Q6OnNpemUi
+LCJTRUxFQ1Q6OnRhYmluZGV4IiwiU09VUkNFOjp0eXBlIiwiVEFCTEU6OmFsaWduIiwiVEFCTEU6OmJn
+Y29sb3IiLCJUQUJMRTo6Ym9yZGVyIiwiVEFCTEU6OmNlbGxwYWRkaW5nIiwiVEFCTEU6OmNlbGxzcGFj
+aW5nIiwiVEFCTEU6OmZyYW1lIiwiVEFCTEU6OnJ1bGVzIiwiVEFCTEU6OnN1bW1hcnkiLCJUQUJMRTo6
+d2lkdGgiLCJUQk9EWTo6YWxpZ24iLCJUQk9EWTo6Y2hhciIsIlRCT0RZOjpjaGFyb2ZmIiwiVEJPRFk6
+OnZhbGlnbiIsIlREOjphYmJyIiwiVEQ6OmFsaWduIiwiVEQ6OmF4aXMiLCJURDo6Ymdjb2xvciIsIlRE
+OjpjaGFyIiwiVEQ6OmNoYXJvZmYiLCJURDo6Y29sc3BhbiIsIlREOjpoZWFkZXJzIiwiVEQ6OmhlaWdo
+dCIsIlREOjpub3dyYXAiLCJURDo6cm93c3BhbiIsIlREOjpzY29wZSIsIlREOjp2YWxpZ24iLCJURDo6
+d2lkdGgiLCJURVhUQVJFQTo6YWNjZXNza2V5IiwiVEVYVEFSRUE6OmF1dG9jb21wbGV0ZSIsIlRFWFRB
+UkVBOjpjb2xzIiwiVEVYVEFSRUE6OmRpc2FibGVkIiwiVEVYVEFSRUE6OmlucHV0bW9kZSIsIlRFWFRB
+UkVBOjpuYW1lIiwiVEVYVEFSRUE6OnBsYWNlaG9sZGVyIiwiVEVYVEFSRUE6OnJlYWRvbmx5IiwiVEVY
+VEFSRUE6OnJlcXVpcmVkIiwiVEVYVEFSRUE6OnJvd3MiLCJURVhUQVJFQTo6dGFiaW5kZXgiLCJURVhU
+QVJFQTo6d3JhcCIsIlRGT09UOjphbGlnbiIsIlRGT09UOjpjaGFyIiwiVEZPT1Q6OmNoYXJvZmYiLCJU
+Rk9PVDo6dmFsaWduIiwiVEg6OmFiYnIiLCJUSDo6YWxpZ24iLCJUSDo6YXhpcyIsIlRIOjpiZ2NvbG9y
+IiwiVEg6OmNoYXIiLCJUSDo6Y2hhcm9mZiIsIlRIOjpjb2xzcGFuIiwiVEg6OmhlYWRlcnMiLCJUSDo6
+aGVpZ2h0IiwiVEg6Om5vd3JhcCIsIlRIOjpyb3dzcGFuIiwiVEg6OnNjb3BlIiwiVEg6OnZhbGlnbiIs
+IlRIOjp3aWR0aCIsIlRIRUFEOjphbGlnbiIsIlRIRUFEOjpjaGFyIiwiVEhFQUQ6OmNoYXJvZmYiLCJU
+SEVBRDo6dmFsaWduIiwiVFI6OmFsaWduIiwiVFI6OmJnY29sb3IiLCJUUjo6Y2hhciIsIlRSOjpjaGFy
+b2ZmIiwiVFI6OnZhbGlnbiIsIlRSQUNLOjpkZWZhdWx0IiwiVFJBQ0s6OmtpbmQiLCJUUkFDSzo6bGFi
+ZWwiLCJUUkFDSzo6c3JjbGFuZyIsIlVMOjpjb21wYWN0IiwiVUw6OnR5cGUiLCJWSURFTzo6Y29udHJv
+bHMiLCJWSURFTzo6aGVpZ2h0IiwiVklERU86Omxvb3AiLCJWSURFTzo6bWVkaWFncm91cCIsIlZJREVP
+OjptdXRlZCIsIlZJREVPOjpwcmVsb2FkIiwiVklERU86OndpZHRoIl0pLHUucykKQy5WQz1ILlZNKHQo
+WzAsMCw2NTQ5MCw0NTA1NSw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5tSz1ILlZNKHQo
+WzAsMCwyNjYyNCwxMDIzLDY1NTM0LDIwNDcsNjU1MzQsMjA0N10pLHUudCkKQy5TcT1ILlZNKHQoWyJI
+RUFEIiwiQVJFQSIsIkJBU0UiLCJCQVNFRk9OVCIsIkJSIiwiQ09MIiwiQ09MR1JPVVAiLCJFTUJFRCIs
+IkZSQU1FIiwiRlJBTUVTRVQiLCJIUiIsIklNQUdFIiwiSU1HIiwiSU5QVVQiLCJJU0lOREVYIiwiTElO
+SyIsIk1FVEEiLCJQQVJBTSIsIlNPVVJDRSIsIlNUWUxFIiwiVElUTEUiLCJXQlIiXSksdS5zKQpDLnhE
+PUguVk0odChbXSksdS5zKQpDLmRuPUguVk0odChbXSksdS5iKQpDLnRvPUguVk0odChbMCwwLDMyNzIy
+LDEyMjg3LDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLkYzPUguVk0odChbMCwwLDI0NTc2
+LDEwMjMsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuZWE9SC5WTSh0KFswLDAsMzI3NTQs
+MTEyNjMsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuWko9SC5WTSh0KFswLDAsMzI3MjIs
+MTIyODcsNjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuV2Q9SC5WTSh0KFswLDAsNjU0OTAs
+MTIyODcsNjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuUXg9SC5WTSh0KFsiYmluZCIsImlm
+IiwicmVmIiwicmVwZWF0Iiwic3ludGF4Il0pLHUucykKQy5CST1ILlZNKHQoWyJBOjpocmVmIiwiQVJF
+QTo6aHJlZiIsIkJMT0NLUVVPVEU6OmNpdGUiLCJCT0RZOjpiYWNrZ3JvdW5kIiwiQ09NTUFORDo6aWNv
+biIsIkRFTDo6Y2l0ZSIsIkZPUk06OmFjdGlvbiIsIklNRzo6c3JjIiwiSU5QVVQ6OnNyYyIsIklOUzo6
+Y2l0ZSIsIlE6OmNpdGUiLCJWSURFTzo6cG9zdGVyIl0pLHUucykKQy5XTz1uZXcgSC5MUCgwLHt9LEMu
+eEQsSC5OMCgiTFA8cVUscVU+IikpCkMuaFU9SC5WTSh0KFtdKSxILk4wKCJqZDxHRD4iKSkKQy5DTT1u
+ZXcgSC5MUCgwLHt9LEMuaFUsSC5OMCgiTFA8R0QsQD4iKSkKQy5UZT1uZXcgSC53digiY2FsbCIpfSko
+KTsoZnVuY3Rpb24gc3RhdGljRmllbGRzKCl7JC55aj0wCiQubUo9bnVsbAokLlA0PW51bGwKJC5ORj1u
+dWxsCiQuVFg9bnVsbAokLng3PW51bGwKJC5udz1udWxsCiQudnY9bnVsbAokLkJ2PW51bGwKJC5TNj1u
+dWxsCiQuazg9bnVsbAokLm1nPW51bGwKJC5VRD0hMQokLlgzPUMuTlUKJC54Zz1bXQokLnhvPW51bGwK
+JC5CTz1udWxsCiQubHQ9bnVsbAokLkVVPW51bGwKJC5vcj1QLkZsKHUuTix1LlopCiQuSTY9bnVsbAok
+LkZmPW51bGx9KSgpOyhmdW5jdGlvbiBsYXp5SW5pdGlhbGl6ZXJzKCl7dmFyIHQ9aHVua0hlbHBlcnMu
+bGF6eQp0KCQsImZhIiwidyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRDbG9zdXJl
+Iil9KQp0KCQsIllmIiwiVU4iLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9qcyIpfSkKdCgk
+LCJVMiIsIlNuIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoewp0b1N0cmluZzpmdW5jdGlvbigp
+e3JldHVybiIkcmVjZWl2ZXIkIn19KSl9KQp0KCQsInhxIiwibHEiLGZ1bmN0aW9uKCl7cmV0dXJuIEgu
+Y00oSC5TNyh7JG1ldGhvZCQ6bnVsbCwKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVy
+JCJ9fSkpfSkKdCgkLCJSMSIsIk45IixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcobnVsbCkpfSkK
+dCgkLCJmTiIsImlJIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVu
+dHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXtudWxsLiRtZXRob2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0
+Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJxaSIsIktmIixmdW5jdGlvbigpe3JldHVy
+biBILmNNKEguUzcodm9pZCAwKSl9KQp0KCQsInJaIiwiWmgiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00o
+ZnVuY3Rpb24oKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5eyh2b2lkIDApLiRt
+ZXRob2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgk
+LCJrcSIsImNQIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguTWoobnVsbCkpfSkKdCgkLCJ0dCIsImMz
+IixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5e251bGwuJG1ldGhvZCR9Y2F0Y2go
+cyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJkdCIsIkhLIixmdW5jdGlvbigpe3JldHVybiBI
+LmNNKEguTWoodm9pZCAwKSl9KQp0KCQsIkE3IiwicjEiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVu
+Y3Rpb24oKXt0cnl7KHZvaWQgMCkuJG1ldGhvZCR9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkp
+fSkKdCgkLCJXYyIsInV0IixmdW5jdGlvbigpe3JldHVybiBQLk9qKCl9KQp0KCQsImtoIiwicmYiLGZ1
+bmN0aW9uKCl7cmV0dXJuIFAuV0koKX0pCnQoJCwiYnQiLCJWNyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5E
+UShILlhGKEguVk0oWy0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
+LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
+LC0yLC0xLC0yLC0yLC0yLC0yLC0yLDYyLC0yLDYyLC0yLDYzLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5
+LDYwLDYxLC0yLC0yLC0yLC0xLC0yLC0yLC0yLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMs
+MTQsMTUsMTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUsLTIsLTIsLTIsLTIsNjMsLTIsMjYsMjcs
+MjgsMjksMzAsMzEsMzIsMzMsMzQsMzUsMzYsMzcsMzgsMzksNDAsNDEsNDIsNDMsNDQsNDUsNDYsNDcs
+NDgsNDksNTAsNTEsLTIsLTIsLTIsLTIsLTJdLHUudCkpKX0pCnQoJCwiTTUiLCJ3USIsZnVuY3Rpb24o
+KXtyZXR1cm4gdHlwZW9mIHByb2Nlc3MhPSJ1bmRlZmluZWQiJiZPYmplY3QucHJvdG90eXBlLnRvU3Ry
+aW5nLmNhbGwocHJvY2Vzcyk9PSJbb2JqZWN0IHByb2Nlc3NdIiYmcHJvY2Vzcy5wbGF0Zm9ybT09Indp
+bjMyIn0pCnQoJCwibWYiLCJ6NCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXltcXC1cXC4wLTlBLVpf
+YS16fl0qJCIpfSkKdCgkLCJKRyIsInZaIixmdW5jdGlvbigpe3JldHVybiBQLnV4KCl9KQp0KCQsIlND
+IiwiQU4iLGZ1bmN0aW9uKCl7cmV0dXJuIFAudE0oWyJBIiwiQUJCUiIsIkFDUk9OWU0iLCJBRERSRVNT
+IiwiQVJFQSIsIkFSVElDTEUiLCJBU0lERSIsIkFVRElPIiwiQiIsIkJESSIsIkJETyIsIkJJRyIsIkJM
+T0NLUVVPVEUiLCJCUiIsIkJVVFRPTiIsIkNBTlZBUyIsIkNBUFRJT04iLCJDRU5URVIiLCJDSVRFIiwi
+Q09ERSIsIkNPTCIsIkNPTEdST1VQIiwiQ09NTUFORCIsIkRBVEEiLCJEQVRBTElTVCIsIkREIiwiREVM
+IiwiREVUQUlMUyIsIkRGTiIsIkRJUiIsIkRJViIsIkRMIiwiRFQiLCJFTSIsIkZJRUxEU0VUIiwiRklH
+Q0FQVElPTiIsIkZJR1VSRSIsIkZPTlQiLCJGT09URVIiLCJGT1JNIiwiSDEiLCJIMiIsIkgzIiwiSDQi
+LCJINSIsIkg2IiwiSEVBREVSIiwiSEdST1VQIiwiSFIiLCJJIiwiSUZSQU1FIiwiSU1HIiwiSU5QVVQi
+LCJJTlMiLCJLQkQiLCJMQUJFTCIsIkxFR0VORCIsIkxJIiwiTUFQIiwiTUFSSyIsIk1FTlUiLCJNRVRF
+UiIsIk5BViIsIk5PQlIiLCJPTCIsIk9QVEdST1VQIiwiT1BUSU9OIiwiT1VUUFVUIiwiUCIsIlBSRSIs
+IlBST0dSRVNTIiwiUSIsIlMiLCJTQU1QIiwiU0VDVElPTiIsIlNFTEVDVCIsIlNNQUxMIiwiU09VUkNF
+IiwiU1BBTiIsIlNUUklLRSIsIlNUUk9ORyIsIlNVQiIsIlNVTU1BUlkiLCJTVVAiLCJUQUJMRSIsIlRC
+T0RZIiwiVEQiLCJURVhUQVJFQSIsIlRGT09UIiwiVEgiLCJUSEVBRCIsIlRJTUUiLCJUUiIsIlRSQUNL
+IiwiVFQiLCJVIiwiVUwiLCJWQVIiLCJWSURFTyIsIldCUiJdLHUuTil9KQp0KCQsIlg0IiwiaEciLGZ1
+bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5cXFMrJCIpfSkKdCgkLCJ3TyIsIm93IixmdW5jdGlvbigpe3Jl
+dHVybiB1LnUuYihQLk5EKHNlbGYpKX0pCnQoJCwia3QiLCJSOCIsZnVuY3Rpb24oKXtyZXR1cm4gSC5Z
+ZygiXyRkYXJ0X2RhcnRPYmplY3QiKX0pCnQoJCwiSmUiLCJrSSIsZnVuY3Rpb24oKXtyZXR1cm4gZnVu
+Y3Rpb24gRGFydE9iamVjdChhKXt0aGlzLm89YX19KQp0KCQsInF0IiwiekIiLGZ1bmN0aW9uKCl7cmV0
+dXJuIG5ldyBULkdWKCl9KQp0KCQsImZlIiwiS0ciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLlhBKCl9
+KQp0KCQsIm1NIiwiblUiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBNLmxJKCQuSGsoKSl9KQp0KCQsInly
+IiwiYkQiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBFLk9GKFAubnUoIi8iKSxQLm51KCJbXi9dJCIpLFAu
+bnUoIl4vIikpfSkKdCgkLCJNayIsIktrIixmdW5jdGlvbigpe3JldHVybiBuZXcgTC5JVihQLm51KCJb
+L1xcXFxdIiksUC5udSgiW14vXFxcXF0kIiksUC5udSgiXihcXFxcXFxcXFteXFxcXF0rXFxcXFteXFxc
+XC9dK3xbYS16QS1aXTpbL1xcXFxdKSIpLFAubnUoIl5bL1xcXFxdKD8hWy9cXFxcXSkiKSl9KQp0KCQs
+ImFrIiwiRWIiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBGLnJ1KFAubnUoIi8iKSxQLm51KCIoXlthLXpB
+LVpdWy0rLmEtekEtWlxcZF0qOi8vfFteL10pJCIpLFAubnUoIlthLXpBLVpdWy0rLmEtekEtWlxcZF0q
+Oi8vW14vXSoiKSxQLm51KCJeLyIpKX0pCnQoJCwibHMiLCJIayIsZnVuY3Rpb24oKXtyZXR1cm4gTy5S
+aCgpfSl9KSgpOyhmdW5jdGlvbiBuYXRpdmVTdXBwb3J0KCl7IWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rp
+b24oYSl7dmFyIG49e30KblthXT0xCnJldHVybiBPYmplY3Qua2V5cyhodW5rSGVscGVycy5jb252ZXJ0
+VG9GYXN0T2JqZWN0KG4pKVswXX0Kdi5nZXRJc29sYXRlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiB0KCJf
+X19kYXJ0XyIrYSt2Lmlzb2xhdGVUYWcpfQp2YXIgcz0iX19fZGFydF9pc29sYXRlX3RhZ3NfIgp2YXIg
+cj1PYmplY3Rbc118fChPYmplY3Rbc109T2JqZWN0LmNyZWF0ZShudWxsKSkKdmFyIHE9Il9aeFl4WCIK
+Zm9yKHZhciBwPTA7O3ArKyl7dmFyIG89dChxKyJfIitwKyJfIikKaWYoIShvIGluIHIpKXtyW29dPTEK
+di5pc29sYXRlVGFnPW8KYnJlYWt9fXYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWU9di5nZXRJc29sYXRlVGFn
+KCJkaXNwYXRjaF9yZWNvcmQiKX0oKQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUludGVyY2VwdG9yc0J5
+VGFnKHtET01FcnJvcjpKLnZCLERPTUltcGxlbWVudGF0aW9uOkoudkIsTWVkaWFFcnJvcjpKLnZCLE5h
+dmlnYXRvcjpKLnZCLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTpKLnZCLE5hdmlnYXRvclVzZXJN
+ZWRpYUVycm9yOkoudkIsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6Si52QixQb3NpdGlvbkVycm9yOkoudkIs
+UmFuZ2U6Si52QixTUUxFcnJvcjpKLnZCLERhdGFWaWV3OkguRVQsQXJyYXlCdWZmZXJWaWV3OkguRVQs
+RmxvYXQzMkFycmF5OkguRGcsRmxvYXQ2NEFycmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJy
+YXk6SC5kRSxJbnQ4QXJyYXk6SC5aQSxVaW50MTZBcnJheTpILndmLFVpbnQzMkFycmF5OkguUHEsVWlu
+dDhDbGFtcGVkQXJyYXk6SC5lRSxDYW52YXNQaXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhU
+TUxBdWRpb0VsZW1lbnQ6Vy5xRSxIVE1MQlJFbGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5x
+RSxIVE1MQ2FudmFzRWxlbWVudDpXLnFFLEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVs
+ZW1lbnQ6Vy5xRSxIVE1MRGF0YUVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRN
+TERldGFpbHNFbGVtZW50OlcucUUsSFRNTERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpX
+LnFFLEhUTUxFbWJlZEVsZW1lbnQ6Vy5xRSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxl
+bWVudDpXLnFFLEhUTUxIZWFkRWxlbWVudDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxI
+dG1sRWxlbWVudDpXLnFFLEhUTUxJRnJhbWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFF
+LEhUTUxJbnB1dEVsZW1lbnQ6Vy5xRSxIVE1MTElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpX
+LnFFLEhUTUxMZWdlbmRFbGVtZW50OlcucUUsSFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1l
+bnQ6Vy5xRSxIVE1MTWVkaWFFbGVtZW50OlcucUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFF
+bGVtZW50OlcucUUsSFRNTE1ldGVyRWxlbWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9M
+aXN0RWxlbWVudDpXLnFFLEhUTUxPYmplY3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpX
+LnFFLEhUTUxPcHRpb25FbGVtZW50OlcucUUsSFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1F
+bGVtZW50OlcucUUsSFRNTFBpY3R1cmVFbGVtZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1M
+UHJvZ3Jlc3NFbGVtZW50OlcucUUsSFRNTFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50
+OlcucUUsSFRNTFNoYWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNl
+RWxlbWVudDpXLnFFLEhUTUxTcGFuRWxlbWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1M
+VGFibGVDYXB0aW9uRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxl
+RGF0YUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFi
+bGVDb2xFbGVtZW50OlcucUUsSFRNTFRleHRBcmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpX
+LnFFLEhUTUxUaXRsZUVsZW1lbnQ6Vy5xRSxIVE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxl
+bWVudDpXLnFFLEhUTUxVbmtub3duRWxlbWVudDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1M
+RGlyZWN0b3J5RWxlbWVudDpXLnFFLEhUTUxGb250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6
+Vy5xRSxIVE1MRnJhbWVTZXRFbGVtZW50OlcucUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVs
+ZW1lbnQ6Vy5xRSxIVE1MQW5jaG9yRWxlbWVudDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxC
+YXNlRWxlbWVudDpXLm5CLEJsb2I6Vy5BeixIVE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246
+Vy5ueCxDaGFyYWN0ZXJEYXRhOlcubngsQ29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpX
+Lm54LFRleHQ6Vy5ueCxDU1NTdHlsZURlY2xhcmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6
+Vy5vSixDU1MyUHJvcGVydGllczpXLm9KLFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01F
+eGNlcHRpb246Vy5OaCxET01SZWN0UmVhZE9ubHk6Vy5JQixET01Ub2tlbkxpc3Q6Vy5uNyxFbGVtZW50
+OlcuY3YsQWJvcnRQYXltZW50RXZlbnQ6Vy5lYSxBbmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBs
+YXliYWNrRXZlbnQ6Vy5lYSxBcHBsaWNhdGlvbkNhY2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRG
+ZXRjaENsaWNrRXZlbnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRj
+aEZhaWxFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJv
+bXB0RXZlbnQ6Vy5lYSxCZWZvcmVVbmxvYWRFdmVudDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQ
+YXltZW50RXZlbnQ6Vy5lYSxDbGlwYm9hcmRFdmVudDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21F
+dmVudDpXLmVhLERldmljZU1vdGlvbkV2ZW50OlcuZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVh
+LEVycm9yRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50
+OlcuZWEsRmV0Y2hFdmVudDpXLmVhLEZvbnRGYWNlU2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNo
+RXZlbnQ6Vy5lYSxHYW1lcGFkRXZlbnQ6Vy5lYSxIYXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZl
+bnQ6Vy5lYSxNZWRpYUVuY3J5cHRlZEV2ZW50OlcuZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxN
+ZWRpYVF1ZXJ5TGlzdEV2ZW50OlcuZWEsTWVkaWFTdHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJh
+Y2tFdmVudDpXLmVhLE1lc3NhZ2VFdmVudDpXLmVhLE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJ
+TWVzc2FnZUV2ZW50OlcuZWEsTXV0YXRpb25FdmVudDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEs
+UGFnZVRyYW5zaXRpb25FdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVx
+dWVzdFVwZGF0ZUV2ZW50OlcuZWEsUG9wU3RhdGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rp
+b25BdmFpbGFibGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEs
+UHJvbWlzZVJlamVjdGlvbkV2ZW50OlcuZWEsUHVzaEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVu
+dDpXLmVhLFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50
+OlcuZWEsUlRDVHJhY2tFdmVudDpXLmVhLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxT
+ZW5zb3JFcnJvckV2ZW50OlcuZWEsU3BlZWNoUmVjb2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29n
+bml0aW9uRXZlbnQ6Vy5lYSxTcGVlY2hTeW50aGVzaXNFdmVudDpXLmVhLFN0b3JhZ2VFdmVudDpXLmVh
+LFN5bmNFdmVudDpXLmVhLFRyYWNrRXZlbnQ6Vy5lYSxUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxXZWJLaXRU
+cmFuc2l0aW9uRXZlbnQ6Vy5lYSxWUkRldmljZUV2ZW50OlcuZWEsVlJEaXNwbGF5RXZlbnQ6Vy5lYSxW
+UlNlc3Npb25FdmVudDpXLmVhLE1vam9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6Vy5lYSxVU0JDb25uZWN0
+aW9uRXZlbnQ6Vy5lYSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6Vy5lYSxBdWRpb1Byb2Nlc3NpbmdFdmVu
+dDpXLmVhLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDpXLmVhLFdlYkdMQ29udGV4dEV2ZW50Olcu
+ZWEsRXZlbnQ6Vy5lYSxJbnB1dEV2ZW50OlcuZWEsRXZlbnRUYXJnZXQ6Vy5EMCxGaWxlOlcuVDUsSFRN
+TEZvcm1FbGVtZW50OlcuaDQsSGlzdG9yeTpXLmJyLEhUTUxEb2N1bWVudDpXLlZiLFhNTEh0dHBSZXF1
+ZXN0OlcuTzcsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpXLndhLEltYWdlRGF0YTpXLlNnLExvY2F0
+aW9uOlcudTgsTW91c2VFdmVudDpXLkFqLERyYWdFdmVudDpXLkFqLFBvaW50ZXJFdmVudDpXLkFqLFdo
+ZWVsRXZlbnQ6Vy5BaixEb2N1bWVudEZyYWdtZW50OlcudUgsU2hhZG93Um9vdDpXLnVILERvY3VtZW50
+VHlwZTpXLnVILE5vZGU6Vy51SCxOb2RlTGlzdDpXLkJILFJhZGlvTm9kZUxpc3Q6Vy5CSCxIVE1MUGFy
+YWdyYXBoRWxlbWVudDpXLlNOLFByb2dyZXNzRXZlbnQ6Vy5ldyxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6
+Vy5ldyxIVE1MU2VsZWN0RWxlbWVudDpXLmxwLEhUTUxUYWJsZUVsZW1lbnQ6Vy5UYixIVE1MVGFibGVS
+b3dFbGVtZW50OlcuSXYsSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ6Vy5CVCxIVE1MVGVtcGxhdGVFbGVt
+ZW50OlcueVksQ29tcG9zaXRpb25FdmVudDpXLnc2LEZvY3VzRXZlbnQ6Vy53NixLZXlib2FyZEV2ZW50
+OlcudzYsVGV4dEV2ZW50OlcudzYsVG91Y2hFdmVudDpXLnc2LFVJRXZlbnQ6Vy53NixXaW5kb3c6Vy5L
+NSxET01XaW5kb3c6Vy5LNSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFNlcnZpY2VXb3Jr
+ZXJHbG9iYWxTY29wZTpXLkNtLFNoYXJlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sV29ya2VyR2xvYmFs
+U2NvcGU6Vy5DbSxBdHRyOlcuQ1EsQ2xpZW50UmVjdDpXLnc0LERPTVJlY3Q6Vy53NCxOYW1lZE5vZGVN
+YXA6Vy5yaCxNb3pOYW1lZEF0dHJNYXA6Vy5yaCxJREJLZXlSYW5nZTpQLmhGLFNWR1NjcmlwdEVsZW1l
+bnQ6UC5uZCxTVkdBRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVFbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZU1v
+dGlvbkVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlVHJhbnNmb3JtRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGlv
+bkVsZW1lbnQ6UC5kNSxTVkdDaXJjbGVFbGVtZW50OlAuZDUsU1ZHQ2xpcFBhdGhFbGVtZW50OlAuZDUs
+U1ZHRGVmc0VsZW1lbnQ6UC5kNSxTVkdEZXNjRWxlbWVudDpQLmQ1LFNWR0Rpc2NhcmRFbGVtZW50OlAu
+ZDUsU1ZHRWxsaXBzZUVsZW1lbnQ6UC5kNSxTVkdGRUJsZW5kRWxlbWVudDpQLmQ1LFNWR0ZFQ29sb3JN
+YXRyaXhFbGVtZW50OlAuZDUsU1ZHRkVDb21wb25lbnRUcmFuc2ZlckVsZW1lbnQ6UC5kNSxTVkdGRUNv
+bXBvc2l0ZUVsZW1lbnQ6UC5kNSxTVkdGRUNvbnZvbHZlTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFRGlm
+ZnVzZUxpZ2h0aW5nRWxlbWVudDpQLmQ1LFNWR0ZFRGlzcGxhY2VtZW50TWFwRWxlbWVudDpQLmQ1LFNW
+R0ZFRGlzdGFudExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFRmxvb2RFbGVtZW50OlAuZDUsU1ZHRkVGdW5j
+QUVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNCRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0dFbGVtZW50OlAuZDUs
+U1ZHRkVGdW5jUkVsZW1lbnQ6UC5kNSxTVkdGRUdhdXNzaWFuQmx1ckVsZW1lbnQ6UC5kNSxTVkdGRUlt
+YWdlRWxlbWVudDpQLmQ1LFNWR0ZFTWVyZ2VFbGVtZW50OlAuZDUsU1ZHRkVNZXJnZU5vZGVFbGVtZW50
+OlAuZDUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDpQLmQ1LFNWR0ZFT2Zmc2V0RWxlbWVudDpQLmQ1LFNW
+R0ZFUG9pbnRMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OlAuZDUs
+U1ZHRkVTcG90TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVUaWxlRWxlbWVudDpQLmQ1LFNWR0ZFVHVyYnVs
+ZW5jZUVsZW1lbnQ6UC5kNSxTVkdGaWx0ZXJFbGVtZW50OlAuZDUsU1ZHRm9yZWlnbk9iamVjdEVsZW1l
+bnQ6UC5kNSxTVkdHRWxlbWVudDpQLmQ1LFNWR0dlb21ldHJ5RWxlbWVudDpQLmQ1LFNWR0dyYXBoaWNz
+RWxlbWVudDpQLmQ1LFNWR0ltYWdlRWxlbWVudDpQLmQ1LFNWR0xpbmVFbGVtZW50OlAuZDUsU1ZHTGlu
+ZWFyR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHTWFya2VyRWxlbWVudDpQLmQ1LFNWR01hc2tFbGVtZW50
+OlAuZDUsU1ZHTWV0YWRhdGFFbGVtZW50OlAuZDUsU1ZHUGF0aEVsZW1lbnQ6UC5kNSxTVkdQYXR0ZXJu
+RWxlbWVudDpQLmQ1LFNWR1BvbHlnb25FbGVtZW50OlAuZDUsU1ZHUG9seWxpbmVFbGVtZW50OlAuZDUs
+U1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHUmVjdEVsZW1lbnQ6UC5kNSxTVkdTZXRFbGVt
+ZW50OlAuZDUsU1ZHU3RvcEVsZW1lbnQ6UC5kNSxTVkdTdHlsZUVsZW1lbnQ6UC5kNSxTVkdTVkdFbGVt
+ZW50OlAuZDUsU1ZHU3dpdGNoRWxlbWVudDpQLmQ1LFNWR1N5bWJvbEVsZW1lbnQ6UC5kNSxTVkdUU3Bh
+bkVsZW1lbnQ6UC5kNSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6UC5kNSxTVkdUZXh0RWxlbWVudDpQLmQ1
+LFNWR1RleHRQYXRoRWxlbWVudDpQLmQ1LFNWR1RleHRQb3NpdGlvbmluZ0VsZW1lbnQ6UC5kNSxTVkdU
+aXRsZUVsZW1lbnQ6UC5kNSxTVkdVc2VFbGVtZW50OlAuZDUsU1ZHVmlld0VsZW1lbnQ6UC5kNSxTVkdH
+cmFkaWVudEVsZW1lbnQ6UC5kNSxTVkdDb21wb25lbnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDpQLmQ1
+LFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6UC5kNSxTVkdNUGF0aEVsZW1lbnQ6UC5kNSxTVkdFbGVtZW50
+OlAuZDV9KQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUxlYWZUYWdzKHtET01FcnJvcjp0cnVlLERPTUlt
+cGxlbWVudGF0aW9uOnRydWUsTWVkaWFFcnJvcjp0cnVlLE5hdmlnYXRvcjp0cnVlLE5hdmlnYXRvckNv
+bmN1cnJlbnRIYXJkd2FyZTp0cnVlLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOnRydWUsT3ZlcmNvbnN0
+cmFpbmVkRXJyb3I6dHJ1ZSxQb3NpdGlvbkVycm9yOnRydWUsUmFuZ2U6dHJ1ZSxTUUxFcnJvcjp0cnVl
+LERhdGFWaWV3OnRydWUsQXJyYXlCdWZmZXJWaWV3OmZhbHNlLEZsb2F0MzJBcnJheTp0cnVlLEZsb2F0
+NjRBcnJheTp0cnVlLEludDE2QXJyYXk6dHJ1ZSxJbnQzMkFycmF5OnRydWUsSW50OEFycmF5OnRydWUs
+VWludDE2QXJyYXk6dHJ1ZSxVaW50MzJBcnJheTp0cnVlLFVpbnQ4Q2xhbXBlZEFycmF5OnRydWUsQ2Fu
+dmFzUGl4ZWxBcnJheTp0cnVlLFVpbnQ4QXJyYXk6ZmFsc2UsSFRNTEF1ZGlvRWxlbWVudDp0cnVlLEhU
+TUxCUkVsZW1lbnQ6dHJ1ZSxIVE1MQnV0dG9uRWxlbWVudDp0cnVlLEhUTUxDYW52YXNFbGVtZW50OnRy
+dWUsSFRNTENvbnRlbnRFbGVtZW50OnRydWUsSFRNTERMaXN0RWxlbWVudDp0cnVlLEhUTUxEYXRhRWxl
+bWVudDp0cnVlLEhUTUxEYXRhTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MRGV0YWlsc0VsZW1lbnQ6dHJ1ZSxI
+VE1MRGlhbG9nRWxlbWVudDp0cnVlLEhUTUxEaXZFbGVtZW50OnRydWUsSFRNTEVtYmVkRWxlbWVudDp0
+cnVlLEhUTUxGaWVsZFNldEVsZW1lbnQ6dHJ1ZSxIVE1MSFJFbGVtZW50OnRydWUsSFRNTEhlYWRFbGVt
+ZW50OnRydWUsSFRNTEhlYWRpbmdFbGVtZW50OnRydWUsSFRNTEh0bWxFbGVtZW50OnRydWUsSFRNTElG
+cmFtZUVsZW1lbnQ6dHJ1ZSxIVE1MSW1hZ2VFbGVtZW50OnRydWUsSFRNTElucHV0RWxlbWVudDp0cnVl
+LEhUTUxMSUVsZW1lbnQ6dHJ1ZSxIVE1MTGFiZWxFbGVtZW50OnRydWUsSFRNTExlZ2VuZEVsZW1lbnQ6
+dHJ1ZSxIVE1MTGlua0VsZW1lbnQ6dHJ1ZSxIVE1MTWFwRWxlbWVudDp0cnVlLEhUTUxNZWRpYUVsZW1l
+bnQ6dHJ1ZSxIVE1MTWVudUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJF
+bGVtZW50OnRydWUsSFRNTE1vZEVsZW1lbnQ6dHJ1ZSxIVE1MT0xpc3RFbGVtZW50OnRydWUsSFRNTE9i
+amVjdEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0R3JvdXBFbGVtZW50OnRydWUsSFRNTE9wdGlvbkVsZW1lbnQ6
+dHJ1ZSxIVE1MT3V0cHV0RWxlbWVudDp0cnVlLEhUTUxQYXJhbUVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVy
+ZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJlRWxlbWVudDp0cnVlLEhUTUxQcm9ncmVzc0VsZW1lbnQ6dHJ1ZSxI
+VE1MUXVvdGVFbGVtZW50OnRydWUsSFRNTFNjcmlwdEVsZW1lbnQ6dHJ1ZSxIVE1MU2hhZG93RWxlbWVu
+dDp0cnVlLEhUTUxTbG90RWxlbWVudDp0cnVlLEhUTUxTb3VyY2VFbGVtZW50OnRydWUsSFRNTFNwYW5F
+bGVtZW50OnRydWUsSFRNTFN0eWxlRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OnRy
+dWUsSFRNTFRhYmxlQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxI
+VE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1M
+VGV4dEFyZWFFbGVtZW50OnRydWUsSFRNTFRpbWVFbGVtZW50OnRydWUsSFRNTFRpdGxlRWxlbWVudDp0
+cnVlLEhUTUxUcmFja0VsZW1lbnQ6dHJ1ZSxIVE1MVUxpc3RFbGVtZW50OnRydWUsSFRNTFVua25vd25F
+bGVtZW50OnRydWUsSFRNTFZpZGVvRWxlbWVudDp0cnVlLEhUTUxEaXJlY3RvcnlFbGVtZW50OnRydWUs
+SFRNTEZvbnRFbGVtZW50OnRydWUsSFRNTEZyYW1lRWxlbWVudDp0cnVlLEhUTUxGcmFtZVNldEVsZW1l
+bnQ6dHJ1ZSxIVE1MTWFycXVlZUVsZW1lbnQ6dHJ1ZSxIVE1MRWxlbWVudDpmYWxzZSxIVE1MQW5jaG9y
+RWxlbWVudDp0cnVlLEhUTUxBcmVhRWxlbWVudDp0cnVlLEhUTUxCYXNlRWxlbWVudDp0cnVlLEJsb2I6
+ZmFsc2UsSFRNTEJvZHlFbGVtZW50OnRydWUsQ0RBVEFTZWN0aW9uOnRydWUsQ2hhcmFjdGVyRGF0YTp0
+cnVlLENvbW1lbnQ6dHJ1ZSxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb246dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5
+bGVEZWNsYXJhdGlvbjp0cnVlLE1TU3R5bGVDU1NQcm9wZXJ0aWVzOnRydWUsQ1NTMlByb3BlcnRpZXM6
+dHJ1ZSxYTUxEb2N1bWVudDp0cnVlLERvY3VtZW50OmZhbHNlLERPTUV4Y2VwdGlvbjp0cnVlLERPTVJl
+Y3RSZWFkT25seTpmYWxzZSxET01Ub2tlbkxpc3Q6dHJ1ZSxFbGVtZW50OmZhbHNlLEFib3J0UGF5bWVu
+dEV2ZW50OnRydWUsQW5pbWF0aW9uRXZlbnQ6dHJ1ZSxBbmltYXRpb25QbGF5YmFja0V2ZW50OnRydWUs
+QXBwbGljYXRpb25DYWNoZUVycm9yRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hDbGlja0V2ZW50OnRy
+dWUsQmFja2dyb3VuZEZldGNoRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hGYWlsRXZlbnQ6dHJ1ZSxC
+YWNrZ3JvdW5kRmV0Y2hlZEV2ZW50OnRydWUsQmVmb3JlSW5zdGFsbFByb21wdEV2ZW50OnRydWUsQmVm
+b3JlVW5sb2FkRXZlbnQ6dHJ1ZSxCbG9iRXZlbnQ6dHJ1ZSxDYW5NYWtlUGF5bWVudEV2ZW50OnRydWUs
+Q2xpcGJvYXJkRXZlbnQ6dHJ1ZSxDbG9zZUV2ZW50OnRydWUsQ3VzdG9tRXZlbnQ6dHJ1ZSxEZXZpY2VN
+b3Rpb25FdmVudDp0cnVlLERldmljZU9yaWVudGF0aW9uRXZlbnQ6dHJ1ZSxFcnJvckV2ZW50OnRydWUs
+RXh0ZW5kYWJsZUV2ZW50OnRydWUsRXh0ZW5kYWJsZU1lc3NhZ2VFdmVudDp0cnVlLEZldGNoRXZlbnQ6
+dHJ1ZSxGb250RmFjZVNldExvYWRFdmVudDp0cnVlLEZvcmVpZ25GZXRjaEV2ZW50OnRydWUsR2FtZXBh
+ZEV2ZW50OnRydWUsSGFzaENoYW5nZUV2ZW50OnRydWUsSW5zdGFsbEV2ZW50OnRydWUsTWVkaWFFbmNy
+eXB0ZWRFdmVudDp0cnVlLE1lZGlhS2V5TWVzc2FnZUV2ZW50OnRydWUsTWVkaWFRdWVyeUxpc3RFdmVu
+dDp0cnVlLE1lZGlhU3RyZWFtRXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbVRyYWNrRXZlbnQ6dHJ1ZSxNZXNz
+YWdlRXZlbnQ6dHJ1ZSxNSURJQ29ubmVjdGlvbkV2ZW50OnRydWUsTUlESU1lc3NhZ2VFdmVudDp0cnVl
+LE11dGF0aW9uRXZlbnQ6dHJ1ZSxOb3RpZmljYXRpb25FdmVudDp0cnVlLFBhZ2VUcmFuc2l0aW9uRXZl
+bnQ6dHJ1ZSxQYXltZW50UmVxdWVzdEV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RVcGRhdGVFdmVudDp0
+cnVlLFBvcFN0YXRlRXZlbnQ6dHJ1ZSxQcmVzZW50YXRpb25Db25uZWN0aW9uQXZhaWxhYmxlRXZlbnQ6
+dHJ1ZSxQcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VFdmVudDp0cnVlLFByb21pc2VSZWplY3Rpb25F
+dmVudDp0cnVlLFB1c2hFdmVudDp0cnVlLFJUQ0RhdGFDaGFubmVsRXZlbnQ6dHJ1ZSxSVENEVE1GVG9u
+ZUNoYW5nZUV2ZW50OnRydWUsUlRDUGVlckNvbm5lY3Rpb25JY2VFdmVudDp0cnVlLFJUQ1RyYWNrRXZl
+bnQ6dHJ1ZSxTZWN1cml0eVBvbGljeVZpb2xhdGlvbkV2ZW50OnRydWUsU2Vuc29yRXJyb3JFdmVudDp0
+cnVlLFNwZWVjaFJlY29nbml0aW9uRXJyb3I6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkV2ZW50OnRydWUs
+U3BlZWNoU3ludGhlc2lzRXZlbnQ6dHJ1ZSxTdG9yYWdlRXZlbnQ6dHJ1ZSxTeW5jRXZlbnQ6dHJ1ZSxU
+cmFja0V2ZW50OnRydWUsVHJhbnNpdGlvbkV2ZW50OnRydWUsV2ViS2l0VHJhbnNpdGlvbkV2ZW50OnRy
+dWUsVlJEZXZpY2VFdmVudDp0cnVlLFZSRGlzcGxheUV2ZW50OnRydWUsVlJTZXNzaW9uRXZlbnQ6dHJ1
+ZSxNb2pvSW50ZXJmYWNlUmVxdWVzdEV2ZW50OnRydWUsVVNCQ29ubmVjdGlvbkV2ZW50OnRydWUsSURC
+VmVyc2lvbkNoYW5nZUV2ZW50OnRydWUsQXVkaW9Qcm9jZXNzaW5nRXZlbnQ6dHJ1ZSxPZmZsaW5lQXVk
+aW9Db21wbGV0aW9uRXZlbnQ6dHJ1ZSxXZWJHTENvbnRleHRFdmVudDp0cnVlLEV2ZW50OmZhbHNlLElu
+cHV0RXZlbnQ6ZmFsc2UsRXZlbnRUYXJnZXQ6ZmFsc2UsRmlsZTp0cnVlLEhUTUxGb3JtRWxlbWVudDp0
+cnVlLEhpc3Rvcnk6dHJ1ZSxIVE1MRG9jdW1lbnQ6dHJ1ZSxYTUxIdHRwUmVxdWVzdDp0cnVlLFhNTEh0
+dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6ZmFsc2UsSW1hZ2VEYXRhOnRydWUsTG9jYXRpb246dHJ1ZSxNb3Vz
+ZUV2ZW50OnRydWUsRHJhZ0V2ZW50OnRydWUsUG9pbnRlckV2ZW50OnRydWUsV2hlZWxFdmVudDp0cnVl
+LERvY3VtZW50RnJhZ21lbnQ6dHJ1ZSxTaGFkb3dSb290OnRydWUsRG9jdW1lbnRUeXBlOnRydWUsTm9k
+ZTpmYWxzZSxOb2RlTGlzdDp0cnVlLFJhZGlvTm9kZUxpc3Q6dHJ1ZSxIVE1MUGFyYWdyYXBoRWxlbWVu
+dDp0cnVlLFByb2dyZXNzRXZlbnQ6dHJ1ZSxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6dHJ1ZSxIVE1MU2Vs
+ZWN0RWxlbWVudDp0cnVlLEhUTUxUYWJsZUVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVSb3dFbGVtZW50OnRy
+dWUsSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGVtcGxhdGVFbGVtZW50OnRydWUsQ29t
+cG9zaXRpb25FdmVudDp0cnVlLEZvY3VzRXZlbnQ6dHJ1ZSxLZXlib2FyZEV2ZW50OnRydWUsVGV4dEV2
+ZW50OnRydWUsVG91Y2hFdmVudDp0cnVlLFVJRXZlbnQ6ZmFsc2UsV2luZG93OnRydWUsRE9NV2luZG93
+OnRydWUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTZXJ2aWNlV29ya2VyR2xvYmFsU2Nv
+cGU6dHJ1ZSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFdvcmtlckdsb2JhbFNjb3BlOnRydWUs
+QXR0cjp0cnVlLENsaWVudFJlY3Q6dHJ1ZSxET01SZWN0OnRydWUsTmFtZWROb2RlTWFwOnRydWUsTW96
+TmFtZWRBdHRyTWFwOnRydWUsSURCS2V5UmFuZ2U6dHJ1ZSxTVkdTY3JpcHRFbGVtZW50OnRydWUsU1ZH
+QUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50
+OnRydWUsU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRpb25FbGVtZW50OnRy
+dWUsU1ZHQ2lyY2xlRWxlbWVudDp0cnVlLFNWR0NsaXBQYXRoRWxlbWVudDp0cnVlLFNWR0RlZnNFbGVt
+ZW50OnRydWUsU1ZHRGVzY0VsZW1lbnQ6dHJ1ZSxTVkdEaXNjYXJkRWxlbWVudDp0cnVlLFNWR0VsbGlw
+c2VFbGVtZW50OnRydWUsU1ZHRkVCbGVuZEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbG9yTWF0cml4RWxlbWVu
+dDp0cnVlLFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50OnRydWUsU1ZHRkVDb21wb3NpdGVFbGVt
+ZW50OnRydWUsU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRURpZmZ1c2VMaWdodGlu
+Z0VsZW1lbnQ6dHJ1ZSxTVkdGRURpc3BsYWNlbWVudE1hcEVsZW1lbnQ6dHJ1ZSxTVkdGRURpc3RhbnRM
+aWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRUZsb29kRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0FFbGVtZW50OnRy
+dWUsU1ZHRkVGdW5jQkVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNHRWxlbWVudDp0cnVlLFNWR0ZFRnVuY1JF
+bGVtZW50OnRydWUsU1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50OnRydWUsU1ZHRkVJbWFnZUVsZW1lbnQ6
+dHJ1ZSxTVkdGRU1lcmdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VOb2RlRWxlbWVudDp0cnVlLFNWR0ZF
+TW9ycGhvbG9neUVsZW1lbnQ6dHJ1ZSxTVkdGRU9mZnNldEVsZW1lbnQ6dHJ1ZSxTVkdGRVBvaW50TGln
+aHRFbGVtZW50OnRydWUsU1ZHRkVTcGVjdWxhckxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFU3BvdExp
+Z2h0RWxlbWVudDp0cnVlLFNWR0ZFVGlsZUVsZW1lbnQ6dHJ1ZSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50
+OnRydWUsU1ZHRmlsdGVyRWxlbWVudDp0cnVlLFNWR0ZvcmVpZ25PYmplY3RFbGVtZW50OnRydWUsU1ZH
+R0VsZW1lbnQ6dHJ1ZSxTVkdHZW9tZXRyeUVsZW1lbnQ6dHJ1ZSxTVkdHcmFwaGljc0VsZW1lbnQ6dHJ1
+ZSxTVkdJbWFnZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5lRWxlbWVudDp0cnVlLFNWR0xpbmVhckdyYWRpZW50
+RWxlbWVudDp0cnVlLFNWR01hcmtlckVsZW1lbnQ6dHJ1ZSxTVkdNYXNrRWxlbWVudDp0cnVlLFNWR01l
+dGFkYXRhRWxlbWVudDp0cnVlLFNWR1BhdGhFbGVtZW50OnRydWUsU1ZHUGF0dGVybkVsZW1lbnQ6dHJ1
+ZSxTVkdQb2x5Z29uRWxlbWVudDp0cnVlLFNWR1BvbHlsaW5lRWxlbWVudDp0cnVlLFNWR1JhZGlhbEdy
+YWRpZW50RWxlbWVudDp0cnVlLFNWR1JlY3RFbGVtZW50OnRydWUsU1ZHU2V0RWxlbWVudDp0cnVlLFNW
+R1N0b3BFbGVtZW50OnRydWUsU1ZHU3R5bGVFbGVtZW50OnRydWUsU1ZHU1ZHRWxlbWVudDp0cnVlLFNW
+R1N3aXRjaEVsZW1lbnQ6dHJ1ZSxTVkdTeW1ib2xFbGVtZW50OnRydWUsU1ZHVFNwYW5FbGVtZW50OnRy
+dWUsU1ZHVGV4dENvbnRlbnRFbGVtZW50OnRydWUsU1ZHVGV4dEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0UGF0
+aEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0UG9zaXRpb25pbmdFbGVtZW50OnRydWUsU1ZHVGl0bGVFbGVtZW50
+OnRydWUsU1ZHVXNlRWxlbWVudDp0cnVlLFNWR1ZpZXdFbGVtZW50OnRydWUsU1ZHR3JhZGllbnRFbGVt
+ZW50OnRydWUsU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdGRURyb3BT
+aGFkb3dFbGVtZW50OnRydWUsU1ZHTVBhdGhFbGVtZW50OnRydWUsU1ZHRWxlbWVudDpmYWxzZX0pCkgu
+YjAuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5SRy4kbmF0aXZlU3VwZXJj
+bGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlZQLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1
+ZmZlclZpZXciCkguRGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5XQi4k
+bmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlpHLiRuYXRpdmVTdXBlcmNsYXNz
+VGFnPSJBcnJheUJ1ZmZlclZpZXciCkguUGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVy
+VmlldyJ9KSgpCmNvbnZlcnRBbGxUb0Zhc3RPYmplY3QodykKY29udmVydFRvRmFzdE9iamVjdCgkKTso
+ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGRvY3VtZW50PT09InVuZGVmaW5lZCIpe2EobnVsbCkKcmV0dXJu
+fWlmKHR5cGVvZiBkb2N1bWVudC5jdXJyZW50U2NyaXB0IT0ndW5kZWZpbmVkJyl7YShkb2N1bWVudC5j
+dXJyZW50U2NyaXB0KQpyZXR1cm59dmFyIHQ9ZG9jdW1lbnQuc2NyaXB0cwpmdW5jdGlvbiBvbkxvYWQo
+Yil7Zm9yKHZhciByPTA7cjx0Lmxlbmd0aDsrK3IpdFtyXS5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2Fk
+IixvbkxvYWQsZmFsc2UpCmEoYi50YXJnZXQpfWZvcih2YXIgcz0wO3M8dC5sZW5ndGg7KytzKXRbc10u
+YWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKX0pKGZ1bmN0aW9uKGEpe3YuY3VycmVu
+dFNjcmlwdD1hCmlmKHR5cGVvZiBkYXJ0TWFpblJ1bm5lcj09PSJmdW5jdGlvbiIpZGFydE1haW5SdW5u
+ZXIoTC5JcSxbXSkKZWxzZSBMLklxKFtdKX0pfSkoKQovLyMgc291cmNlTWFwcGluZ1VSTD1taWdyYXRp
+b24uanMubWFwCg==
''';
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart
index 4cece1d..6c7afbd 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/edit_details.dart
@@ -25,12 +25,17 @@
/// The path of the file that was edited.
final String path;
+ /// A list of traces representing stacktrace-like views of why the change was
+ /// made, or the empty list if there are no traces for this change.
+ final List<Trace> traces;
+
EditDetails(
{@required this.details,
this.edits,
@required this.explanation,
@required this.line,
- @required this.path});
+ @required this.path,
+ this.traces = const []});
EditDetails.fromJson(dynamic json)
: details = [
@@ -39,7 +44,8 @@
edits = _decodeEdits(json['edits']),
explanation = json['explanation'],
line = json['line'],
- path = json['path'];
+ path = json['path'],
+ traces = _decodeTraces(json['traces']);
Map<String, Object> toJson() => {
'details': [for (var detail in details) detail.toJson()],
@@ -47,10 +53,15 @@
'explanation': explanation,
'line': line,
'path': path,
+ if (traces != null)
+ 'traces': [for (var trace in traces) trace.toJson()],
};
static List<EditLink> _decodeEdits(dynamic json) =>
json == null ? null : [for (var edit in json) EditLink.fromJson(edit)];
+
+ static List<Trace> _decodeTraces(dynamic json) =>
+ json == null ? null : [for (var trace in json) Trace.fromJson(trace)];
}
/// Information about a single link that should be included in the
@@ -127,3 +138,57 @@
'path': path,
};
}
+
+/// A trace of why a nullability decision was made.
+class Trace {
+ /// Text description of the trace.
+ final String description;
+
+ /// List of trace entries.
+ final List<TraceEntry> entries;
+
+ Trace({@required this.description, @required this.entries});
+
+ Trace.fromJson(dynamic json)
+ : description = json['description'],
+ entries = [
+ for (var entry in json['entries']) TraceEntry.fromJson(entry)
+ ];
+
+ Map<String, Object> toJson() => {
+ 'description': description,
+ 'entries': [for (var entry in entries) entry.toJson()]
+ };
+}
+
+/// Information about a single entry in a nullability trace.
+class TraceEntry {
+ /// Text description of the entry.
+ final String description;
+
+ /// The function associated with the entry. We display this before the link
+ /// so that the trace has the familiar appearance of a stacktrace.
+ ///
+ /// Null if not known.
+ final String function;
+
+ /// Source code location associated with the entry, or `null` if no source
+ /// code location is known.
+ final TargetLink link;
+
+ TraceEntry({@required this.description, this.function, this.link});
+
+ TraceEntry.fromJson(dynamic json)
+ : description = json['description'],
+ function = json['function'],
+ link = _decodeLink(json['link']);
+
+ Map<String, Object> toJson() => {
+ 'description': description,
+ if (function != null) 'function': function,
+ if (link != null) 'link': link.toJson()
+ };
+
+ static TargetLink _decodeLink(dynamic json) =>
+ json == null ? null : TargetLink.fromJson(json);
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
index f37e014..36caedb 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
@@ -2,6 +2,7 @@
// 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.
+import 'dart:async';
import 'dart:convert';
import 'dart:html';
@@ -26,6 +27,19 @@
pushState(path, offset, lineNumber);
});
}
+
+ final applyMigrationButton = document.querySelector('.apply-migration');
+ applyMigrationButton.onClick.listen((event) {
+ doPost('/apply-migration').then((xhr) {
+ document.body.classes
+ ..remove('proposed')
+ ..add('applied');
+ }).catchError((e, st) {
+ logError('apply migration error: $e', st);
+
+ window.alert('Could not apply migration ($e).');
+ });
+ });
});
window.addEventListener('popstate', (event) {
@@ -48,15 +62,6 @@
String get rootPath => querySelector('.root').text.trim();
-/// Return the absolute path of [path], assuming [path] is relative to [root].
-String absolutePath(String path) {
- if (path[0] != '/') {
- return '$rootPath/$path';
- } else {
- return path;
- }
-}
-
void addArrowClickHandler(Element arrow) {
Element childList =
(arrow.parentNode as Element).querySelector(':scope > ul');
@@ -107,6 +112,19 @@
});
}
+Future<HttpRequest> doPost(String path) => HttpRequest.request(
+ path,
+ method: 'POST',
+ requestHeaders: {'Content-Type': 'application/json; charset=UTF-8'},
+ ).then((HttpRequest xhr) {
+ if (xhr.status == 200) {
+ // Request OK.
+ return xhr;
+ } else {
+ throw 'Request failed; status of ${xhr.status}';
+ }
+ });
+
int getLine(String location) {
String str = Uri.parse(location).queryParameters['line'];
return str == null ? null : int.tryParse(str);
@@ -150,28 +168,17 @@
void handlePostLinkClick(MouseEvent event) {
String path = (event.currentTarget as Element).getAttribute('href');
- // TODO(devoncarew): Validate that this path logic is correct.
- // This is only called by .post-link elements - the 'edits' / incremental
- // workflow code path.
- path = absolutePath(path);
// Directing the server to produce an edit; request it, then do work with the
// response.
- HttpRequest.request(
- path,
- method: 'POST',
- requestHeaders: {'Content-Type': 'application/json; charset=UTF-8'},
- ).then((HttpRequest xhr) {
- if (xhr.status == 200) {
- // Likely request new navigation and file content.
- } else {
- window.alert('Request failed; status of ${xhr.status}');
- }
- }).catchError((e, st) {
+ doPost(path).catchError((e, st) {
logError('handlePostLinkClick: $e', st);
window.alert('Could not load $path ($e).');
});
+
+ // Don't navigate on link click.
+ event.preventDefault();
}
void highlightAllCode() {
@@ -289,8 +296,8 @@
/// Scroll target with id [offset] into view if it is not currently in view.
///
-/// If [offset] is null, instead scroll the "unit-name" header, at the top of the
-/// page, into view.
+/// If [offset] is null, instead scroll the "unit-name" header, at the top of
+/// the page, into view.
///
/// Also add the "target" class, highlighting the target. Also add the
/// "highlight" class to the entire line on which the target lies.
@@ -380,18 +387,10 @@
for (var detail in response.details) {
var detailItem = detailList.append(document.createElement('li'));
detailItem.append(Text(detail.description));
- if (detail.link != null) {
- int targetLine = detail.link.line;
-
+ var link = detail.link;
+ if (link != null) {
detailItem.append(Text(' ('));
- AnchorElement a = detailItem.append(document.createElement('a'));
- a.append(Text("${detail.link.path}:$targetLine"));
-
- String relLink = detail.link.href;
- String fullPath = _p.normalize(_p.join(parentDirectory, relLink));
-
- a.setAttribute('href', fullPath);
- a.classes.add('nav-link');
+ detailItem.append(_aElementForLink(link, parentDirectory));
detailItem.append(Text(')'));
}
}
@@ -403,7 +402,25 @@
Element a = editParagraph.append(document.createElement('a'));
a.append(Text(edit.description));
a.setAttribute('href', edit.href);
- a.classes.add('post-link');
+ a.classes = ['post-link', 'before-apply'];
+ }
+ }
+
+ for (var trace in response.traces) {
+ var traceParagraph = editPanel.append(document.createElement('p'));
+ traceParagraph.append(Text(trace.description));
+ var ul = traceParagraph.append(document.createElement('ul'));
+ for (var entry in trace.entries) {
+ var li = ul.append(document.createElement('li'));
+ li.append(Text(entry.function ?? 'unknown'));
+ var link = entry.link;
+ if (link != null) {
+ li.append(Text(' ('));
+ li.append(_aElementForLink(link, parentDirectory));
+ li.append(Text(')'));
+ }
+ li.append(Text(': '));
+ li.append(Text(entry.description));
}
}
}
@@ -550,6 +567,19 @@
}
}
+AnchorElement _aElementForLink(TargetLink link, String parentDirectory) {
+ int targetLine = link.line;
+ AnchorElement a = document.createElement('a');
+ a.append(Text('${link.path}:$targetLine'));
+
+ String relLink = link.href;
+ String fullPath = _p.normalize(_p.join(parentDirectory, relLink));
+
+ a.setAttribute('href', fullPath);
+ a.classes.add('nav-link');
+ return a;
+}
+
class _PermissiveNodeValidator implements NodeValidator {
static _PermissiveNodeValidator instance = _PermissiveNodeValidator();
diff --git a/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart b/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
index e395a67..b0002cb 100644
--- a/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
+++ b/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
@@ -14,6 +14,12 @@
Future<void> handleGetRequest(HttpRequest request);
}
+/// Instances of the class [AbstractPostHandler] handle POST requests.
+abstract class AbstractPostHandler {
+ /// Handle a POST request received by the HTTP server.
+ Future<void> handlePostRequest(HttpRequest request);
+}
+
/// Instances of the class [HttpPreviewServer] implement a simple HTTP server
/// that serves up dartfix preview pages.
class HttpPreviewServer {
@@ -23,6 +29,9 @@
/// An object that can handle GET requests.
AbstractGetHandler getHandler;
+ /// An object that can handle POST requests.
+ AbstractPostHandler postHandler;
+
/// Future that is completed with the HTTP server once it is running.
Future<HttpServer> _serverFuture;
@@ -68,12 +77,20 @@
await getHandler.handleGetRequest(request);
}
+ /// Handle a POST request received by the HTTP server.
+ Future<void> _handlePostRequest(HttpRequest request) async {
+ postHandler ??= PreviewSite(migrationState);
+ await postHandler.handlePostRequest(request);
+ }
+
/// Attach a listener to a newly created HTTP server.
void _handleServer(HttpServer httpServer) {
httpServer.listen((HttpRequest request) async {
List<String> updateValues = request.headers[HttpHeaders.upgradeHeader];
if (request.method == 'GET') {
await _handleGetRequest(request);
+ } else if (request.method == 'POST') {
+ await _handlePostRequest(request);
} else if (updateValues != null && updateValues.contains('websocket')) {
// We do not support serving analysis server communications over
// WebSocket connections.
diff --git a/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart b/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart
index c69ed62..e0996d3 100644
--- a/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart
+++ b/pkg/analysis_server/lib/src/edit/preview/index_file_page.dart
@@ -19,8 +19,10 @@
@override
Future<void> generatePage(Map<String, String> params) async {
- InstrumentationRenderer renderer =
- InstrumentationRenderer(site.migrationInfo, site.pathMapper);
+ InstrumentationRenderer renderer = InstrumentationRenderer(
+ site.migrationInfo,
+ site.pathMapper,
+ site.migrationState.hasBeenApplied);
buf.write(renderer.render());
}
}
diff --git a/pkg/analysis_server/lib/src/edit/preview/preview_site.dart b/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
index 999ee2c..302c5ee 100644
--- a/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
+++ b/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
@@ -17,11 +17,13 @@
import 'package:analysis_server/src/edit/preview/navigation_tree_page.dart';
import 'package:analysis_server/src/edit/preview/not_found_page.dart';
import 'package:analysis_server/src/edit/preview/region_page.dart';
+import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/status/pages.dart';
import 'package:analyzer/file_system/file_system.dart';
/// The site used to serve pages for the preview tool.
-class PreviewSite extends Site implements AbstractGetHandler {
+class PreviewSite extends Site
+ implements AbstractGetHandler, AbstractPostHandler {
/// The path of the CSS page used to style the semantic highlighting within a
/// Dart file.
static const highlightCssPath = '/highlight.css';
@@ -31,6 +33,8 @@
static const navigationTreePath = '/_preview/navigationTree.json';
+ static const applyMigrationPath = '/apply-migration';
+
/// The state of the migration being previewed.
final MigrationState migrationState;
@@ -92,14 +96,6 @@
@override
Future<void> handleGetRequest(HttpRequest request) async {
Uri uri = request.uri;
- if (uri.queryParameters.containsKey('replacement')) {
- // TODO(devoncarew): We should only perform work on a 'POST' request.
- performEdit(uri);
-
- respondOk(request);
- return;
- }
-
String path = uri.path;
try {
if (path == highlightCssPath) {
@@ -121,6 +117,7 @@
// https://github.com/dart-lang/sdk/issues/39204
return await respond(request, IndexFilePage(this));
}
+
UnitInfo unitInfo = unitInfoMap[path];
if (unitInfo != null) {
if (uri.queryParameters.containsKey('inline')) {
@@ -146,18 +143,46 @@
return await respond(
request, createUnknownPage(path), HttpStatus.notFound);
} catch (exception, stackTrace) {
- try {
- await respond(
- request,
- createExceptionPageWithPath(path, '$exception', stackTrace),
- HttpStatus.internalServerError);
- } catch (exception, stackTrace) {
- HttpResponse response = request.response;
- response.statusCode = HttpStatus.internalServerError;
- response.headers.contentType = ContentType.text;
- response.write('$exception\n\n$stackTrace');
- response.close();
+ _respondInternalError(request, path, exception, stackTrace);
+ }
+ }
+
+ @override
+ Future<void> handlePostRequest(HttpRequest request) async {
+ Uri uri = request.uri;
+ String path = uri.path;
+ try {
+ if (path == applyMigrationPath) {
+ performApply();
+
+ respondOk(request);
+ return;
+ } else if (uri.queryParameters.containsKey('replacement')) {
+ performEdit(uri);
+
+ respondOk(request);
+ return;
}
+ } catch (exception, stackTrace) {
+ _respondInternalError(request, path, exception, stackTrace);
+ }
+ }
+
+ /// Perform the migration.
+ void performApply() {
+ if (migrationState.hasBeenApplied) {
+ throw StateError('Cannot reapply migration.');
+ }
+
+ final edits = migrationState.listener.sourceChange.edits;
+
+ // Eagerly mark the migration applied. If this throws, we cannot go back.
+ migrationState.markApplied();
+ for (final fileEdit in edits) {
+ final file = pathMapper.provider.getFile(fileEdit.file);
+ String code = file.exists ? file.readAsStringSync() : '';
+ code = SourceEdit.applySequence(code, fileEdit.edits);
+ file.writeAsStringSync(code);
}
}
@@ -207,4 +232,20 @@
response.write(await page.generate(request.uri.queryParameters));
response.close();
}
+
+ Future<void> _respondInternalError(HttpRequest request, String path,
+ dynamic exception, StackTrace stackTrace) async {
+ try {
+ await respond(
+ request,
+ createExceptionPageWithPath(path, '$exception', stackTrace),
+ HttpStatus.internalServerError);
+ } catch (exception, stackTrace) {
+ HttpResponse response = request.response;
+ response.statusCode = HttpStatus.internalServerError;
+ response.headers.contentType = ContentType.text;
+ response.write('$exception\n\n$stackTrace');
+ response.close();
+ }
+ }
}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
index 056bd4f..3230f33 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
@@ -39,6 +39,9 @@
RenameRefactoring.getElementToRename(node, element);
final refactoring = RenameRefactoring(
server.refactoringWorkspace, unit.result, refactorDetails.element);
+ if (refactoring == null) {
+ return success(null);
+ }
// Check the rename is valid here.
final initStatus = await refactoring.checkInitialConditions();
@@ -100,6 +103,9 @@
RenameRefactoring.getElementToRename(node, element);
final refactoring = RenameRefactoring(
server.refactoringWorkspace, unit.result, refactorDetails.element);
+ if (refactoring == null) {
+ return success(null);
+ }
// TODO(dantup): Consider using window/showMessageRequest to prompt
// the user to see if they'd like to proceed with a rename if there
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index 30992a8..c8a69de 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -27,6 +27,7 @@
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart'
show CompletionPerformance;
@@ -118,9 +119,11 @@
ResourceProvider baseResourceProvider,
AnalysisServerOptions options,
this.sdkManager,
+ CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
this.instrumentationService, {
DiagnosticServer diagnosticServer,
- }) : super(options, diagnosticServer, baseResourceProvider) {
+ }) : super(options, diagnosticServer, crashReportingAttachmentsBuilder,
+ baseResourceProvider) {
messageHandler = UninitializedStateMessageHandler(this);
// TODO(dantup): This code is almost identical to AnalysisServer, consider
// moving it the base class that already holds many of these fields.
@@ -629,15 +632,7 @@
}
}
});
- analysisDriver.exceptions.listen((nd.ExceptionResult result) {
- String message = 'Analysis failed: ${result.path}';
- if (result.contextKey != null) {
- message += ' context: ${result.contextKey}';
- }
- // TODO(39284): should this exception be silent?
- AnalysisEngine.instance.instrumentationService.logException(
- SilentException.wrapInMessage(message, result.exception));
- });
+ analysisDriver.exceptions.listen(analysisServer.logExceptionResult);
analysisServer.driverMap[folder] = analysisDriver;
return analysisDriver;
}
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
index 55f2bcf..3c49e8a 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
@@ -8,6 +8,7 @@
import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/socket_server.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
@@ -75,8 +76,13 @@
'File read mode was set to the unknown mode: $analysisServerOptions.fileReadMode');
}
- analysisServer = LspAnalysisServer(serverChannel, resourceProvider,
- analysisServerOptions, sdkManager, instrumentationService,
+ analysisServer = LspAnalysisServer(
+ serverChannel,
+ resourceProvider,
+ analysisServerOptions,
+ sdkManager,
+ CrashReportingAttachmentsBuilder.empty,
+ instrumentationService,
diagnosticServer: diagnosticServer);
}
}
diff --git a/pkg/analysis_server/lib/src/server/crash_reporting.dart b/pkg/analysis_server/lib/src/server/crash_reporting.dart
index f30a41b..247f064 100644
--- a/pkg/analysis_server/lib/src/server/crash_reporting.dart
+++ b/pkg/analysis_server/lib/src/server/crash_reporting.dart
@@ -5,6 +5,7 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/instrumentation/noop_service.dart';
import 'package:analyzer/instrumentation/plugin_data.dart';
+import 'package:analyzer/instrumentation/service.dart';
import 'package:telemetry/crash_reporting.dart';
class CrashReportingInstrumentation extends NoopInstrumentationService {
@@ -13,19 +14,30 @@
CrashReportingInstrumentation(this.reporter);
@override
- void logException(dynamic exception, [StackTrace stackTrace]) {
+ void logException(dynamic exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]) {
+ var crashReportAttachments = (attachments ?? []).map((e) {
+ return CrashReportAttachment.string(
+ field: 'attachment_${e.id}',
+ value: e.stringValue,
+ );
+ }).toList();
+
if (exception is CaughtException) {
// Get the root CaughtException, which matters most for debugging.
CaughtException root = exception.rootCaughtException;
reporter
- .sendReport(root.exception, root.stackTrace, comment: root.message)
+ .sendReport(root.exception, root.stackTrace,
+ attachments: crashReportAttachments, comment: root.message)
.catchError((error) {
// We silently ignore errors sending crash reports (network issues, ...).
});
} else {
reporter
- .sendReport(exception, stackTrace ?? StackTrace.current)
+ .sendReport(exception, stackTrace ?? StackTrace.current,
+ attachments: crashReportAttachments)
.catchError((error) {
// We silently ignore errors sending crash reports (network issues, ...).
});
diff --git a/pkg/analysis_server/lib/src/server/crash_reporting_attachments.dart b/pkg/analysis_server/lib/src/server/crash_reporting_attachments.dart
new file mode 100644
index 0000000..281c6d2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/server/crash_reporting_attachments.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analyzer/instrumentation/service.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart' show ExceptionResult;
+
+/// A builder for attachments to include into crash reports.
+class CrashReportingAttachmentsBuilder {
+ static final CrashReportingAttachmentsBuilder empty =
+ CrashReportingAttachmentsBuilder();
+
+ /// Return attachments with information about the analysis exception.
+ List<InstrumentationServiceAttachment> forExceptionResult(
+ ExceptionResult result,
+ ) {
+ return const [];
+ }
+}
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 5464aeb..6cb9049 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -12,6 +12,7 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/lsp/lsp_socket_server.dart';
import 'package:analysis_server/src/server/crash_reporting.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
import 'package:analysis_server/src/server/dev_server.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
@@ -287,14 +288,17 @@
/// should be used to compute relevance scores.
static const String USE_NEW_RELEVANCE = 'use-new-relevance';
- /// The instrumentation service that is to be used by the analysis server.
- InstrumentationService instrumentationService;
+ /// The builder for attachments that should be included into crash reports.
+ CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder =
+ CrashReportingAttachmentsBuilder.empty;
- /// *
/// An optional manager to handle file systems which may not always be
/// available.
DetachableFileSystemManager detachableFileSystemManager;
+ /// The instrumentation service that is to be used by the analysis server.
+ InstrumentationService instrumentationService;
+
HttpAnalysisServer httpServer;
Driver();
@@ -455,6 +459,7 @@
analysisServerOptions,
parser,
dartSdkManager,
+ crashReportingAttachmentsBuilder,
instrumentationService,
RequestStatisticsHelper(),
analytics,
@@ -468,6 +473,7 @@
AnalysisServerOptions analysisServerOptions,
CommandLineParser parser,
DartSdkManager dartSdkManager,
+ CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
InstrumentationService instrumentationService,
RequestStatisticsHelper requestStatistics,
telemetry.Analytics analytics,
@@ -500,6 +506,7 @@
final socketServer = SocketServer(
analysisServerOptions,
dartSdkManager,
+ crashReportingAttachmentsBuilder,
instrumentationService,
requestStatistics,
diagnosticServer,
diff --git a/pkg/analysis_server/lib/src/server/error_notifier.dart b/pkg/analysis_server/lib/src/server/error_notifier.dart
index 0547cd4..79faa40 100644
--- a/pkg/analysis_server/lib/src/server/error_notifier.dart
+++ b/pkg/analysis_server/lib/src/server/error_notifier.dart
@@ -8,7 +8,9 @@
AbstractAnalysisServer server;
@override
- void logException(dynamic exception, [StackTrace stackTrace]) {
+ void logException(dynamic exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]) {
if (exception is SilentException) {
// Silent exceptions should not be reported to the user.
return;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 3c9b3e8..e4570fe 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -361,6 +361,7 @@
}
if (entity is Token && (entity as Token).type == TokenType.CLOSE_PAREN) {
_addSuggestion(Keyword.COVARIANT);
+ _addSuggestion(Keyword.DYNAMIC);
if (request.featureSet.isEnabled(Feature.non_nullable)) {
_addSuggestion(Keyword.REQUIRED);
}
@@ -368,6 +369,7 @@
Token beginToken = (entity as FormalParameter).beginToken;
if (beginToken != null && request.target.offset == beginToken.end) {
_addSuggestion(Keyword.COVARIANT);
+ _addSuggestion(Keyword.DYNAMIC);
if (request.featureSet.isEnabled(Feature.non_nullable)) {
_addSuggestion(Keyword.REQUIRED);
}
@@ -513,12 +515,15 @@
@override
void visitMethodInvocation(MethodInvocation node) {
- if (entity == node.methodName || entity == node.argumentList) {
- // no keywords in '.' expressions or type argument lists
+ if (entity == node.methodName) {
+ // no keywords in '.' expressions
+ } else if (entity == node.argumentList) {
// Note that we're checking the argumentList rather than the typeArgumentList
// as you'd expect. For some reason, when the cursor is in a type argument
// list (f<^>()), the entity is the invocation's argumentList...
// See similar logic in `imported_reference_contributor`.
+
+ _addSuggestion(Keyword.DYNAMIC);
} else {
super.visitMethodInvocation(node);
}
@@ -659,6 +664,11 @@
}
@override
+ void visitTypeArgumentList(TypeArgumentList node) {
+ _addSuggestion(Keyword.DYNAMIC);
+ }
+
+ @override
void visitVariableDeclaration(VariableDeclaration node) {
if (entity == node.initializer) {
_addExpressionKeywords(node);
@@ -820,6 +830,7 @@
Keyword.ASSERT,
Keyword.CONST,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index a5ea15e..a39e416 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -53,6 +53,8 @@
TypeProvider get typeProvider => _context.typeProvider;
+ CompilationUnit get unit => _context.unit;
+
CorrectionUtils get utils => _context.utils;
Future<void> compute(DartChangeBuilder builder);
@@ -94,6 +96,7 @@
final int selectionLength;
final int selectionEnd;
+ final CompilationUnit unit;
final CorrectionUtils utils;
final String file;
@@ -118,6 +121,7 @@
sessionHelper = AnalysisSessionHelper(resolvedResult.session),
typeProvider = resolvedResult.typeProvider,
selectionEnd = (selectionOffset ?? 0) + (selectionLength ?? 0),
+ unit = resolvedResult.unit,
utils = CorrectionUtils(resolvedResult);
AstNode get node => _node;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
new file mode 100644
index 0000000..a1534d0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
@@ -0,0 +1,146 @@
+// Copyright (c) 2020, 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.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class InlineTypedef extends CorrectionProducer {
+ String name;
+
+ @override
+ List<Object> get fixArguments => [name];
+
+ @override
+ FixKind get fixKind => DartFixKind.INLINE_TYPEDEF;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ //
+ // Extract the information needed to build the edit.
+ //
+ TypeAnnotation returnType;
+ TypeParameterList typeParameters;
+ List<FormalParameter> parameters;
+ if (node is FunctionTypeAlias) {
+ var typedef = node as FunctionTypeAlias;
+ returnType = typedef.returnType;
+ name = typedef.name.name;
+ typeParameters = typedef.typeParameters;
+ parameters = typedef.parameters.parameters;
+ } else if (node is GenericTypeAlias) {
+ var typedef = node as GenericTypeAlias;
+ if (typedef.typeParameters != null) {
+ return;
+ }
+ var functionType = typedef.functionType;
+ returnType = functionType.returnType;
+ name = typedef.name.name;
+ typeParameters = functionType.typeParameters;
+ parameters = functionType.parameters.parameters;
+ } else {
+ return;
+ }
+ // TODO(brianwilkerson) Handle parts.
+ var finder = _ReferenceFinder(name);
+ resolvedResult.unit.accept(finder);
+ if (finder.count != 1) {
+ return;
+ }
+ //
+ // Build the edit.
+ //
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(utils.getLinesRange(range.node(node)));
+ builder.addReplacement(range.node(finder.reference),
+ (DartEditBuilder builder) {
+ if (returnType != null) {
+ builder.write(utils.getNodeText(returnType));
+ builder.write(' ');
+ }
+ builder.write('Function');
+ if (typeParameters != null) {
+ builder.write(utils.getNodeText(typeParameters));
+ }
+ String groupEnd;
+ builder.write('(');
+ for (int i = 0; i < parameters.length; i++) {
+ var parameter = parameters[i];
+ if (i > 0) {
+ // This intentionally drops any trailing comma in order to improve
+ // formatting.
+ builder.write(', ');
+ }
+ if (parameter is DefaultFormalParameter) {
+ if (groupEnd == null) {
+ if (parameter.isNamed) {
+ groupEnd = '}';
+ builder.write('{');
+ } else {
+ groupEnd = ']';
+ builder.write('[');
+ }
+ }
+ parameter = (parameter as DefaultFormalParameter).parameter;
+ }
+ if (parameter is FunctionTypedFormalParameter) {
+ builder.write(utils.getNodeText(parameter));
+ } else if (parameter is SimpleFormalParameter) {
+ if (parameter.metadata.isNotEmpty) {
+ builder
+ .write(utils.getRangeText(range.nodes(parameter.metadata)));
+ }
+ if (parameter.requiredKeyword != null) {
+ builder.write('required ');
+ }
+ if (parameter.covariantKeyword != null) {
+ builder.write('covariant ');
+ }
+ var keyword = parameter.keyword;
+ if (keyword != null && keyword.type != Keyword.VAR) {
+ builder.write(keyword.lexeme);
+ }
+ if (parameter.type == null) {
+ builder.write('dynamic');
+ } else {
+ builder.write(utils.getNodeText(parameter.type));
+ }
+ if (parameter.isNamed) {
+ builder.write(' ');
+ builder.write(parameter.identifier.name);
+ }
+ }
+ }
+ if (groupEnd != null) {
+ builder.write(groupEnd);
+ }
+ builder.write(')');
+ });
+ });
+ }
+}
+
+class _ReferenceFinder extends RecursiveAstVisitor {
+ final String typeName;
+
+ TypeName reference;
+
+ int count = 0;
+
+ _ReferenceFinder(this.typeName);
+
+ @override
+ void visitTypeName(TypeName node) {
+ if (node.name.name == typeName) {
+ reference ??= node;
+ count++;
+ }
+ super.visitTypeName(node);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
new file mode 100644
index 0000000..febb28b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused.dart
@@ -0,0 +1,154 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnusedElement extends _RemoveUnused {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNUSED_ELEMENT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ final sourceRanges = <SourceRange>[];
+ final referencedNode = node.parent;
+ if (referencedNode is ClassDeclaration ||
+ referencedNode is EnumDeclaration ||
+ referencedNode is FunctionDeclaration ||
+ referencedNode is FunctionTypeAlias ||
+ referencedNode is MethodDeclaration ||
+ referencedNode is VariableDeclaration) {
+ final element = referencedNode is Declaration
+ ? referencedNode.declaredElement
+ : (referencedNode as NamedCompilationUnitMember).declaredElement;
+ final references = _findAllReferences(unit, element);
+ // todo (pq): consider filtering for references that are limited to within the class.
+ if (references.length == 1) {
+ var sourceRange;
+ if (referencedNode is VariableDeclaration) {
+ VariableDeclarationList parent = referencedNode.parent;
+ if (parent.variables.length == 1) {
+ sourceRange = utils.getLinesRange(range.node(parent.parent));
+ } else {
+ sourceRange = range.nodeInList(parent.variables, referencedNode);
+ }
+ } else {
+ sourceRange = utils.getLinesRange(range.node(referencedNode));
+ }
+ sourceRanges.add(sourceRange);
+ }
+ }
+
+ await builder.addFileEdit(file, (builder) {
+ for (var sourceRange in sourceRanges) {
+ builder.addDeletion(sourceRange);
+ }
+ });
+ }
+}
+
+class RemoveUnusedField extends _RemoveUnused {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNUSED_FIELD;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ final declaration = node.parent;
+ if (declaration is! VariableDeclaration) {
+ return;
+ }
+ final element = (declaration as VariableDeclaration).declaredElement;
+ if (element is! FieldElement) {
+ return;
+ }
+
+ final sourceRanges = <SourceRange>[];
+ final references = _findAllReferences(unit, element);
+ for (var reference in references) {
+ // todo (pq): consider scoping this to parent or parent.parent.
+ final referenceNode = reference.thisOrAncestorMatching((node) =>
+ node is VariableDeclaration ||
+ node is ExpressionStatement ||
+ node is ConstructorFieldInitializer ||
+ node is FieldFormalParameter);
+ if (referenceNode == null) {
+ return;
+ }
+ var sourceRange;
+ if (referenceNode is VariableDeclaration) {
+ VariableDeclarationList parent = referenceNode.parent;
+ if (parent.variables.length == 1) {
+ sourceRange = utils.getLinesRange(range.node(parent.parent));
+ } else {
+ sourceRange = range.nodeInList(parent.variables, referenceNode);
+ }
+ } else if (referenceNode is ConstructorFieldInitializer) {
+ ConstructorDeclaration cons =
+ referenceNode.parent as ConstructorDeclaration;
+ // A() : _f = 0;
+ if (cons.initializers.length == 1) {
+ sourceRange = range.endEnd(cons.parameters, referenceNode);
+ } else {
+ sourceRange = range.nodeInList(cons.initializers, referenceNode);
+ }
+ } else if (referenceNode is FieldFormalParameter) {
+ FormalParameterList params =
+ referenceNode.parent as FormalParameterList;
+ if (params.parameters.length == 1) {
+ sourceRange =
+ range.endStart(params.leftParenthesis, params.rightParenthesis);
+ } else {
+ sourceRange = range.nodeInList(params.parameters, referenceNode);
+ }
+ } else {
+ sourceRange = utils.getLinesRange(range.node(referenceNode));
+ }
+ sourceRanges.add(sourceRange);
+ }
+
+ await builder.addFileEdit(file, (builder) {
+ for (var sourceRange in sourceRanges) {
+ builder.addDeletion(sourceRange);
+ }
+ });
+ }
+}
+
+class _ElementReferenceCollector extends RecursiveAstVisitor<void> {
+ final Element element;
+ final List<SimpleIdentifier> references = [];
+
+ _ElementReferenceCollector(this.element);
+
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ final staticElement = node.staticElement;
+ if (staticElement == element) {
+ references.add(node);
+ } else if (staticElement is PropertyAccessorElement) {
+ if (staticElement.variable == element) {
+ references.add(node);
+ }
+ } else if (staticElement is FieldFormalParameterElement) {
+ if (staticElement.field == element) {
+ references.add(node);
+ }
+ }
+ }
+}
+
+abstract class _RemoveUnused extends CorrectionProducer {
+ List<SimpleIdentifier> _findAllReferences(AstNode root, Element element) {
+ var collector = _ElementReferenceCollector(element);
+ root.accept(collector);
+ return collector.references;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
new file mode 100644
index 0000000..bba9db5
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class WrapInFuture extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.WRAP_IN_FUTURE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ //
+ // Extract the information needed to build the edit.
+ //
+ Expression expression;
+ if (node is ReturnStatement) {
+ expression = (node as ReturnStatement).expression;
+ } else if (node is Expression) {
+ expression = node;
+ } else {
+ return;
+ }
+ var value = utils.getNodeText(expression);
+ //
+ // Build the edit.
+ //
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ range.node(expression), 'Future.value($value)');
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 36ba2de..2b76ff0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -268,6 +268,8 @@
FixKind('IMPORT_LIBRARY_SHOW', 55, "Update library '{0}' import");
static const INLINE_INVOCATION =
FixKind('INLINE_INVOCATION', 30, "Inline invocation of '{0}'");
+ static const INLINE_TYPEDEF =
+ FixKind('INLINE_TYPEDEF', 30, "Inline the definition of '{0}'");
static const INSERT_SEMICOLON = FixKind('INSERT_SEMICOLON', 50, "Insert ';'");
static const MAKE_CLASS_ABSTRACT =
FixKind('MAKE_CLASS_ABSTRACT', 50, "Make class '{0}' abstract");
@@ -409,6 +411,8 @@
"Use != null instead of 'is! Null' everywhere in file");
static const USE_RETHROW =
FixKind('USE_RETHROW', 50, 'Replace throw with rethrow');
+ static const WRAP_IN_FUTURE =
+ FixKind('WRAP_IN_FUTURE', 50, "Wrap in 'Future.value'");
}
/// An enumeration of quick fix kinds for the errors found in an Android
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 757c8c5..df63966 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -18,9 +18,12 @@
import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_set_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_where_type.dart';
+import 'package:analysis_server/src/services/correction/dart/inline_typedef.dart';
import 'package:analysis_server/src/services/correction/dart/remove_dead_if_null.dart';
import 'package:analysis_server/src/services/correction/dart/remove_if_null_operator.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unused.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_eight_digit_hex.dart';
+import 'package:analysis_server/src/services/correction/dart/wrap_in_future.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
import 'package:analysis_server/src/services/correction/levenshtein.dart';
@@ -33,7 +36,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/precedence.dart';
import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -372,12 +374,6 @@
if (errorCode == HintCode.UNUSED_CATCH_STACK) {
await _addFix_removeUnusedCatchStack();
}
- if (errorCode == HintCode.UNUSED_ELEMENT) {
- await _addFix_removeUnusedElement();
- }
- if (errorCode == HintCode.UNUSED_FIELD) {
- await _addFix_removeUnusedField();
- }
if (errorCode == HintCode.UNUSED_IMPORT) {
await _addFix_removeUnusedImport();
}
@@ -629,6 +625,9 @@
if (name == LintNames.avoid_return_types_on_setters) {
await _addFix_removeTypeAnnotation();
}
+ if (name == LintNames.avoid_returning_null_for_future) {
+ await _addFix_addAsync();
+ }
if (name == LintNames.avoid_types_on_closure_parameters) {
await _addFix_replaceWithIdentifier();
}
@@ -3747,110 +3746,6 @@
}
}
- Future<void> _addFix_removeUnusedElement() async {
- final sourceRanges = <SourceRange>[];
- final referencedNode = node.parent;
- if (referencedNode is ClassDeclaration ||
- referencedNode is EnumDeclaration ||
- referencedNode is FunctionDeclaration ||
- referencedNode is FunctionTypeAlias ||
- referencedNode is MethodDeclaration ||
- referencedNode is VariableDeclaration) {
- final element = referencedNode is Declaration
- ? referencedNode.declaredElement
- : (referencedNode as NamedCompilationUnitMember).declaredElement;
- final references = _findAllReferences(unit, element);
- // todo (pq): consider filtering for references that are limited to within the class.
- if (references.length == 1) {
- var sourceRange;
- if (referencedNode is VariableDeclaration) {
- VariableDeclarationList parent = referencedNode.parent;
- if (parent.variables.length == 1) {
- sourceRange = utils.getLinesRange(range.node(parent.parent));
- } else {
- sourceRange = range.nodeInList(parent.variables, referencedNode);
- }
- } else {
- sourceRange = utils.getLinesRange(range.node(referencedNode));
- }
- sourceRanges.add(sourceRange);
- }
- }
-
- if (sourceRanges.isNotEmpty) {
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- for (var sourceRange in sourceRanges) {
- builder.addDeletion(sourceRange);
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_ELEMENT);
- }
- }
-
- Future<void> _addFix_removeUnusedField() async {
- final declaration = node.parent;
- if (declaration is! VariableDeclaration) {
- return;
- }
- final element = (declaration as VariableDeclaration).declaredElement;
- if (element is! FieldElement) {
- return;
- }
-
- final sourceRanges = <SourceRange>[];
- final references = _findAllReferences(unit, element);
- for (var reference in references) {
- // todo (pq): consider scoping this to parent or parent.parent.
- final referenceNode = reference.thisOrAncestorMatching((node) =>
- node is VariableDeclaration ||
- node is ExpressionStatement ||
- node is ConstructorFieldInitializer ||
- node is FieldFormalParameter);
- if (referenceNode == null) {
- return;
- }
- var sourceRange;
- if (referenceNode is VariableDeclaration) {
- VariableDeclarationList parent = referenceNode.parent;
- if (parent.variables.length == 1) {
- sourceRange = utils.getLinesRange(range.node(parent.parent));
- } else {
- sourceRange = range.nodeInList(parent.variables, referenceNode);
- }
- } else if (referenceNode is ConstructorFieldInitializer) {
- ConstructorDeclaration cons =
- referenceNode.parent as ConstructorDeclaration;
- // A() : _f = 0;
- if (cons.initializers.length == 1) {
- sourceRange = range.endEnd(cons.parameters, referenceNode);
- } else {
- sourceRange = range.nodeInList(cons.initializers, referenceNode);
- }
- } else if (referenceNode is FieldFormalParameter) {
- FormalParameterList params =
- referenceNode.parent as FormalParameterList;
- if (params.parameters.length == 1) {
- sourceRange =
- range.endStart(params.leftParenthesis, params.rightParenthesis);
- } else {
- sourceRange = range.nodeInList(params.parameters, referenceNode);
- }
- } else {
- sourceRange = utils.getLinesRange(range.node(referenceNode));
- }
- sourceRanges.add(sourceRange);
- }
-
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- for (var sourceRange in sourceRanges) {
- builder.addDeletion(sourceRange);
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_FIELD);
- }
-
Future<void> _addFix_removeUnusedImport() async {
// prepare ImportDirective
ImportDirective importDirective =
@@ -4709,11 +4604,19 @@
}
var errorCode = error.errorCode;
- if (errorCode == StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION) {
+ if (errorCode == HintCode.UNUSED_ELEMENT) {
+ await compute(RemoveUnusedElement());
+ } else if (errorCode == HintCode.UNUSED_FIELD) {
+ await compute(RemoveUnusedField());
+ } else if (errorCode == StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION) {
await compute(RemoveDeadIfNull());
} else if (errorCode is LintCode) {
String name = errorCode.name;
- if (name == LintNames.prefer_collection_literals) {
+ if (name == LintNames.avoid_private_typedef_functions) {
+ await compute(InlineTypedef());
+ } else if (name == LintNames.avoid_returning_null_for_future) {
+ await compute(WrapInFuture());
+ } else if (name == LintNames.prefer_collection_literals) {
await compute(ConvertToListLiteral());
await compute(ConvertToMapLiteral());
await compute(ConvertToSetLiteral());
@@ -4835,12 +4738,6 @@
_addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD, args: [name]);
}
- List<SimpleIdentifier> _findAllReferences(AstNode root, Element element) {
- var collector = _ElementReferenceCollector(element);
- root.accept(collector);
- return collector.references;
- }
-
/// Return the class, enum or mixin declaration for the given [element].
Future<ClassOrMixinDeclaration> _getClassDeclaration(
ClassElement element) async {
@@ -5226,32 +5123,6 @@
}
}
-class _ElementReferenceCollector extends RecursiveAstVisitor<void> {
- final Element element;
- final List<SimpleIdentifier> references = [];
-
- _ElementReferenceCollector(this.element);
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- final staticElement = node.staticElement;
- if (staticElement == element) {
- references.add(node);
- }
- // Implicit Setter.
- else if (staticElement is PropertyAccessorElement) {
- if (staticElement.variable == element) {
- references.add(node);
- }
- // Field Formals.
- } else if (staticElement is FieldFormalParameterElement) {
- if (staticElement.field == element) {
- references.add(node);
- }
- }
- }
-}
-
/// [ExecutableElement], its parameters, and operations on them.
class _ExecutableParameters {
final AnalysisSessionHelper sessionHelper;
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index 4c8b4f3..6546d87 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -19,6 +19,10 @@
static const String avoid_relative_lib_imports = 'avoid_relative_lib_imports';
static const String avoid_return_types_on_setters =
'avoid_return_types_on_setters';
+ static const String avoid_private_typedef_functions =
+ 'avoid_private_typedef_functions';
+ static const String avoid_returning_null_for_future =
+ 'avoid_returning_null_for_future';
static const String avoid_types_on_closure_parameters =
'avoid_types_on_closure_parameters';
static const String await_only_futures = 'await_only_futures';
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 8db1252..a742bcf 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -7,6 +7,7 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/analysis_server_abstract.dart';
import 'package:analysis_server/src/channel/channel.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/utilities/request_statistics.dart';
@@ -31,6 +32,7 @@
/// The function used to create a new SDK using the default SDK.
final DartSdkManager sdkManager;
+ final CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder;
final InstrumentationService instrumentationService;
final RequestStatisticsHelper requestStatistics;
@override
@@ -45,6 +47,7 @@
SocketServer(
this.analysisServerOptions,
this.sdkManager,
+ this.crashReportingAttachmentsBuilder,
this.instrumentationService,
this.requestStatistics,
this.diagnosticServer,
@@ -81,6 +84,7 @@
resourceProvider,
analysisServerOptions,
sdkManager,
+ crashReportingAttachmentsBuilder,
instrumentationService,
requestStatistics: requestStatistics,
diagnosticServer: diagnosticServer,
diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart
index 18e8eac..859f8e7 100644
--- a/pkg/analysis_server/lib/starter.dart
+++ b/pkg/analysis_server/lib/starter.dart
@@ -2,6 +2,7 @@
// 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.
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
import 'package:analysis_server/src/server/driver.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -14,6 +15,11 @@
/// Initialize a newly created starter to start up an analysis server.
factory ServerStarter() = Driver;
+ /// Set the new builder for attachments that should be included into crash
+ /// reports.
+ set crashReportingAttachmentsBuilder(
+ CrashReportingAttachmentsBuilder builder);
+
/// An optional manager to handle file systems which may not always be
/// available.
set detachableFileSystemManager(DetachableFileSystemManager manager);
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index 194e306..631c7d6 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -17,13 +17,12 @@
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(NewAnalysisOptionsFileNotificationTest);
- defineReflectiveTests(OldAnalysisOptionsFileNotificationTest);
+ defineReflectiveTests(AnalysisOptionsFileNotificationTest);
});
}
-abstract class AnalysisOptionsFileNotificationTest
- extends AbstractAnalysisTest {
+@reflectiveTest
+class AnalysisOptionsFileNotificationTest extends AbstractAnalysisTest {
Map<String, List<AnalysisError>> filesErrors = {};
final testSource = '''
@@ -37,7 +36,7 @@
List<AnalysisError> get optionsFileErrors => filesErrors[optionsFilePath];
- String get optionsFilePath;
+ String get optionsFilePath => '$projectPath/analysis_options.yaml';
List<AnalysisError> get testFileErrors => filesErrors[testFile];
@@ -260,17 +259,3 @@
expect(rules, unorderedEquals(lints));
}
}
-
-@reflectiveTest
-class NewAnalysisOptionsFileNotificationTest
- extends AnalysisOptionsFileNotificationTest {
- @override
- String get optionsFilePath => '$projectPath/analysis_options.yaml';
-}
-
-@reflectiveTest
-class OldAnalysisOptionsFileNotificationTest
- extends AnalysisOptionsFileNotificationTest {
- @override
- String get optionsFilePath => '$projectPath/.analysis_options';
-}
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index 425090c..5461be7 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -200,7 +200,7 @@
Future<void> test_lintError() async {
var camelCaseTypesLintName = 'camel_case_types';
- newFile(join(projectPath, '.analysis_options'), content: '''
+ newFile(join(projectPath, 'analysis_options.yaml'), content: '''
linter:
rules:
- $camelCaseTypesLintName
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 9a5107f..07447dd 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -10,6 +10,7 @@
hide AnalysisOptions;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -125,6 +126,7 @@
resourceProvider,
options,
DartSdkManager(resourceProvider.convertPath('/sdk'), true),
+ CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
}
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index e966735..9588a2f 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -9,6 +9,7 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_server.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -86,6 +87,7 @@
resourceProvider,
AnalysisServerOptions(),
DartSdkManager(convertPath('/sdk'), false),
+ CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
}
diff --git a/pkg/analysis_server/test/client/impl/abstract_client.dart b/pkg/analysis_server/test/client/impl/abstract_client.dart
index 3c5286b..b8f60a0 100644
--- a/pkg/analysis_server/test/client/impl/abstract_client.dart
+++ b/pkg/analysis_server/test/client/impl/abstract_client.dart
@@ -10,6 +10,7 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -104,8 +105,13 @@
AnalysisServer createAnalysisServer(String sdkPath) {
sdk = MockSdk(resourceProvider: resourceProvider);
var options = AnalysisServerOptions();
- return AnalysisServer(serverChannel, resourceProvider, options,
- DartSdkManager(sdkPath, true), InstrumentationService.NULL_SERVICE);
+ return AnalysisServer(
+ serverChannel,
+ resourceProvider,
+ options,
+ DartSdkManager(sdkPath, true),
+ CrashReportingAttachmentsBuilder.empty,
+ InstrumentationService.NULL_SERVICE);
}
/// Create a project at [projectPath].
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index b405e4c..80a76a6 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -43,8 +43,7 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AbstractContextManagerTest);
- defineReflectiveTests(ContextManagerWithNewOptionsTest);
- defineReflectiveTests(ContextManagerWithOldOptionsTest);
+ defineReflectiveTests(ContextManagerWithOptionsTest);
});
}
@@ -1657,7 +1656,6 @@
'**/*.${AnalysisEngine.SUFFIX_DART}',
'**/*.${AnalysisEngine.SUFFIX_HTML}',
'**/*.${AnalysisEngine.SUFFIX_HTM}',
- '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
'**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}'
];
return patterns
@@ -1712,27 +1710,9 @@
}
@reflectiveTest
-class ContextManagerWithNewOptionsTest extends ContextManagerWithOptionsTest {
- @override
+class ContextManagerWithOptionsTest extends ContextManagerTest {
String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
- @override
- @failingTest
- Future<void> test_analysis_options_parse_failure() async {
- // We have lost the ability to detect errors of this form.
- return super.test_analysis_options_parse_failure();
- }
-}
-
-@reflectiveTest
-class ContextManagerWithOldOptionsTest extends ContextManagerWithOptionsTest {
- @override
- String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_FILE;
-}
-
-abstract class ContextManagerWithOptionsTest extends ContextManagerTest {
- String get optionsFileName;
-
void deleteOptionsFile() {
deleteFile('$projPath/$optionsFileName');
}
@@ -1879,6 +1859,7 @@
expect(lints[0].name, 'camel_case_types');
}
+ @failingTest
Future<void> test_analysis_options_parse_failure() async {
// Create files.
String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
@@ -2423,7 +2404,7 @@
driverMap[path] = currentDriver;
currentDriver.exceptions.listen((ExceptionResult result) {
AnalysisEngine.instance.instrumentationService.logException(
- CaughtException.withMessage('Analysis failed: ${result.path}',
+ CaughtException.withMessage('Analysis failed: ${result.filePath}',
result.exception.exception, result.exception.stackTrace));
});
return currentDriver;
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 4765a7e..e2a2668 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -9,6 +9,7 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/sdk.dart';
@@ -364,6 +365,7 @@
resourceProvider,
AnalysisServerOptions(),
DartSdkManager(convertPath('/sdk'), false),
+ CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
handler = AnalysisDomainHandler(server);
// listen for notifications
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index eeb47aa..c439ee55 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -7,6 +7,7 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_execution.dart';
import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -32,6 +33,7 @@
provider,
AnalysisServerOptions(),
DartSdkManager('', false),
+ CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
handler = ExecutionDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index 012fb35..9447a19 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -7,6 +7,7 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_server.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -29,6 +30,7 @@
resourceProvider,
AnalysisServerOptions(),
DartSdkManager('', false),
+ CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
handler = ServerDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
index 1a31955..0032db9 100644
--- a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
@@ -23,7 +23,7 @@
standardAnalysisSetup();
}
- Future<void> test_option_warning_newOptionFile() async {
+ Future<void> test_option_warning_optionFile() async {
String options = sourcePath(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
writeFile(options, '''
linter:
@@ -47,31 +47,4 @@
expect(error.location.startLine, 3);
expect(error.location.startColumn, 7);
}
-
- Future<void> test_option_warning_oldOptionFile() async {
- String options = sourcePath(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
- writeFile(options, '''
-linter:
- rules:
- - camel_case_types
-''');
-
- optionsAnalysisSetup();
-
- await analysisFinished;
-
- expect(currentAnalysisErrors[options], isList);
- List<AnalysisError> errors = currentAnalysisErrors[options];
- expect(errors, hasLength(1));
- AnalysisError error = errors[0];
- expect(error.location.file, options);
- expect(error.severity, AnalysisErrorSeverity.INFO);
- expect(error.type, AnalysisErrorType.HINT);
- expect(error.location.offset, 0);
- expect(error.location.length, 1);
- expect(error.location.startLine, 1);
- expect(error.location.startColumn, 1);
- expect(error.message,
- 'The name of the analysis options file .analysis_options is deprecated; consider renaming it to analysis_options.yaml.');
- }
}
diff --git a/pkg/analysis_server/test/integration/analysis/lint_test.dart b/pkg/analysis_server/test/integration/analysis/lint_test.dart
index faa2467..05051f5 100644
--- a/pkg/analysis_server/test/integration/analysis/lint_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/lint_test.dart
@@ -31,7 +31,7 @@
expect(errors, hasLength(0));
}
- Future<void> test_simple_lint_newOptionsFile() async {
+ Future<void> test_simple_lint_optionsFile() async {
writeFile(sourcePath(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE), '''
linter:
rules:
@@ -55,29 +55,4 @@
expect(error.severity, AnalysisErrorSeverity.INFO);
expect(error.type, AnalysisErrorType.LINT);
}
-
- Future<void> test_simple_lint_oldOptionsFile() async {
- writeFile(sourcePath(AnalysisEngine.ANALYSIS_OPTIONS_FILE), '''
-linter:
- rules:
- - camel_case_types
-''');
-
- String source = sourcePath('test.dart');
- writeFile(source, '''
-class a { // lint: not CamelCase
-}''');
-
- standardAnalysisSetup();
-
- await analysisFinished;
-
- expect(currentAnalysisErrors[source], isList);
- List<AnalysisError> errors = currentAnalysisErrors[source];
- expect(errors, hasLength(1));
- AnalysisError error = errors[0];
- expect(error.location.file, source);
- expect(error.severity, AnalysisErrorSeverity.INFO);
- expect(error.type, AnalysisErrorType.LINT);
- }
}
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 7472d7e..15bf575 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -12,6 +12,7 @@
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/sdk.dart';
@@ -79,6 +80,7 @@
resourceProvider,
AnalysisServerOptions(),
DartSdkManager(convertPath('/sdk'), false),
+ CrashReportingAttachmentsBuilder.empty,
InstrumentationService.NULL_SERVICE);
projectFolderPath = convertPath('/home/test');
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index ebe6350..cf1b4b7 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -71,7 +71,7 @@
}
List<Keyword> get constructorParameter {
- List<Keyword> keywords = [Keyword.COVARIANT, Keyword.THIS];
+ List<Keyword> keywords = [Keyword.COVARIANT, Keyword.DYNAMIC, Keyword.THIS];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.REQUIRED);
}
@@ -156,7 +156,7 @@
}
List<Keyword> get methodParameter {
- List<Keyword> keywords = [Keyword.COVARIANT];
+ List<Keyword> keywords = [Keyword.COVARIANT, Keyword.DYNAMIC];
if (isEnabled(ExperimentalFeatures.non_nullable)) {
keywords.add(Keyword.REQUIRED);
}
@@ -168,6 +168,7 @@
Keyword.ASSERT,
Keyword.CONST,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
@@ -194,6 +195,7 @@
Keyword.CONST,
Keyword.CONTINUE,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
@@ -220,6 +222,7 @@
Keyword.CONST,
Keyword.CONTINUE,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
@@ -243,6 +246,7 @@
Keyword.BREAK,
Keyword.CONST,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
@@ -268,6 +272,7 @@
Keyword.BREAK,
Keyword.CONST,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
@@ -293,6 +298,7 @@
Keyword.CONST,
Keyword.DEFAULT,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
@@ -320,6 +326,7 @@
Keyword.CONST,
Keyword.DEFAULT,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
@@ -342,6 +349,7 @@
Keyword.ASSERT,
Keyword.CONST,
Keyword.DO,
+ Keyword.DYNAMIC,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
@@ -994,13 +1002,13 @@
}
Future<void> test_constructor_param_noPrefix() async {
- addTestSource('class A { A(^) {});}');
+ addTestSource('class A { A(^) {}}');
await computeSuggestions();
assertSuggestKeywords(constructorParameter);
}
Future<void> test_constructor_param_prefix() async {
- addTestSource('class A { A(t^) {});}');
+ addTestSource('class A { A(t^) {}}');
await computeSuggestions();
assertSuggestKeywords(constructorParameter);
}
@@ -1910,7 +1918,7 @@
}
Future<void> test_method_param_noPrefix() async {
- addTestSource('class A { foo(^) {});}');
+ addTestSource('class A { foo(^) {}}');
await computeSuggestions();
expect(suggestions, isNotEmpty);
assertSuggestKeywords(methodParameter);
@@ -2142,6 +2150,12 @@
assertSuggestKeywords(statementStartInSwitchOutsideClass);
}
+ Future<void> test_variable_decl_type_args() async {
+ addTestSource('void m() {List<^> list;}');
+ await computeSuggestions();
+ assertSuggestKeywords([Keyword.DYNAMIC]);
+ }
+
Future<void> test_while_break_continue() async {
addTestSource('main() {while (true) {^}}');
await computeSuggestions();
@@ -2259,7 +2273,7 @@
''');
await computeSuggestions();
- assertSuggestKeywords([]);
+ assertSuggestKeywords([Keyword.DYNAMIC]);
}
}
diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart
index 85d8c45..a2ede5d 100644
--- a/pkg/analysis_server/test/socket_server_test.dart
+++ b/pkg/analysis_server/test/socket_server_test.dart
@@ -8,6 +8,7 @@
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/error_notifier.dart';
import 'package:analysis_server/src/socket_server.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
@@ -102,8 +103,14 @@
static SocketServer _createSocketServer(MockServerChannel channel) {
final errorNotifier = ErrorNotifier();
- final server = SocketServer(AnalysisServerOptions(),
- DartSdkManager('', false), errorNotifier, null, null, null);
+ final server = SocketServer(
+ AnalysisServerOptions(),
+ DartSdkManager('', false),
+ CrashReportingAttachmentsBuilder.empty,
+ errorNotifier,
+ null,
+ null,
+ null);
server.createAnalysisServer(channel);
errorNotifier.server = server.analysisServer;
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
index a5c5a92..c1c9e05 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
@@ -6,6 +6,7 @@
import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:meta/meta.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -237,6 +238,16 @@
}
}
+ void assertTraceEntry(
+ UnitInfo unit, TraceEntryInfo entryInfo, String function, int offset) {
+ var lineInfo = LineInfo.fromContent(unit.content);
+ var expectedLocation = lineInfo.getLocation(offset);
+ expect(entryInfo.target.filePath, unit.path);
+ expect(entryInfo.target.line, expectedLocation.lineNumber);
+ expect(entryInfo.target.offset, expectedLocation.columnNumber);
+ expect(entryInfo.function, function);
+ }
+
Future<void> test_asExpression() async {
UnitInfo unit = await buildInfoForSingleTestFile('''
void f([num a]) {
@@ -1335,7 +1346,6 @@
details: ['A nullable value is assigned']);
}
- @FailingTest(issue: 'https://dartbug.com/40773')
Future<void> test_parameter_fromOverriddenField_explicit() async {
UnitInfo unit = await buildInfoForSingleTestFile('''
class A {
@@ -1357,8 +1367,7 @@
List<RegionInfo> regions = unit.fixRegions;
expect(regions, hasLength(2));
assertRegion(region: regions[0], offset: 15, details: [
- // TODO(mfairhurst): Implement something similar to this error message
- 'No initializer is given',
+ 'This field is not initialized',
"An explicit 'null' is assigned in the function 'f'",
]);
assertRegion(region: regions[1], offset: 61, details: [
@@ -1710,6 +1719,73 @@
details: ['This variable is initialized to a nullable value']);
}
+ Future<void> test_trace_deadCode() async {
+ UnitInfo unit = await buildInfoForSingleTestFile('''
+void f(int/*!*/ i) {
+ if (i == null) return;
+}
+''', migratedContent: '''
+void f(int/*!*/ i) {
+ /* if (i == null) return; */
+}
+''');
+ var region = unit.regions
+ .where(
+ (regionInfo) => regionInfo.offset == unit.content.indexOf('/* if'))
+ .single;
+ // The reason data associated with dead code removal is a non-nullable node,
+ // and we don't currently generate a trace for non-nullable nodes.
+ expect(region.traces, isEmpty);
+ }
+
+ Future<void> test_trace_nullableType() async {
+ UnitInfo unit = await buildInfoForSingleTestFile('''
+void f(int i) {} // f
+void g(int i) { // g
+ f(i);
+}
+void h() {
+ g(null);
+}
+''', migratedContent: '''
+void f(int? i) {} // f
+void g(int? i) { // g
+ f(i);
+}
+void h() {
+ g(null);
+}
+''');
+ var region = unit.regions
+ .where((regionInfo) =>
+ regionInfo.offset == unit.content.indexOf('? i) {} // f'))
+ .single;
+ expect(region.traces, hasLength(1));
+ var entries = region.traces.single.entries;
+ expect(entries, hasLength(3));
+ // Entry 0 is the edge from g's argument to f's argument, due to g's call to
+ // f.
+ assertTraceEntry(unit, entries[0], 'g', unit.content.indexOf('i);'));
+ // Entry 1 is the edge from null to g's argument, due to h's call to g.
+ assertTraceEntry(unit, entries[1], 'h', unit.content.indexOf('null'));
+ // Entry 2 is the edge from always to null.
+ assertTraceEntry(unit, entries[2], 'h', unit.content.indexOf('null'));
+ }
+
+ Future<void> test_trace_nullCheck() async {
+ UnitInfo unit = await buildInfoForSingleTestFile(
+ 'int f(int/*?*/ i) => i + 1;',
+ migratedContent: 'int f(int?/*?*/ i) => i! + 1;');
+ var region = unit.regions
+ .where((regionInfo) => regionInfo.offset == unit.content.indexOf('! +'))
+ .single;
+ expect(region.traces, hasLength(1));
+ var entries = region.traces.single.entries;
+ expect(entries, hasLength(1));
+ // Entry 0 is the edge from always to the type of i.
+ assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int?'));
+ }
+
Future<void> test_uninitializedField() async {
UnitInfo unit = await buildInfoForSingleTestFile('''
class C {
@@ -1747,7 +1823,6 @@
assertDetail(detail: region.details[2], offset: 70, length: 3);
}
- @FailingTest(issue: 'https://dartbug.com/40773')
Future<void> test_uninitializedMember() async {
UnitInfo unit = await buildInfoForSingleTestFile('''
class C {
@@ -1761,10 +1836,11 @@
List<RegionInfo> regions = unit.fixRegions;
expect(regions, hasLength(1));
expect(regions[0].details, isNotEmpty);
- // disabled so that it won't interfere with @FailingTest annotation.
- //assertRegion(region: regions[0], offset: 15, length: 1, details: [
- // 'This field is not initialized and is therefore made nullable'
- //]);
+ assertRegion(
+ region: regions[0],
+ offset: 15,
+ length: 1,
+ details: ['This field is not initialized']);
}
Future<void> test_uninitializedVariable_notLate_uninitializedUse() async {
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
index dbc0e4a..15d9cc8 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
@@ -19,13 +19,14 @@
@reflectiveTest
class InstrumentationRendererTest extends NnbdMigrationTestBase {
/// Render the instrumentation view for [files].
- Future<String> renderViewForTestFiles(Map<String, String> files) async {
+ Future<String> renderViewForTestFiles(Map<String, String> files,
+ {bool applied = false}) async {
var packageRoot = convertPath('/project');
await buildInfoForTestFiles(files, includedRoot: packageRoot);
var migrationInfo =
MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
- var instrumentationRenderer =
- InstrumentationRenderer(migrationInfo, PathMapper(resourceProvider));
+ var instrumentationRenderer = InstrumentationRenderer(
+ migrationInfo, PathMapper(resourceProvider), applied);
return instrumentationRenderer.render();
}
@@ -35,4 +36,18 @@
var expectedPath = convertPath('/project');
expect(renderedView, contains('<p class="root">$expectedPath</p>'));
}
+
+ Future<void> test_notAppliedStyle() async {
+ var renderedView = await renderViewForTestFiles(
+ {convertPath('/project/lib/a.dart'): 'int a = null;'},
+ applied: false);
+ expect(renderedView, contains('<body class="proposed">'));
+ }
+
+ Future<void> test_appliedStyle() async {
+ var renderedView = await renderViewForTestFiles(
+ {convertPath('/project/lib/a.dart'): 'int a = null;'},
+ applied: true);
+ expect(renderedView, contains('<body class="applied">'));
+ }
}
diff --git a/pkg/analysis_server/test/src/edit/preview/preview_site_test.dart b/pkg/analysis_server/test/src/edit/preview/preview_site_test.dart
new file mode 100644
index 0000000..f21fd48
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/preview/preview_site_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
+import 'package:analysis_server/src/edit/preview/preview_site.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PreviewSiteTest);
+ });
+}
+
+@reflectiveTest
+class PreviewSiteTest with ResourceProviderMixin {
+ PreviewSite site;
+ DartFixListener dartfixListener;
+ MigrationState state;
+
+ void setUp() {
+ dartfixListener = DartFixListener(null);
+ resourceProvider = MemoryResourceProvider();
+ final migrationInfo = MigrationInfo({}, {}, null, null);
+ state = MigrationState(null, null, dartfixListener, null, null);
+ state.pathMapper = PathMapper(resourceProvider);
+ state.migrationInfo = migrationInfo;
+ site = PreviewSite(state);
+ }
+
+ void test_applyChangesEmpty() {
+ final file = getFile('/test.dart');
+ file.writeAsStringSync('void main() {}');
+ site.performApply();
+ expect(file.readAsStringSync(), 'void main() {}');
+ expect(state.hasBeenApplied, true);
+ }
+
+ void test_applyChangesTwiceThrows() {
+ site.performApply();
+ expect(site.performApply, throwsA(isA<StateError>()));
+ }
+
+ void test_applyMultipleChanges() {
+ final path = convertPath('/test.dart');
+ final file = getFile(path);
+ file.writeAsStringSync('void main() {}');
+ dartfixListener.addSourceChange(
+ 'test change',
+ Location(path, 10, 0, 1, 10),
+ SourceChange('test change', edits: [
+ SourceFileEdit(path, 0, edits: [
+ SourceEdit(10, 0, 'List args'),
+ SourceEdit(13, 0, '\n print(args);\n')
+ ])
+ ]));
+ site.performApply();
+ expect(file.readAsStringSync(), '''
+void main(List args) {
+ print(args);
+}''');
+ expect(state.hasBeenApplied, true);
+ }
+
+ void test_applySingleChange() {
+ final path = convertPath('/test.dart');
+ final file = getFile(path);
+ file.writeAsStringSync('void main() {}');
+ dartfixListener.addSourceChange(
+ 'test change',
+ Location(path, 10, 0, 1, 10),
+ SourceChange('test change', edits: [
+ SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')])
+ ]));
+ site.performApply();
+ expect(file.readAsStringSync(), 'void main(List args) {}');
+ expect(state.hasBeenApplied, true);
+ }
+}
diff --git a/pkg/analysis_server/test/src/edit/preview/test_all.dart b/pkg/analysis_server/test/src/edit/preview/test_all.dart
new file mode 100644
index 0000000..e357e6d
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/preview/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, 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.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'preview_site_test.dart' as preview_site;
+
+void main() {
+ defineReflectiveSuite(() {
+ preview_site.main();
+ }, name: 'preview');
+}
diff --git a/pkg/analysis_server/test/src/edit/test_all.dart b/pkg/analysis_server/test/src/edit/test_all.dart
index b36abbb..f63fe71 100644
--- a/pkg/analysis_server/test/src/edit/test_all.dart
+++ b/pkg/analysis_server/test/src/edit/test_all.dart
@@ -6,10 +6,12 @@
import 'fix/test_all.dart' as fix;
import 'nnbd_migration/test_all.dart' as nnbd_migration;
+import 'preview/test_all.dart' as preview;
void main() {
defineReflectiveSuite(() {
fix.main();
nnbd_migration.main();
+ preview.main();
}, name: 'edit');
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
index 2dcde2c..0c2a51a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -13,6 +14,7 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AddAsyncTest);
+ defineReflectiveTests(AvoidReturningNullForFutureTest);
});
}
@@ -183,3 +185,25 @@
''');
}
}
+
+@reflectiveTest
+class AvoidReturningNullForFutureTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_ASYNC;
+
+ @override
+ String get lintCode => LintNames.avoid_returning_null_for_future;
+
+ Future<void> test_asyncFor() async {
+ await resolveTestUnit('''
+Future<String> f() {
+ return null;
+}
+''');
+ await assertHasFix('''
+Future<String> f() async {
+ return null;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index f633431..6631e92 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -27,13 +27,17 @@
/// The offset of the lint marker in the code being analyzed.
int lintOffset = -1;
+ /// Return a list of the experiments that are to be enabled for tests in this
+ /// class, or `null` if there are no experiments that should be enabled.
+ List<String> get experiments => null;
+
/// Return the lint code being tested.
String get lintCode;
@override
void setUp() {
super.setUp();
- createAnalysisOptionsFile(lints: [lintCode]);
+ createAnalysisOptionsFile(experiments: experiments, lints: [lintCode]);
}
/// Find the error that is to be fixed by computing the errors in the file,
diff --git a/pkg/analysis_server/test/src/services/correction/fix/inline_typedef_test.dart b/pkg/analysis_server/test/src/services/correction/fix/inline_typedef_test.dart
new file mode 100644
index 0000000..92b2217
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/inline_typedef_test.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InlineTypedefTest);
+ defineReflectiveTests(InlineTypedefWithNNBDTest);
+ });
+}
+
+@reflectiveTest
+class InlineTypedefTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.INLINE_TYPEDEF;
+
+ @override
+ String get lintCode => LintNames.avoid_private_typedef_functions;
+
+ Future<void> test_generic_parameter_optionalNamed() async {
+ await resolveTestUnit('''
+typedef _F = Function({int i});
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function({int i}) f) {}
+''');
+ }
+
+ Future<void> test_generic_parameter_optionalPositional_withName() async {
+ await resolveTestUnit('''
+typedef _F = Function([int i]);
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function([int]) f) {}
+''');
+ }
+
+ Future<void> test_generic_parameter_optionalPositional_withoutName() async {
+ await resolveTestUnit('''
+typedef _F = Function([int]);
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function([int]) f) {}
+''');
+ }
+
+ Future<void> test_generic_parameter_requiredPositional_withName() async {
+ await resolveTestUnit('''
+typedef _F = Function(int i);
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function(int) f) {}
+''');
+ }
+
+ Future<void> test_generic_parameter_requiredPositional_withoutName() async {
+ await resolveTestUnit('''
+typedef _F = Function(int);
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function(int) f) {}
+''');
+ }
+
+ Future<void> test_generic_returnType() async {
+ await resolveTestUnit('''
+typedef _F = void Function();
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(void Function() f) {}
+''');
+ }
+
+ Future<void> test_generic_typeParameters() async {
+ await resolveTestUnit('''
+typedef _F = Function<T>(T);
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function<T>(T) f) {}
+''');
+ }
+
+ Future<void> test_nonGeneric_parameter_requiredPositional_typed() async {
+ await resolveTestUnit('''
+typedef _F(int i);
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function(int) f) {}
+''');
+ }
+
+ Future<void> test_nonGeneric_parameter_requiredPositional_untyped() async {
+ await resolveTestUnit('''
+typedef _F(i);
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function(dynamic) f) {}
+''');
+ }
+
+ Future<void> test_nonGeneric_returnType() async {
+ await resolveTestUnit('''
+typedef void _F();
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(void Function() f) {}
+''');
+ }
+
+ Future<void> test_nonGeneric_typeParameters() async {
+ await resolveTestUnit('''
+typedef _F<T>(T t);
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function<T>(T) f) {}
+''');
+ }
+}
+
+@reflectiveTest
+class InlineTypedefWithNNBDTest extends InlineTypedefTest {
+ @override
+ List<String> get experiments => ['non-nullable'];
+
+ Future<void> test_generic_parameter_requiredNamed() async {
+ await resolveTestUnit('''
+typedef _F = Function({required int i});
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function({required int i}) f) {}
+''');
+ }
+
+ Future<void> test_nonGeneric_parameter_requiredNamed() async {
+ await resolveTestUnit('''
+typedef _F({required int i});
+void g(_F f) {}
+''');
+ await assertHasFix('''
+void g(Function({required int i}) f) {}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 76b12e7..3b49d2a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -82,6 +82,7 @@
import 'import_library_sdk_test.dart' as import_library_sdk;
import 'import_library_show_test.dart' as import_library_show;
import 'inline_invocation_test.dart' as inline_invocation;
+import 'inline_typedef_test.dart' as inline_typedef;
import 'insert_semicolon_test.dart' as insert_semicolon;
import 'make_class_abstract_test.dart' as make_class_abstract;
import 'make_field_not_final_test.dart' as make_field_not_final;
@@ -150,6 +151,7 @@
import 'use_is_not_empty_test.dart' as use_is_not_empty;
import 'use_not_eq_null_test.dart' as use_not_eq_null;
import 'use_rethrow_test.dart' as use_rethrow;
+import 'wrap_in_future_test.dart' as wrap_in_future;
void main() {
defineReflectiveSuite(() {
@@ -220,6 +222,7 @@
import_library_sdk.main();
import_library_show.main();
inline_invocation.main();
+ inline_typedef.main();
insert_semicolon.main();
make_class_abstract.main();
make_field_not_final.main();
@@ -283,5 +286,6 @@
use_is_not_empty.main();
use_not_eq_null.main();
use_rethrow.main();
+ wrap_in_future.main();
}, name: 'fix');
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/wrap_in_future_test.dart b/pkg/analysis_server/test/src/services/correction/fix/wrap_in_future_test.dart
new file mode 100644
index 0000000..3736686
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/wrap_in_future_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(WrapInFutureTest);
+ });
+}
+
+@reflectiveTest
+class WrapInFutureTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.WRAP_IN_FUTURE;
+
+ @override
+ String get lintCode => LintNames.avoid_returning_null_for_future;
+
+ Future<void> test_asyncFor() async {
+ await resolveTestUnit('''
+Future<String> f() {
+ return null;
+}
+''');
+ await assertHasFix('''
+Future<String> f() {
+ return Future.value(null);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/tool/completion_metrics/metrics_util_test.dart b/pkg/analysis_server/test/tool/completion_metrics/metrics_util_test.dart
index a410f22..807acf4 100644
--- a/pkg/analysis_server/test/tool/completion_metrics/metrics_util_test.dart
+++ b/pkg/analysis_server/test/tool/completion_metrics/metrics_util_test.dart
@@ -46,7 +46,7 @@
var mrrc = MeanReciprocalRankComputer();
expect(mrrc.rankCount, equals(0));
expect(mrrc.ranks, isEmpty);
- expect(mrrc.mrr, equals(0));
+ expect(mrrc.getMRR(), equals(0));
});
test('clear', () {
@@ -69,7 +69,7 @@
mrrc.addRank(3);
expect(mrrc.rankCount, equals(5));
expect(mrrc.ranks, equals([3, 3, 3, 3, 3]));
- expect(mrrc.mrr, doubleEquals(1 / 3));
+ expect(mrrc.getMRR(), doubleEquals(1 / 3));
});
test('mmr- example', () {
@@ -79,7 +79,17 @@
mrrc.addRank(1);
expect(mrrc.rankCount, equals(3));
expect(mrrc.ranks, equals([3, 2, 1]));
- expect(mrrc.mrr, doubleEquals(11 / 18));
+ expect(mrrc.getMRR(), doubleEquals(11 / 18));
+ });
+
+ test('mmr- max rank', () {
+ var mrrc = MeanReciprocalRankComputer();
+ mrrc.addRank(3);
+ mrrc.addRank(2);
+ mrrc.addRank(1);
+ expect(mrrc.rankCount, equals(3));
+ expect(mrrc.ranks, equals([3, 2, 1]));
+ expect(mrrc.getMRR(2), doubleEquals(1 / 2));
});
});
diff --git a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
index d22512d..0c80948 100644
--- a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
@@ -20,32 +20,101 @@
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/services/available_declarations.dart';
+import 'package:args/args.dart';
+import 'package:path/path.dart' as path;
import 'metrics_util.dart';
import 'visitors.dart';
Future<void> main(List<String> args) async {
- if (args.isEmpty) {
- print('Usage: a single absolute file path to analyze.');
- io.exit(1);
+ ArgParser parser = createArgParser();
+ ArgResults result = parser.parse(args);
+
+ if (validArguments(parser, result)) {
+ var code = await CompletionCoverageMetrics(result.rest[0])
+ .compute(corpus: result['corpus'], verbose: result['verbose']);
+ io.exit(code);
}
- await CompletionCoverageMetrics(args[0]).compute();
- io.exit(0);
+ return io.exit(1);
+}
+
+/// Create a parser that can be used to parse the command-line arguments.
+ArgParser createArgParser() {
+ ArgParser parser = ArgParser();
+ parser.addFlag(
+ 'corpus',
+ help: 'Analyze each of the subdirectories separately',
+ negatable: false,
+ );
+ parser.addOption(
+ 'help',
+ abbr: 'h',
+ help: 'Print this help message.',
+ );
+ parser.addFlag(
+ 'verbose',
+ abbr: 'v',
+ help: 'Print additional information about the analysis',
+ negatable: false,
+ );
+ return parser;
+}
+
+/// Return `true` if the command-line arguments (represented by the [result] and
+/// parsed by the [parser]) are valid.
+bool validArguments(ArgParser parser, ArgResults result) {
+ if (result.wasParsed('help')) {
+ printUsage(parser);
+ return false;
+ } else if (result.rest.length != 1) {
+ printUsage(parser, error: 'No package path specified.');
+ return false;
+ }
+ var rootPath = result.rest[0];
+ if (!io.Directory(rootPath).existsSync()) {
+ printUsage(parser, error: 'The directory "$rootPath" does not exist.');
+ return false;
+ }
+ return true;
+}
+
+/// Print usage information for this tool.
+void printUsage(ArgParser parser, {String error}) {
+ if (error != null) {
+ print(error);
+ print('');
+ }
+ print('usage: dart completion_metrics.dart [options] packagePath');
+ print('');
+ print('Compute code completion health metrics.');
+ print('');
+ print(parser.usage);
}
/// This is the main metrics computer class for code completions. After the
/// object is constructed, [computeCompletionMetrics] is executed to do analysis
/// and print a summary of the metrics gathered from the completion tests.
-abstract class AbstractCompletionMetricsComputer {
- // TODO(brianwilkerson) Consider merging this class into the single concrete
- // subclass.
+class CompletionCoverageMetrics {
final String _rootPath;
String _currentFilePath;
+ bool _verbose;
+
ResolvedUnitResult _resolvedUnitResult;
- AbstractCompletionMetricsComputer(this._rootPath);
+ /// The int to be returned from the [compute] call.
+ int resultCode;
+
+ int includedCount = 0;
+ int notIncludedCount = 0;
+
+ var completionMissedTokenCounter = Counter('missing completion counter');
+ var completionKindCounter = Counter('completion kind counter');
+ var completionElementKindCounter = Counter('completion element kind counter');
+ var mRRComputer = MeanReciprocalRankComputer();
+
+ CompletionCoverageMetrics(this._rootPath);
/// The path to the current file.
String get currentFilePath => _currentFilePath;
@@ -53,90 +122,141 @@
/// If the concrete class has this getter return true, then when
/// [forEachExpectedCompletion] is called, the [List] of
/// [CompletionSuggestion]s will be passed.
- bool get doComputeCompletionsFromAnalysisServer;
-
- /// The current [ResolvedUnitResult].
- ResolvedUnitResult get resolvedUnitResult => _resolvedUnitResult;
+ bool get doComputeCompletionsFromAnalysisServer => true;
/// The analysis root path that this CompletionMetrics class will be computed.
String get rootPath => _rootPath;
- void compute() async {
- print('Analyzing root: \"$_rootPath\"');
+ Future<int> compute({bool corpus = false, bool verbose = false}) async {
+ _verbose = verbose;
+ resultCode = 0;
- if (!io.Directory(_rootPath).existsSync()) {
- print('\tError: No such directory exists on this machine.\n');
- return;
- }
+ var roots = _computeRootPaths(_rootPath, corpus);
+ for (var root in roots) {
+ print('Analyzing root: \"$root\"');
+ final collection = AnalysisContextCollection(
+ includedPaths: [root],
+ resourceProvider: PhysicalResourceProvider.INSTANCE,
+ );
- final collection = AnalysisContextCollection(
- includedPaths: [_rootPath],
- resourceProvider: PhysicalResourceProvider.INSTANCE,
- );
-
- for (var context in collection.contexts) {
- // Set the DeclarationsTracker, only call doWork to build up the available
- // suggestions if doComputeCompletionsFromAnalysisServer is true.
- var declarationsTracker = DeclarationsTracker(
- MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
- declarationsTracker.addContext(context);
- if (doComputeCompletionsFromAnalysisServer) {
+ for (var context in collection.contexts) {
+ // Set the DeclarationsTracker, only call doWork to build up the available
+ // suggestions if doComputeCompletionsFromAnalysisServer is true.
+ var declarationsTracker = DeclarationsTracker(
+ MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
+ declarationsTracker.addContext(context);
while (declarationsTracker.hasWork) {
declarationsTracker.doWork();
}
- }
- // Loop through each file, resolve the file and call
- // forEachExpectedCompletion
- for (var filePath in context.contextRoot.analyzedFiles()) {
- if (AnalysisEngine.isDartFileName(filePath)) {
- _currentFilePath = filePath;
- try {
- _resolvedUnitResult =
- await context.currentSession.getResolvedUnit(filePath);
+ // Loop through each file, resolve the file and call
+ // forEachExpectedCompletion
+ for (var filePath in context.contextRoot.analyzedFiles()) {
+ if (AnalysisEngine.isDartFileName(filePath)) {
+ _currentFilePath = filePath;
+ try {
+ _resolvedUnitResult =
+ await context.currentSession.getResolvedUnit(filePath);
- var error = getFirstErrorOrNull(resolvedUnitResult);
- if (error != null) {
- print('File $filePath skipped due to errors such as:');
- print(' ${error.toString()}');
- print('');
- continue;
+ var analysisError = getFirstErrorOrNull(_resolvedUnitResult);
+ if (analysisError != null) {
+ print('File $filePath skipped due to errors such as:');
+ print(' ${analysisError.toString()}');
+ print('');
+ resultCode = 1;
+ continue;
+ }
+
+ // Use the ExpectedCompletionsVisitor to compute the set of expected
+ // completions for this CompilationUnit.
+ final visitor = ExpectedCompletionsVisitor();
+ _resolvedUnitResult.unit.accept(visitor);
+
+ for (var expectedCompletion in visitor.expectedCompletions) {
+ forEachExpectedCompletion(
+ expectedCompletion,
+ doComputeCompletionsFromAnalysisServer
+ ? await _computeCompletionSuggestions(
+ _resolvedUnitResult,
+ expectedCompletion.offset,
+ declarationsTracker)
+ : null);
+ }
+ } catch (e) {
+ print('Exception caught analyzing: $filePath');
+ print(e.toString());
+ resultCode = 1;
}
-
- // Use the ExpectedCompletionsVisitor to compute the set of expected
- // completions for this CompilationUnit.
- final visitor = ExpectedCompletionsVisitor();
- resolvedUnitResult.unit.accept(visitor);
-
- for (var expectedCompletion in visitor.expectedCompletions) {
- // Call forEachExpectedCompletion, passing in the computed
- // suggestions only if doComputeCompletionsFromAnalysisServer is
- // true:
- forEachExpectedCompletion(
- expectedCompletion,
- doComputeCompletionsFromAnalysisServer
- ? await _computeCompletionSuggestions(resolvedUnitResult,
- expectedCompletion.offset, declarationsTracker)
- : null);
- }
- } catch (e) {
- print('Exception caught analyzing: $filePath');
- print(e.toString());
}
}
}
}
printAndClearComputers();
+ return resultCode;
}
- /// Overridden by each subclass, this method gathers some set of data from
- /// each [ExpectedCompletion], and each [CompletionSuggestion] list (if
- /// [doComputeCompletionsFromAnalysisServer] is set to true.)
void forEachExpectedCompletion(ExpectedCompletion expectedCompletion,
- List<CompletionSuggestion> suggestions);
+ List<CompletionSuggestion> suggestions) {
+ assert(suggestions != null);
- /// This method is called to print a summary of the data collected.
- void printAndClearComputers();
+ var place = placementInSuggestionList(suggestions, expectedCompletion);
+
+ mRRComputer.addRank(place.rank);
+
+ if (place.denominator != 0) {
+ includedCount++;
+ } else {
+ notIncludedCount++;
+
+ completionMissedTokenCounter.count(expectedCompletion.completion);
+ completionKindCounter.count(expectedCompletion.kind.toString());
+ completionElementKindCounter
+ .count(expectedCompletion.elementKind.toString());
+
+ if (_verbose) {
+ // The format "/file/path/foo.dart:3:4" makes for easier input
+ // with the Files dialog in IntelliJ
+ print(
+ '$currentFilePath:${expectedCompletion.lineNumber}:${expectedCompletion.columnNumber}');
+ print(
+ '\tdid not include the expected completion: \"${expectedCompletion.completion}\", completion kind: ${expectedCompletion.kind.toString()}, element kind: ${expectedCompletion.elementKind.toString()}');
+ print('');
+ }
+ }
+ }
+
+ void printAndClearComputers() {
+ final totalCompletionCount = includedCount + notIncludedCount;
+ final percentIncluded = includedCount / totalCompletionCount;
+ final percentNotIncluded = 1 - percentIncluded;
+
+ print('');
+ completionMissedTokenCounter.printCounterValues();
+ print('');
+
+ completionKindCounter.printCounterValues();
+ print('');
+
+ completionElementKindCounter.printCounterValues();
+ print('');
+
+ mRRComputer.printMean();
+ print('');
+
+ print('Summary for $_rootPath:');
+ print('Total number of completion tests = $totalCompletionCount');
+ print(
+ 'Number of successful completions = $includedCount (${printPercentage(percentIncluded)})');
+ print(
+ 'Number of unsuccessful completions = $notIncludedCount (${printPercentage(percentNotIncluded)})');
+
+ includedCount = 0;
+ notIncludedCount = 0;
+ completionMissedTokenCounter.clear();
+ completionKindCounter.clear();
+ completionElementKindCounter.clear();
+ mRRComputer.clear();
+ }
Future<List<CompletionSuggestion>> _computeCompletionSuggestions(
ResolvedUnitResult resolvedUnitResult, int offset,
@@ -179,6 +299,20 @@
return suggestions;
}
+ List<String> _computeRootPaths(String rootPath, bool corpus) {
+ var roots = <String>[];
+ if (!corpus) {
+ roots.add(rootPath);
+ } else {
+ for (var child in io.Directory(rootPath).listSync()) {
+ if (child is io.Directory) {
+ roots.add(path.join(rootPath, child.path));
+ }
+ }
+ }
+ return roots;
+ }
+
/// Given some [ResolvedUnitResult] return the first error of high severity
/// if such an error exists, null otherwise.
static err.AnalysisError getFirstErrorOrNull(
@@ -203,80 +337,3 @@
return Place.none();
}
}
-
-class CompletionCoverageMetrics extends AbstractCompletionMetricsComputer {
- int includedCount = 0;
- int notIncludedCount = 0;
- var completionMissedTokenCounter = Counter('missing completion counter');
- var completionKindCounter = Counter('completion kind counter');
- var completionElementKindCounter = Counter('completion element kind counter');
- var mRRComputer = MeanReciprocalRankComputer();
-
- CompletionCoverageMetrics(String rootPath) : super(rootPath);
-
- @override
- bool get doComputeCompletionsFromAnalysisServer => true;
-
- @override
- void forEachExpectedCompletion(ExpectedCompletion expectedCompletion,
- List<CompletionSuggestion> suggestions) {
- assert(suggestions != null);
-
- var place = AbstractCompletionMetricsComputer.placementInSuggestionList(
- suggestions, expectedCompletion);
-
- mRRComputer.addRank(place.rank);
-
- if (place.denominator != 0) {
- includedCount++;
- } else {
- notIncludedCount++;
-
- completionMissedTokenCounter.count(expectedCompletion.completion);
- completionKindCounter.count(expectedCompletion.kind.toString());
- completionElementKindCounter
- .count(expectedCompletion.elementKind.toString());
-
- // The format "/file/path/foo.dart:3:4" makes for easier input
- // with the Files dialog in IntelliJ
- print(
- '$currentFilePath:${expectedCompletion.lineNumber}:${expectedCompletion.columnNumber}');
- print(
- '\tdid not include the expected completion: \"${expectedCompletion.completion}\", completion kind: ${expectedCompletion.kind.toString()}, element kind: ${expectedCompletion.elementKind.toString()}');
- print('');
- }
- }
-
- @override
- void printAndClearComputers() {
- final totalCompletionCount = includedCount + notIncludedCount;
- final percentIncluded = includedCount / totalCompletionCount;
- final percentNotIncluded = 1 - percentIncluded;
-
- completionMissedTokenCounter.printCounterValues();
- print('');
-
- completionKindCounter.printCounterValues();
- print('');
-
- completionElementKindCounter.printCounterValues();
- print('');
-
- mRRComputer.printMean();
- print('');
-
- print('Summary for $_rootPath:');
- print('Total number of completion tests = $totalCompletionCount');
- print(
- 'Number of successful completions = $includedCount (${printPercentage(percentIncluded)})');
- print(
- 'Number of unsuccessful completions = $notIncludedCount (${printPercentage(percentNotIncluded)})');
-
- includedCount = 0;
- notIncludedCount = 0;
- completionMissedTokenCounter.clear();
- completionKindCounter.clear();
- completionElementKindCounter.clear();
- mRRComputer.clear();
- }
-}
diff --git a/pkg/analysis_server/tool/completion_metrics/feature_computer.dart b/pkg/analysis_server/tool/completion_metrics/feature_computer.dart
new file mode 100644
index 0000000..bce7cf1
--- /dev/null
+++ b/pkg/analysis_server/tool/completion_metrics/feature_computer.dart
@@ -0,0 +1,440 @@
+// Copyright (c) 2020, 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.
+
+/// Utility methods to compute the value of the features used for code
+/// completion.
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart'
+ show ClassElement, FieldElement;
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+
+// TODO(brianwilkerson) Move this file to `lib` so that it can be used by the
+// completion contributors.
+
+/// An object that computes the values of features.
+class FeatureComputer {
+ /// The type provider used to access types defined by the spec.
+ final TypeProvider typeProvider;
+
+ /// Initialize a newly created feature computer.
+ FeatureComputer(this.typeProvider);
+
+ /// Return the type imposed on the given [node] based on its context, or
+ /// `null` if the context does not impose any type.
+ DartType computeContextType(AstNode node) {
+ // This method is only visible for the metrics computation and might be made
+ // private at some future date.
+ var type = node.parent?.accept(_ContextTypeVisitor(typeProvider, node));
+ if (type == null || type.isDynamic) {
+ return null;
+ }
+ return type;
+ }
+
+ /// Return the inheritance distance between the [subclass] and the
+ /// [superclass]. We define the inheritance distance between two types to be
+ /// zero if the two types are the same and the minimum number of edges that
+ /// must be traversed in the type graph to get from the subtype to the
+ /// supertype if the two types are not the same. Return `-1` if the [subclass]
+ /// is not a subclass of the [superclass].
+ int inheritanceDistance(ClassElement subclass, ClassElement superclass) {
+ // This method is only visible for the metrics computation and might be made
+ // private at some future date.
+ return _inheritanceDistance(subclass, superclass, {});
+ }
+
+ /// Return the value of the inheritance distance feature for a member defined
+ /// in the [superclass] that is being accessed through an expression whose
+ /// static type is the [subclass].
+ double inheritanceDistanceFeature(
+ ClassElement subclass, ClassElement superclass) {
+ var distance = _inheritanceDistance(subclass, superclass, {});
+ if (distance < 0) {
+ return 0;
+ }
+ return 1 / (distance + 1);
+ }
+
+ /// Return the inheritance distance between the [subclass] and the
+ /// [superclass]. The set of [visited] elements is used to guard against
+ /// cycles in the type graph.
+ ///
+ /// This is the implementation of [inheritanceDistance].
+ int _inheritanceDistance(ClassElement subclass, ClassElement superclass,
+ Set<ClassElement> visited) {
+ if (subclass == null) {
+ return -1;
+ } else if (subclass == superclass) {
+ return 0;
+ } else if (!visited.add(subclass)) {
+ return -1;
+ }
+ var minDepth =
+ _inheritanceDistance(subclass.supertype?.element, superclass, visited);
+
+ void visitTypes(List<InterfaceType> types) {
+ for (var type in types) {
+ var depth = _inheritanceDistance(type.element, superclass, visited);
+ if (minDepth < 0 || (depth >= 0 && depth < minDepth)) {
+ minDepth = depth;
+ }
+ }
+ }
+
+ visitTypes(subclass.superclassConstraints);
+ visitTypes(subclass.mixins);
+ visitTypes(subclass.interfaces);
+
+ visited.remove(subclass);
+ if (minDepth < 0) {
+ return minDepth;
+ }
+ return minDepth + 1;
+ }
+}
+
+/// An object used to compute metrics for a single file or directory.
+class _ContextTypeVisitor extends SimpleAstVisitor<DartType> {
+ final TypeProvider typeProvider;
+
+ AstNode childNode;
+
+ _ContextTypeVisitor(this.typeProvider, this.childNode);
+
+ @override
+ DartType visitAdjacentStrings(AdjacentStrings node) {
+ if (childNode == node.strings[0]) {
+ return _visitParent(node);
+ }
+ return typeProvider.stringType;
+ }
+
+ @override
+ DartType visitArgumentList(ArgumentList node) {
+ return (childNode as Expression).staticParameterElement?.type;
+ }
+
+ @override
+ DartType visitAssertInitializer(AssertInitializer node) {
+ if (childNode == node.condition) {
+ return typeProvider.boolType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitAssertStatement(AssertStatement node) {
+ if (childNode == node.condition) {
+ return typeProvider.boolType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitAssignmentExpression(AssignmentExpression node) {
+ if (childNode == node.rightHandSide) {
+ return node.leftHandSide.staticType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitAwaitExpression(AwaitExpression node) {
+ return _visitParent(node);
+ }
+
+ @override
+ DartType visitBinaryExpression(BinaryExpression node) {
+ if (childNode == node.rightOperand) {
+ return (childNode as Expression).staticParameterElement?.type;
+ }
+ return _visitParent(node);
+ }
+
+ @override
+ DartType visitCascadeExpression(CascadeExpression node) {
+ if (childNode == node.target) {
+ return _visitParent(node);
+ }
+ return null;
+ }
+
+ @override
+ DartType visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ if (childNode == node.expression) {
+ var element = node.fieldName.staticElement;
+ if (element is FieldElement) {
+ return element.type;
+ }
+ }
+ return null;
+ }
+
+ @override
+ DartType visitDefaultFormalParameter(DefaultFormalParameter node) {
+ if (childNode == node.defaultValue) {
+ return node.parameter.declaredElement.type;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitDoStatement(DoStatement node) {
+ if (childNode == node.condition) {
+ return typeProvider.boolType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+ if (childNode == node.iterable) {
+ var parent = node.parent;
+ if ((parent is ForStatement && parent.awaitKeyword != null) ||
+ (parent is ForElement && parent.awaitKeyword != null)) {
+ return typeProvider.streamDynamicType;
+ }
+ return typeProvider.iterableDynamicType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+ if (childNode == node.iterable) {
+ var parent = node.parent;
+ if ((parent is ForStatement && parent.awaitKeyword != null) ||
+ (parent is ForElement && parent.awaitKeyword != null)) {
+ return typeProvider.streamDynamicType;
+ }
+ return typeProvider.iterableDynamicType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+ if (childNode == node.condition) {
+ return typeProvider.boolType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitForPartsWithExpression(ForPartsWithExpression node) {
+ if (childNode == node.condition) {
+ return typeProvider.boolType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitFunctionExpressionInvocation(
+ FunctionExpressionInvocation node) {
+ if (childNode == node.function) {
+ return _visitParent(node);
+ }
+ return null;
+ }
+
+ @override
+ DartType visitIfElement(IfElement node) {
+ if (childNode == node.condition) {
+ return typeProvider.boolType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitIfStatement(IfStatement node) {
+ if (childNode == node.condition) {
+ return typeProvider.boolType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitIndexExpression(IndexExpression node) {
+ if (childNode == node.index) {
+ var parameters = node.staticElement?.parameters;
+ if (parameters != null && parameters.length == 1) {
+ return parameters[0].type;
+ }
+ }
+ return null;
+ }
+
+ @override
+ DartType visitListLiteral(ListLiteral node) {
+ var typeArguments = node.typeArguments?.arguments;
+ if (typeArguments != null && typeArguments.length == 1) {
+ return typeArguments[0].type;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitMapLiteralEntry(MapLiteralEntry node) {
+ var typeArguments =
+ node.thisOrAncestorOfType<SetOrMapLiteral>()?.typeArguments;
+ if (typeArguments != null && typeArguments.length == 2) {
+ if (childNode == node.key) {
+ return typeArguments.arguments[0].type;
+ } else {
+ return typeArguments.arguments[1].type;
+ }
+ }
+ return null;
+ }
+
+ @override
+ DartType visitMethodInvocation(MethodInvocation node) {
+ if (childNode == node.target) {
+ return _visitParent(node);
+ }
+ return null;
+ }
+
+ @override
+ DartType visitParenthesizedExpression(ParenthesizedExpression node) {
+ return _visitParent(node);
+ }
+
+ @override
+ DartType visitPostfixExpression(PostfixExpression node) {
+ return (childNode as Expression).staticParameterElement?.type;
+ }
+
+ @override
+ DartType visitPrefixExpression(PrefixExpression node) {
+ return (childNode as Expression).staticParameterElement?.type;
+ }
+
+ @override
+ DartType visitPropertyAccess(PropertyAccess node) {
+ if (childNode == node.target) {
+ return _visitParent(node);
+ }
+ return null;
+ }
+
+ @override
+ DartType visitReturnStatement(ReturnStatement node) {
+ if (childNode == node.expression) {
+ return _returnType(node);
+ }
+ return null;
+ }
+
+ @override
+ DartType visitSetOrMapLiteral(SetOrMapLiteral node) {
+ if (node.isSet) {
+ var typeArguments = node.typeArguments?.arguments;
+ if (typeArguments != null && typeArguments.length == 1) {
+ return typeArguments[0].type;
+ }
+ }
+ return null;
+ }
+
+ @override
+ DartType visitSpreadElement(SpreadElement node) {
+ if (childNode == node.expression) {
+ var currentNode = node.parent;
+ while (currentNode != null) {
+ if (currentNode is ListLiteral) {
+ return typeProvider.iterableDynamicType;
+ } else if (currentNode is SetOrMapLiteral) {
+ if (currentNode.isSet) {
+ return typeProvider.iterableDynamicType;
+ }
+ return typeProvider.mapType2(
+ typeProvider.dynamicType, typeProvider.dynamicType);
+ }
+ currentNode = currentNode.parent;
+ }
+ }
+ return null;
+ }
+
+ @override
+ DartType visitVariableDeclaration(VariableDeclaration node) {
+ if (childNode == node.initializer) {
+ var parent = node.parent;
+ if (parent is VariableDeclarationList && parent.type != null) {
+ return parent.type.type;
+ }
+ }
+ return null;
+ }
+
+ @override
+ DartType visitWhileStatement(WhileStatement node) {
+ if (childNode == node.condition) {
+ return typeProvider.boolType;
+ }
+ return null;
+ }
+
+ @override
+ DartType visitYieldStatement(YieldStatement node) {
+ if (childNode == node.expression) {
+ return _returnType(node);
+ }
+ return null;
+ }
+
+ DartType _returnType(AstNode node) {
+ DartType unwrap(DartType returnType, FunctionBody body) {
+ if (returnType is InterfaceTypeImpl) {
+ DartType unwrapAs(ClassElement superclass) {
+ var convertedType = returnType.asInstanceOf(superclass);
+ if (convertedType != null) {
+ return convertedType.typeArguments[0];
+ }
+ return null;
+ }
+
+ if (body.isAsynchronous) {
+ if (body.isGenerator) {
+ // async* implies Stream<T>
+ return unwrapAs(typeProvider.streamElement);
+ } else {
+ // async implies Future<T>
+ return unwrapAs(typeProvider.futureElement);
+ }
+ } else if (body.isGenerator) {
+ // sync* implies Iterable<T>
+ return unwrapAs(typeProvider.iterableElement);
+ }
+ }
+ return returnType;
+ }
+
+ var parent = node.parent;
+ while (parent != null) {
+ if (parent is MethodDeclaration) {
+ return unwrap(parent.declaredElement.returnType, parent.body);
+ } else if (parent is ConstructorDeclaration) {
+ return parent.declaredElement.returnType;
+ } else if (parent is FunctionDeclaration) {
+ return unwrap(
+ parent.declaredElement.returnType, parent.functionExpression.body);
+ }
+ parent = parent.parent;
+ }
+ return null;
+ }
+
+ DartType _visitParent(AstNode node) {
+ if (node.parent != null) {
+ childNode = node;
+ return node.parent.accept(this);
+ }
+ return null;
+ }
+}
diff --git a/pkg/analysis_server/tool/completion_metrics/metrics_util.dart b/pkg/analysis_server/tool/completion_metrics/metrics_util.dart
index 7552187..36ca3e6 100644
--- a/pkg/analysis_server/tool/completion_metrics/metrics_util.dart
+++ b/pkg/analysis_server/tool/completion_metrics/metrics_util.dart
@@ -65,14 +65,21 @@
final List<int> ranks = [];
MeanReciprocalRankComputer();
- double get mrr {
- if (ranks.isEmpty) {
+ double getMRR([int maxRank = 0]) {
+ if (ranks.isEmpty || maxRank < 0) {
return 0;
}
-
double sum = 0;
ranks.forEach((rank) {
- sum += rank != 0 ? (1 / rank) : 0;
+ if (maxRank == 0) {
+ if (rank != 0) {
+ sum += 1 / rank;
+ }
+ } else {
+ if (rank != 0 && rank <= maxRank) {
+ sum += 1 / rank;
+ }
+ }
});
return sum / rankCount;
}
@@ -86,9 +93,15 @@
void clear() => ranks.clear();
void printMean() {
- var mrrVal = mrr;
- print('Mean Reciprocal Rank = ${mrrVal.toStringAsFixed(5)}');
- print('Harmonic Mean (inverse) = ${(1 / mrrVal).toStringAsFixed(2)}');
+ var mrrVal = getMRR();
+ print(
+ 'Mean Reciprocal Rank = ${mrrVal.toStringAsFixed(6)} '
+ '(inverse = ${(1 / mrrVal).toStringAsFixed(3)})');
+
+ var mrrVal5 = getMRR(5);
+ print(
+ 'Mean Reciprocal Rank (max rank 5) = ${mrrVal5.toStringAsFixed(6)} '
+ '(inverse = ${(1 / mrrVal5).toStringAsFixed(3)})');
}
}
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
index 60d81c4..1c5b8bf 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
@@ -24,43 +24,101 @@
ExtensionElement,
LibraryElement,
LocalVariableElement,
- ParameterElement;
+ ParameterElement,
+ PropertyAccessorElement;
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/dart/element/type_system.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:args/args.dart';
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
+import 'feature_computer.dart';
+
+/// Compute metrics to determine whether they should be used to compute a
+/// relevance score for completion suggestions.
Future<void> main(List<String> args) async {
- var out = io.stdout;
- if (args.isEmpty) {
- out.writeln('Usage: a single absolute file path to analyze.');
+ ArgParser parser = createArgParser();
+ ArgResults result = parser.parse(args);
+
+ if (validArguments(parser, result)) {
+ var out = io.stdout;
+ var rootPath = result.rest[0];
+ out.writeln('Analyzing root: "$rootPath"');
+
+ var computer = RelevanceMetricsComputer();
+ var stopwatch = Stopwatch();
+ stopwatch.start();
+ await computer.compute(rootPath,
+ corpus: result['corpus'], verbose: result['verbose']);
+ stopwatch.stop();
+
+ var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
+ out.writeln('Metrics computed in $duration');
+ computer.writeMetrics(out);
await out.flush();
- io.exit(1);
}
-
- var corpus = args[0] == '--corpus';
- var rootPath = corpus ? args[1] : args[0];
- out.writeln('Analyzing root: \"$rootPath\"');
- if (!io.Directory(rootPath).existsSync()) {
- out.writeln('\tError: No such directory exists on this machine.\n');
- return;
- }
-
- var computer = RelevanceMetricsComputer();
- var stopwatch = Stopwatch();
- stopwatch.start();
- await computer.compute(rootPath, corpus: corpus);
- stopwatch.stop();
- var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
- out.writeln(' Metrics computed in $duration');
- computer.writeMetrics(out);
- await out.flush();
io.exit(0);
}
+/// Create a parser that can be used to parse the command-line arguments.
+ArgParser createArgParser() {
+ ArgParser parser = ArgParser();
+ parser.addFlag(
+ 'corpus',
+ help: 'Analyze each of the subdirectories separately',
+ negatable: false,
+ );
+ parser.addOption(
+ 'help',
+ abbr: 'h',
+ help: 'Print this help message.',
+ );
+ parser.addFlag(
+ 'verbose',
+ abbr: 'v',
+ help: 'Print additional information about the analysis',
+ negatable: false,
+ );
+ return parser;
+}
+
+/// Print usage information for this tool.
+void printUsage(ArgParser parser, {String error}) {
+ if (error != null) {
+ print(error);
+ print('');
+ }
+ print('usage: dart relevance_metrics.dart [options] packagePath');
+ print('');
+ print('Compute metrics to determine whether they should be used to compute');
+ print('a relevance score for completion suggestions.');
+ print('');
+ print(parser.usage);
+}
+
+/// Return `true` if the command-line arguments (represented by the [result] and
+/// parsed by the [parser]) are valid.
+bool validArguments(ArgParser parser, ArgResults result) {
+ if (result.wasParsed('help')) {
+ printUsage(parser);
+ return false;
+ } else if (result.rest.length != 1) {
+ printUsage(parser, error: 'No package path specified.');
+ return false;
+ }
+ var rootPath = result.rest[0];
+ if (!io.Directory(rootPath).existsSync()) {
+ printUsage(parser, error: 'The directory "$rootPath" does not exist.');
+ return false;
+ }
+ return true;
+}
+
/// An object that records the data used to compute the metrics.
class RelevanceData {
/// A number identifying the version of this code that produced a given JSON
@@ -299,9 +357,15 @@
/// The library containing the compilation unit being visited.
LibraryElement enclosingLibrary;
+ /// The type provider associated with the current compilation unit.
+ TypeProvider typeProvider;
+
/// The type system associated with the current compilation unit.
TypeSystem typeSystem;
+ /// The object used to compute the values of features.
+ FeatureComputer featureComputer;
+
/// Initialize a newly created collector to add data points to the given
/// [data].
RelevanceDataCollector(this.data);
@@ -503,8 +567,10 @@
@override
void visitCompilationUnit(CompilationUnit node) {
enclosingLibrary = node.declaredElement.library;
+ typeProvider = enclosingLibrary.typeProvider;
typeSystem = enclosingLibrary.typeSystem;
inheritanceManager = InheritanceManager3();
+ featureComputer = FeatureComputer(typeProvider);
for (var directive in node.directives) {
_recordTokenType('CompilationUnit (directive)', directive,
@@ -516,9 +582,11 @@
}
super.visitCompilationUnit(node);
- typeSystem = null;
- enclosingLibrary = null;
+ featureComputer = null;
inheritanceManager = null;
+ typeSystem = null;
+ typeProvider = null;
+ enclosingLibrary = null;
}
@override
@@ -775,6 +843,15 @@
@override
void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
// There are no completions.
+ var contextType = featureComputer.computeContextType(node);
+ if (contextType != null) {
+ var memberType = _returnType(node.staticElement);
+ if (memberType != null) {
+ _recordTypeRelationships(
+ 'function expression invocation', contextType, memberType,
+ isContextType: true);
+ }
+ }
super.visitFunctionExpressionInvocation(node);
}
@@ -957,8 +1034,10 @@
(element.enclosingElement as ClassElement).thisType,
Name(element.librarySource.uri, element.name));
if (overriddenMembers != null) {
- // TODO(brianwilkerson) Should we limit this to the most immediate
- // override?
+ // Consider limiting this to the most immediate override. If the
+ // signature of a method is changed by one of the overrides, then it
+ // isn't reasonable to expect the overrides of that member to conform to
+ // the signatures of the overridden members from superclasses.
for (var overridden in overriddenMembers) {
_recordOverride(element, overridden);
}
@@ -969,7 +1048,28 @@
@override
void visitMethodInvocation(MethodInvocation node) {
- _recordMemberDepth(node.target?.staticType, node.methodName.staticElement);
+ var member = node.methodName.staticElement;
+ _recordMemberDepth(node.target?.staticType, member);
+ if (node.target is SuperExpression) {
+ var enclosingMethod = node.thisOrAncestorOfType<MethodDeclaration>();
+ if (enclosingMethod != null) {
+ if (enclosingMethod.name.name == node.methodName.name) {
+ data.recordTypeMatch('super invocation member', 'same');
+ } else {
+ data.recordTypeMatch('super invocation member', 'different');
+ }
+ }
+ }
+ if (node.target != null) {
+ var contextType = featureComputer.computeContextType(node);
+ if (contextType != null) {
+ var memberType = _returnType(member);
+ if (memberType != null) {
+ _recordTypeRelationships('method invocation', contextType, memberType,
+ isContextType: true);
+ }
+ }
+ }
super.visitMethodInvocation(node);
}
@@ -1064,8 +1164,28 @@
@override
void visitPropertyAccess(PropertyAccess node) {
- _recordMemberDepth(
- node.target?.staticType, node.propertyName.staticElement);
+ var member = node.propertyName.staticElement;
+ _recordMemberDepth(node.target?.staticType, member);
+ if (node.target is SuperExpression) {
+ var enclosingMethod = node.thisOrAncestorOfType<MethodDeclaration>();
+ if (enclosingMethod != null) {
+ if (enclosingMethod.name.name == node.propertyName.name) {
+ data.recordTypeMatch('super property access member', 'same');
+ } else {
+ data.recordTypeMatch('super property access member', 'different');
+ }
+ }
+ }
+ if (!(member is PropertyAccessorElement && member.isSetter)) {
+ var contextType = featureComputer.computeContextType(node);
+ if (contextType != null) {
+ var memberType = _returnType(member);
+ if (memberType != null) {
+ _recordTypeRelationships('property access', contextType, memberType,
+ isContextType: true);
+ }
+ }
+ }
super.visitPropertyAccess(node);
}
@@ -1371,9 +1491,6 @@
}
}
if (currentNode is SimpleIdentifier && currentNode.inDeclarationContext()) {
- // TODO(brianwilkerson) Explore recording when the left-most identifier is
- // in a declaration context to help align identifier counts (from the
- // token type list) with the element counts.
return null;
}
return currentNode;
@@ -1417,8 +1534,10 @@
var distance = 0;
var node = reference;
while (node != null) {
- if (node is ForStatement) {
- var loopParts = node.forLoopParts;
+ if (node is ForStatement || node is ForElement) {
+ var loopParts = node is ForStatement
+ ? node.forLoopParts
+ : (node as ForElement).forLoopParts;
if (loopParts is ForPartsWithDeclarations) {
for (var declaredVariable in loopParts.variables.variables.reversed) {
if (declaredVariable.declaredElement == variable) {
@@ -1536,6 +1655,9 @@
/// Record the distance between the static type of the target (the
/// [targetType]) and the [member] to which the reference was resolved.
void _recordMemberDepth(DartType targetType, Element member) {
+ if (member == null) {
+ return;
+ }
if (targetType is InterfaceType) {
var targetClass = targetType.element;
var extension = member.thisOrAncestorOfType<ExtensionElement>();
@@ -1581,47 +1703,21 @@
return depth;
}
- const notFound = 0xFFFF;
-
- /// Return the minimum distance from the [currentClass] to the
- /// [memberClass] along any inheritance chain (including interfaces).
- /// This includes paths introduced by mixins.
- int getInterfaceDepth(ClassElement currentClass) {
- if (currentClass == null) {
- return notFound;
- } else if (currentClass == memberClass) {
- return 0;
- }
- var minDepth = getInterfaceDepth(currentClass.supertype?.element);
- for (var mixin in currentClass.mixins) {
- var depth = getInterfaceDepth(mixin.element);
- if (depth < minDepth) {
- minDepth = depth;
- }
- }
- for (var interface in currentClass.interfaces) {
- var depth = getInterfaceDepth(interface.element);
- if (depth < minDepth) {
- minDepth = depth;
- }
- }
- return minDepth + 1;
- }
-
int superclassDepth = getSuperclassDepth();
- int interfaceDepth = getInterfaceDepth(targetClass);
+ int interfaceDepth =
+ featureComputer.inheritanceDistance(targetClass, memberClass);
if (superclassDepth >= 0) {
_recordDistance('member (superclass)', superclassDepth);
- data.recordDistanceByDepth(getTargetDepth(), superclassDepth);
+ } else if (interfaceDepth >= 0) {
+ _recordDistance('member (interface)', interfaceDepth);
} else {
- if (interfaceDepth < notFound) {
- _recordDistance('member (interface)', interfaceDepth);
- } else {
- _recordDistance('member (not found)', 0);
- }
+ // This shouldn't happen, so it's worth investigating the cause when
+ // it does.
+ _recordDistance('member (not found)', 0);
}
- if (interfaceDepth < notFound) {
+ if (interfaceDepth >= 0) {
_recordDistance('member (shortest distance)', interfaceDepth);
+ data.recordDistanceByDepth(getTargetDepth(), interfaceDepth);
}
}
}
@@ -1691,6 +1787,9 @@
// crossed and then reporting the distance with a label such as
// 'local variable ($boundaryCount)'.
var distance = _localVariableDistance(node, element);
+ if (distance < 0) {
+ DateTime.now();
+ }
_recordDistance('distance to local variable', distance);
} else if (element != null) {
// TODO(brianwilkerson) We might want to cross reference the depth of
@@ -1791,17 +1890,56 @@
/// Record information about how the [parameterType] and [argumentType] are
/// related, using the [descriptor] to differentiate between the counts.
void _recordTypeRelationships(
- String descriptor, DartType parameterType, DartType argumentType) {
+ String descriptor, DartType parameterType, DartType argumentType,
+ {bool isContextType = false}) {
if (argumentType == parameterType) {
data.recordTypeMatch('$descriptor', 'exact');
+ data.recordTypeMatch('all', 'exact');
} else if (typeSystem.isSubtypeOf(argumentType, parameterType)) {
data.recordTypeMatch('$descriptor', 'subtype');
+ data.recordTypeMatch('all', 'subtype');
+ if (isContextType &&
+ argumentType is InterfaceType &&
+ parameterType is InterfaceType) {
+ int distance;
+ if (parameterType.element == typeProvider.futureOrElement) {
+ var typeArgument = parameterType.typeArguments[0];
+ distance = featureComputer.inheritanceDistance(
+ argumentType.element, typeProvider.futureElement);
+ if (typeArgument is InterfaceType) {
+ var argDistance = featureComputer.inheritanceDistance(
+ argumentType.element, typeArgument.element);
+ if (distance < 0 || (argDistance >= 0 && argDistance < distance)) {
+ distance = argDistance;
+ }
+ }
+ } else {
+ distance = featureComputer.inheritanceDistance(
+ argumentType.element, parameterType.element);
+ }
+ if (distance < 0) {
+ DateTime.now();
+ }
+ data.recordDistance('Subtype of context type ($descriptor)', distance);
+ data.recordDistance('Subtype of context type (all)', distance);
+ }
} else if (typeSystem.isSubtypeOf(parameterType, argumentType)) {
data.recordTypeMatch('$descriptor', 'supertype');
+ data.recordTypeMatch('all', 'supertype');
} else {
data.recordTypeMatch('$descriptor', 'unrelated');
+ data.recordTypeMatch('all', 'unrelated');
}
}
+
+ /// Return the return type of the [element], or `null` if the element doesn't
+ /// have a return type.
+ DartType _returnType(Element element) {
+ if (element is ExecutableElement) {
+ return element.returnType;
+ }
+ return null;
+ }
}
/// An object used to compute metrics for a single file or directory.
@@ -1816,7 +1954,8 @@
/// Compute the metrics for the file(s) in the [rootPath].
/// If [corpus] is true, treat rootPath as a container of packages, creating
/// a new context collection for each subdirectory.
- void compute(String rootPath, {bool corpus}) async {
+ void compute(String rootPath,
+ {@required bool corpus, @required bool verbose}) async {
final collector = RelevanceDataCollector(data);
var roots = _computeRootPaths(rootPath, corpus);
for (var root in roots) {
@@ -1835,20 +1974,28 @@
//
if (resolvedUnitResult == null) {
print('File $filePath skipped because resolved unit was null.');
- print('');
+ if (verbose) {
+ print('');
+ }
continue;
} else if (resolvedUnitResult.state != ResultState.VALID) {
print(
'File $filePath skipped because it could not be analyzed.');
- print('');
+ if (verbose) {
+ print('');
+ }
continue;
} else if (hasError(resolvedUnitResult)) {
- print('File $filePath skipped due to errors:');
- for (var error in resolvedUnitResult.errors
- .where((e) => e.severity == Severity.error)) {
- print(' ${error.toString()}');
+ if (verbose) {
+ print('File $filePath skipped due to errors:');
+ for (var error in resolvedUnitResult.errors
+ .where((e) => e.severity == Severity.error)) {
+ print(' ${error.toString()}');
+ }
+ print('');
+ } else {
+ print('File $filePath skipped due to analysis errors.');
}
- print('');
continue;
}
@@ -1856,6 +2003,7 @@
resolvedUnitResult.unit.accept(collector);
} catch (exception, stacktrace) {
print('Exception caught analyzing: "$filePath"');
+ print(exception);
print(stacktrace);
}
}
@@ -1874,12 +2022,14 @@
var firstLabel = ', first token';
var firstIndex = key.indexOf(firstLabel);
if (firstIndex > 0) {
- first[key.replaceFirst(firstLabel, '')] = entry.value;
+ first[' ${key.replaceFirst(firstLabel, '')}'] =
+ entry.value.map((key, value) => MapEntry(' $key', value));
} else {
var wholeLabel = ', whole';
var wholeIndex = key.indexOf(wholeLabel);
if (wholeIndex > 0) {
- whole[key.replaceFirst(wholeLabel, '')] = entry.value;
+ whole[' ${key.replaceFirst(wholeLabel, '')}'] =
+ entry.value.map((key, value) => MapEntry(' $key', value));
} else {
rest[key] = entry.value;
}
@@ -2025,7 +2175,11 @@
void _writeContextMap(
StringSink sink, Map<String, Map<String, int>> contextMap) {
var contexts = contextMap.keys.toList()..sort();
- for (var context in contexts) {
+ for (var i = 0; i < contexts.length; i++) {
+ if (i > 0) {
+ sink.writeln();
+ }
+ var context = contexts[i];
var lines = _convertMap(context, contextMap[context]);
for (var line in lines) {
sink.writeln(' $line');
@@ -2141,3 +2295,24 @@
return false;
}
}
+
+class Timer {
+ Stopwatch stopwatch = Stopwatch();
+
+ int count = 0;
+
+ Timer();
+
+ double get averageTime => count == 0 ? 0 : totalTime / count;
+
+ int get totalTime => stopwatch.elapsedMilliseconds;
+
+ void start() {
+ stopwatch.start();
+ }
+
+ void stop() {
+ stopwatch.stop();
+ count++;
+ }
+}
diff --git a/pkg/analysis_server/tool/migration_runner.dart b/pkg/analysis_server/tool/migration_runner.dart
index ce974de..4a1e7e3 100644
--- a/pkg/analysis_server/tool/migration_runner.dart
+++ b/pkg/analysis_server/tool/migration_runner.dart
@@ -25,6 +25,7 @@
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
@@ -72,8 +73,13 @@
String sdkPath = FolderBasedDartSdk.defaultSdkDirectory(
PhysicalResourceProvider.INSTANCE,
).path;
- return AnalysisServer(serverChannel, resourceProvider, options,
- DartSdkManager(sdkPath, true), InstrumentationService.NULL_SERVICE);
+ return AnalysisServer(
+ serverChannel,
+ resourceProvider,
+ options,
+ DartSdkManager(sdkPath, true),
+ CrashReportingAttachmentsBuilder.empty,
+ InstrumentationService.NULL_SERVICE);
}
void processNotification(Notification notification) {
diff --git a/pkg/analysis_server_client/lib/server.dart b/pkg/analysis_server_client/lib/server.dart
index 17d93c6..d8024dd 100644
--- a/pkg/analysis_server_client/lib/server.dart
+++ b/pkg/analysis_server_client/lib/server.dart
@@ -26,6 +26,10 @@
/// or if the server has already been stopped.
Process _process;
+ /// Replicate all stdout/stderr data from the server process to stdout/stderr,
+ /// when true.
+ bool _stdioPassthrough;
+
/// Commands that have been sent to the server but not yet acknowledged,
/// and the [Completer] objects which should be completed
/// when acknowledgement is received.
@@ -43,9 +47,11 @@
/// [listenToOutput] has not been called or [stop] has been called.
StreamSubscription<String> _stdoutSubscription;
- Server({ServerListener listener, Process process})
+ Server(
+ {ServerListener listener, Process process, bool stdioPassthrough = false})
: _listener = listener,
- _process = process;
+ _process = process,
+ _stdioPassthrough = stdioPassthrough;
/// Force kill the server. Returns exit code future.
Future<int> kill({String reason = 'none'}) {
@@ -63,6 +69,7 @@
.transform(utf8.decoder)
.transform(LineSplitter())
.listen((String line) {
+ if (_stdioPassthrough) stdout.writeln(line);
String trimmedLine = line.trim();
// Guard against lines like:
@@ -116,6 +123,7 @@
.transform(utf8.decoder)
.transform(LineSplitter())
.listen((String line) {
+ if (_stdioPassthrough) stderr.writeln(line);
String trimmedLine = line.trim();
_listener?.errorMessage(trimmedLine);
});
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index f6e77f1..c85edce 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -367,6 +367,8 @@
HintCode.DUPLICATE_IMPORT,
HintCode.DUPLICATE_HIDDEN_NAME,
HintCode.DUPLICATE_SHOWN_NAME,
+ HintCode.EQUAL_ELEMENTS_IN_SET,
+ HintCode.EQUAL_KEYS_IN_MAP,
HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE,
HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE,
HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
@@ -381,6 +383,7 @@
HintCode.INVALID_IMMUTABLE_ANNOTATION,
HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN,
HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS,
+ HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION,
HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE,
HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER,
HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX,
@@ -656,6 +659,7 @@
ParserErrorCode.VAR_ENUM,
ParserErrorCode.VAR_RETURN_TYPE,
ParserErrorCode.VAR_TYPEDEF,
+ ParserErrorCode.VOID_WITH_TYPE_ARGUMENTS,
ParserErrorCode.WITH_BEFORE_EXTENDS,
ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER,
ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
diff --git a/pkg/analyzer/lib/instrumentation/log_adapter.dart b/pkg/analyzer/lib/instrumentation/log_adapter.dart
index d1b54f5..48dea7d 100644
--- a/pkg/analyzer/lib/instrumentation/log_adapter.dart
+++ b/pkg/analyzer/lib/instrumentation/log_adapter.dart
@@ -38,7 +38,9 @@
void logError(String message) => _log(TAG_ERROR, message);
@override
- void logException(dynamic exception, [StackTrace stackTrace]) {
+ void logException(dynamic exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]) {
if (_instrumentationLogger != null) {
String message = _toString(exception);
String trace = _toString(stackTrace);
diff --git a/pkg/analyzer/lib/instrumentation/multicast_service.dart b/pkg/analyzer/lib/instrumentation/multicast_service.dart
index 0d4fa40..d0e288d 100644
--- a/pkg/analyzer/lib/instrumentation/multicast_service.dart
+++ b/pkg/analyzer/lib/instrumentation/multicast_service.dart
@@ -17,8 +17,11 @@
}
@override
- void logException(exception, [StackTrace stackTrace]) {
- _services.forEach((s) => s.logException(exception, stackTrace));
+ void logException(exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]) {
+ _services
+ .forEach((s) => s.logException(exception, stackTrace, attachments));
}
@override
diff --git a/pkg/analyzer/lib/instrumentation/noop_service.dart b/pkg/analyzer/lib/instrumentation/noop_service.dart
index c550863..47ca4ac 100644
--- a/pkg/analyzer/lib/instrumentation/noop_service.dart
+++ b/pkg/analyzer/lib/instrumentation/noop_service.dart
@@ -12,7 +12,9 @@
void logError(String message) {}
@override
- void logException(dynamic exception, [StackTrace stackTrace]) {}
+ void logException(dynamic exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]) {}
@override
void logInfo(String message, [dynamic exception]) {}
diff --git a/pkg/analyzer/lib/instrumentation/service.dart b/pkg/analyzer/lib/instrumentation/service.dart
index 59d9a2a..1fda166 100644
--- a/pkg/analyzer/lib/instrumentation/service.dart
+++ b/pkg/analyzer/lib/instrumentation/service.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/instrumentation/noop_service.dart';
import 'package:analyzer/instrumentation/plugin_data.dart';
+import 'package:meta/meta.dart';
/// The interface used by client code to communicate with an instrumentation
/// service of some kind.
@@ -16,7 +17,9 @@
/// Log that the given non-priority [exception] was thrown, with the given
/// [stackTrace].
- void logException(dynamic exception, [StackTrace stackTrace]);
+ void logException(dynamic exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]);
/// Log unstructured text information for debugging purposes.
void logInfo(String message, [dynamic exception]);
@@ -75,3 +78,16 @@
/// Shut down this service.
Future<void> shutdown();
}
+
+/// The additional attachment to be logged.
+class InstrumentationServiceAttachment {
+ final String id;
+ final String stringValue;
+
+ /// Create a new attachment with the unique [id] and string [value].
+ InstrumentationServiceAttachment.string({
+ @required String id,
+ @required String value,
+ }) : id = id,
+ stringValue = value;
+}
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
index 41ffce6..1a8488c 100644
--- a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
@@ -21,8 +21,7 @@
AnalysisOptionsProvider([this.sourceFactory]);
- /// Provide the options found in either
- /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_FILE] or
+ /// Provide the options found in
/// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE].
/// Recursively merge options referenced by an include directive
/// and remove the include directive from the resulting options map.
@@ -43,10 +42,6 @@
File getOptionsFile(Folder root, {bool crawlUp = false}) {
Resource resource;
for (Folder folder = root; folder != null; folder = folder.parent) {
- resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
- if (resource.exists) {
- break;
- }
resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
if (resource.exists || !crawlUp) {
break;
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index ab6528f..56a0059 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -378,12 +378,7 @@
}
Folder root = resourceProvider.getFolder(path);
for (Folder folder = root; folder != null; folder = folder.parent) {
- File file =
- folder.getChildAssumingFile(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
- if (file.exists) {
- return file;
- }
- file = folder
+ File file = folder
.getChildAssumingFile(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
if (file.exists) {
return file;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index e70caa1..6376a63 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1473,7 +1473,6 @@
var featureSetProvider = FeatureSetProvider.build(
resourceProvider: resourceProvider,
packages: _packages,
- sourceFactory: _sourceFactory,
packageDefaultFeatureSet: _analysisOptions.contextFeatures,
nonPackageDefaultFeatureSet: _analysisOptions.nonPackageFeatureSet,
);
@@ -1688,7 +1687,15 @@
contextKey = state.contextKey;
}
CaughtException caught = CaughtException(exception, stackTrace);
- _exceptionController.add(ExceptionResult(path, caught, contextKey));
+ String fileContent = _fsState.getFileForPath(path).content;
+ _exceptionController.add(
+ ExceptionResult(
+ filePath: path,
+ fileContent: fileContent,
+ exception: caught,
+ contextKey: contextKey,
+ ),
+ );
}
/// Serialize the given [resolvedUnit] errors and index into bytes.
@@ -2116,7 +2123,10 @@
/// The path of the file being analyzed when the [exception] happened.
///
/// Absolute and normalized.
- final String path;
+ final String filePath;
+
+ /// The path of the file being analyzed when the [exception] happened.
+ final String fileContent;
/// The exception during analysis of the file with the [path].
final CaughtException exception;
@@ -2127,7 +2137,12 @@
/// number of context to store was reached, etc.
final String contextKey;
- ExceptionResult(this.path, this.exception, this.contextKey);
+ ExceptionResult({
+ @required this.filePath,
+ @required this.fileContent,
+ @required this.exception,
+ @required this.contextKey,
+ });
}
/// Worker in [AnalysisDriverScheduler].
diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
index 40511f1..eb9896b 100644
--- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
@@ -5,7 +5,7 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/packages.dart';
-import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:meta/meta.dart';
class FeatureSetProvider {
@@ -37,7 +37,8 @@
for (var package in _packages.packages) {
if (package.rootFolder.contains(path)) {
var languageVersion = package.languageVersion;
- if (languageVersion == null) {
+ if (languageVersion == null ||
+ languageVersion == ExperimentStatus.currentVersion) {
return _packageDefaultFeatureSet;
} else {
return _packageDefaultFeatureSet.restrictToVersion(languageVersion);
@@ -51,7 +52,6 @@
static FeatureSetProvider build({
@required ResourceProvider resourceProvider,
@required Packages packages,
- @required SourceFactory sourceFactory,
@required FeatureSet packageDefaultFeatureSet,
@required FeatureSet nonPackageDefaultFeatureSet,
}) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index a53d2a1..27aaef9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -23,6 +23,10 @@
/// element model. But we want to index these parameter references
/// as references to declared parameters.
ParameterElement namedParameterElement(ExecutableElement executable) {
+ if (executable == null) {
+ return null;
+ }
+
var parameterName = node.name;
return executable.declaration.parameters.where((parameter) {
return parameter.isNamed && parameter.name == parameterName;
@@ -39,7 +43,8 @@
if (invocation is InstanceCreationExpression) {
return namedParameterElement(invocation.staticElement);
} else if (invocation is MethodInvocation) {
- return namedParameterElement(invocation.methodName.staticElement);
+ var executable = invocation.methodName.staticElement;
+ return namedParameterElement(executable);
}
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index a41e3dc..7c6cc1c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -14,7 +14,7 @@
import 'package:analyzer/src/error/best_practices_verifier.dart';
import 'package:analyzer/src/error/dart2js_verifier.dart';
import 'package:analyzer/src/error/dead_code_verifier.dart';
-import 'package:analyzer/src/error/invalid_language_version_override_finder.dart';
+import 'package:analyzer/src/error/language_version_override_verifier.dart';
import 'package:analyzer/src/error/override_verifier.dart';
import 'package:analyzer/src/error/todo_finder.dart';
import 'package:analyzer/src/error/unused_local_elements_verifier.dart';
@@ -279,7 +279,7 @@
));
TodoFinder(errorReporter).findIn(unit);
- InvalidLanguageVersionOverrideFinder(errorReporter).findIn(unit);
+ LanguageVersionOverrideVerifier(errorReporter).verify(unit);
// Verify imports.
{
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 5373504..a5a7761 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -1393,14 +1393,14 @@
@override
Iterator<SyntacticEntity> get iterator => _entities.iterator;
- /// Add an AST node or token as the next child entity, if it is not null.
+ /// Add an AST node or token as the next child entity, if it is not `null`.
void add(SyntacticEntity entity) {
if (entity != null) {
_entities.add(entity);
}
}
- /// Add the given items as the next child entities, if [items] is not null.
+ /// Add the given items as the next child entities, if [items] is not `null`.
void addAll(Iterable<SyntacticEntity> items) {
if (items != null) {
_entities.addAll(items);
@@ -4067,6 +4067,8 @@
NodeList<Annotation> metadata = this.metadata;
if (metadata.isNotEmpty) {
return metadata.beginToken;
+ } else if (requiredKeyword != null) {
+ return requiredKeyword;
} else if (covariantKeyword != null) {
return covariantKeyword;
} else if (keyword != null) {
@@ -5166,11 +5168,19 @@
}
@override
- Token get beginToken =>
- this.metadata.beginToken ??
- covariantKeyword ??
- _returnType?.beginToken ??
- identifier?.beginToken;
+ Token get beginToken {
+ NodeList<Annotation> metadata = this.metadata;
+ if (metadata.isNotEmpty) {
+ return metadata.beginToken;
+ } else if (requiredKeyword != null) {
+ return requiredKeyword;
+ } else if (covariantKeyword != null) {
+ return covariantKeyword;
+ } else if (_returnType != null) {
+ return _returnType.beginToken;
+ }
+ return identifier?.beginToken;
+ }
@override
Iterable<SyntacticEntity> get childEntities =>
@@ -5853,6 +5863,7 @@
@override
bool get isNullAware =>
+ question != null ||
leftBracket.type == TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET ||
(leftBracket.type == TokenType.OPEN_SQUARE_BRACKET &&
period != null &&
@@ -7690,9 +7701,7 @@
} else {
result.addAll(sortedCommentAndAnnotations);
}
- if (covariantKeyword != null) {
- result.add(covariantKeyword);
- }
+ result..add(requiredKeyword)..add(covariantKeyword);
return result;
}
@@ -8724,6 +8733,8 @@
NodeList<Annotation> metadata = this.metadata;
if (metadata.isNotEmpty) {
return metadata.beginToken;
+ } else if (requiredKeyword != null) {
+ return requiredKeyword;
} else if (covariantKeyword != null) {
return covariantKeyword;
} else if (keyword != null) {
diff --git a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
index 1f5145f..81188ae 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -741,13 +741,14 @@
@override
void visitIndexExpression(IndexExpression node) {
if (node.isCascaded) {
- sink.write(node.period.lexeme);
+ safelyVisitToken(node.period);
} else {
safelyVisitNode(node.target);
}
- sink.write('[');
+ safelyVisitToken(node.question);
+ safelyVisitToken(node.leftBracket);
safelyVisitNode(node.index);
- sink.write(']');
+ safelyVisitToken(node.rightBracket);
}
@override
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 6d5e688..84df830 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -371,6 +371,21 @@
"members.");
/**
+ * No parameters.
+ */
+ static const HintCode EQUAL_ELEMENTS_IN_SET = HintCode(
+ 'EQUAL_ELEMENTS_IN_SET',
+ "Two elements in a set literal shouldn't be equal.",
+ correction: "Change or remove the duplicate element.");
+
+ /**
+ * No parameters.
+ */
+ static const HintCode EQUAL_KEYS_IN_MAP = HintCode(
+ 'EQUAL_KEYS_IN_MAP', "Two keys in a map literal shouldn't be equal.",
+ correction: "Change or remove the duplicate key.");
+
+ /**
* It is a bad practice for a source file in a package "lib" directory
* hierarchy to traverse outside that directory hierarchy. For example, a
* source file in the "lib" directory should not contain a directive such as
@@ -727,6 +742,16 @@
correction: "Specify a Dart language version override with a comment "
"like '// @dart = 2.0'.");
+ static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION =
+ HintCodeWithUniqueName(
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE',
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION',
+ "The language version override must be before any declaration or "
+ "directive.",
+ correction:
+ "Try moving the language version override to the top of the file.",
+ );
+
/// Invalid Dart language version comments don't follow the specification [1].
/// If a comment begins with "@dart" or "dart" (letters in any case),
/// followed by optional whitespace, followed by optional non-alphanumeric,
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 3d72df4..56aa287 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -881,6 +881,9 @@
correction: "Try removing the keyword 'var', or "
"replacing it with the name of the return type.");
+ static const ParserErrorCode VOID_WITH_TYPE_ARGUMENTS =
+ _VOID_WITH_TYPE_ARGUMENTS;
+
/**
* Initialize a newly created error code to have the given [name]. The message
* associated with the error will be created from the given [message]
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 44e6243..a07b175 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -107,6 +107,7 @@
_MULTIPLE_VARIANCE_MODIFIERS,
_INVALID_USE_OF_COVARIANT_IN_EXTENSION,
_TYPE_PARAMETER_ON_CONSTRUCTOR,
+ _VOID_WITH_TYPE_ARGUMENTS,
];
const ParserErrorCode _ABSTRACT_CLASS_MEMBER = ParserErrorCode(
@@ -574,6 +575,10 @@
correction:
"Try removing the keyword 'var', or replacing it with the name of the return type.");
+const ParserErrorCode _VOID_WITH_TYPE_ARGUMENTS = ParserErrorCode(
+ 'VOID_WITH_TYPE_ARGUMENTS', r"Type 'void' can't have type arguments.",
+ correction: "Try removing the type arguments.");
+
const ParserErrorCode _WITH_BEFORE_EXTENDS = ParserErrorCode(
'WITH_BEFORE_EXTENDS',
r"The extends clause must be before the with clause.",
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 86cf045..4930380 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -101,7 +101,6 @@
var featureSetProvider = FeatureSetProvider.build(
resourceProvider: resourceProvider,
packages: Packages.empty,
- sourceFactory: analysisContext.sourceFactory,
packageDefaultFeatureSet: analysisContext.analysisOptions.contextFeatures,
nonPackageDefaultFeatureSet:
(options as AnalysisOptionsImpl).nonPackageFeatureSet,
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index 7ceee5d..353a746 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -125,14 +125,14 @@
}
void executableDeclaration_enter(
- Declaration node, FormalParameterList parameters, bool isClosure) {
+ AstNode node, FormalParameterList parameters, bool isClosure) {
if (isClosure) {
flow.functionExpression_begin(node);
}
if (parameters != null) {
for (var parameter in parameters.parameters) {
- flow.initialize(parameter.declaredElement);
+ flow.declare(parameter.declaredElement, true);
}
}
}
@@ -224,9 +224,7 @@
var variables = node.variables;
for (var i = 0; i < variables.length; ++i) {
var variable = variables[i];
- if (variable.initializer != null) {
- flow.initialize(variable.declaredElement);
- }
+ flow.declare(variable.declaredElement, variable.initializer != null);
}
}
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
index d7a6426..efb83e0 100644
--- a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
@@ -124,6 +124,10 @@
loopVariableElement.type = elementType;
}
+ if (loopVariable != null) {
+ _flowAnalysis?.flow?.declare(loopVariable.declaredElement, true);
+ }
+
_flowAnalysis?.flow?.forEach_bodyBegin(
node,
identifierElement is VariableElement
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 31d7255..6c5f405 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -566,6 +566,12 @@
}
@override
+ void visitSetOrMapLiteral(SetOrMapLiteral node) {
+ _checkForDuplications(node);
+ super.visitSetOrMapLiteral(node);
+ }
+
+ @override
void visitSimpleIdentifier(SimpleIdentifier node) {
_checkForDeprecatedMemberUseAtIdentifier(node);
_invalidAccessVerifier.verify(node);
@@ -824,6 +830,31 @@
return false;
}
+ /// Generate hints related to duplicate elements (keys) in sets (maps).
+ void _checkForDuplications(SetOrMapLiteral node) {
+ // This only checks for top-level elements. If, for, and spread elements
+ // that contribute duplicate values are not detected.
+ if (node.isConst) {
+ // This case is covered by the ErrorVerifier.
+ return;
+ }
+ final expressions = node.isSet
+ ? node.elements.whereType<Expression>()
+ : node.elements.whereType<MapLiteralEntry>().map((entry) => entry.key);
+ final alreadySeen = <DartObject>{};
+ for (final expression in expressions) {
+ final constEvaluation = _linterContext.evaluateConstant(expression);
+ if (constEvaluation.errors.isEmpty) {
+ if (!alreadySeen.add(constEvaluation.value)) {
+ var errorCode = node.isSet
+ ? HintCode.EQUAL_ELEMENTS_IN_SET
+ : HintCode.EQUAL_KEYS_IN_MAP;
+ _errorReporter.reportErrorForNode(errorCode, expression);
+ }
+ }
+ }
+ }
+
/// Checks whether [node] violates the rules of [immutable].
///
/// If [node] is marked with [immutable] or inherits from a class or mixin
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 9352b05..4b9438d 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -1654,7 +1654,8 @@
// returned by an iterator.
static const CompileTimeErrorCode EQUAL_ELEMENTS_IN_CONST_SET =
CompileTimeErrorCode('EQUAL_ELEMENTS_IN_CONST_SET',
- "Two values in a constant set can't be equal.",
+ "Two elements in a constant set literal can't be equal.",
+ correction: "Change or remove the duplicate element.",
hasPublishedDocs: true);
/**
@@ -8162,14 +8163,16 @@
* it indicates a different type of programmer error and has different
* corrections.
*
- * Parameters: none
+ * No parameters.
*/
- static const StaticWarningCode INVALID_USE_OF_NULL_VALUE = StaticWarningCode(
- 'INVALID_USE_OF_NULL_VALUE',
- "This expression is invalid as it will always be null.",
- correction:
- "Try changing the type, or casting, to a more useful type like "
- "dynamic.");
+ static const StaticWarningCode INVALID_USE_OF_NULL_VALUE =
+ StaticWarningCodeWithUniqueName(
+ 'USE_OF_NULLABLE_VALUE',
+ 'INVALID_USE_OF_NULL_VALUE',
+ "This expression is invalid as it will always be null.",
+ correction:
+ "Try changing the type, or casting, to a more useful type like "
+ "dynamic.");
/**
* Parameters:
@@ -9117,10 +9120,11 @@
/**
* For the purposes of experimenting with potential non-null type semantics.
*
- * Parameters: none
+ * No parameters.
*/
static const StaticWarningCode UNCHECKED_USE_OF_NULLABLE_VALUE =
- StaticWarningCode(
+ StaticWarningCodeWithUniqueName(
+ 'USE_OF_NULLABLE_VALUE',
'UNCHECKED_USE_OF_NULLABLE_VALUE',
"The expression is nullable and must be null-checked before it can "
"be used.",
diff --git a/pkg/analyzer/lib/src/error/invalid_language_version_override_finder.dart b/pkg/analyzer/lib/src/error/language_version_override_verifier.dart
similarity index 86%
rename from pkg/analyzer/lib/src/error/invalid_language_version_override_finder.dart
rename to pkg/analyzer/lib/src/error/language_version_override_verifier.dart
index 23d397f..d5732f9 100644
--- a/pkg/analyzer/lib/src/error/invalid_language_version_override_finder.dart
+++ b/pkg/analyzer/lib/src/error/language_version_override_verifier.dart
@@ -7,20 +7,17 @@
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/error/codes.dart';
-/// Instances of the class `InvalidLanguageVersionOverrideFinder` find invalid
-/// Dart language version override comments in Dart code.
-class InvalidLanguageVersionOverrideFinder {
- /// The error reporter by which invalid Dart language version override
- /// comments will be reported.
+/// Finds invalid, or misplaced language override comments.
+class LanguageVersionOverrideVerifier {
+ static final _overrideCommentLine = RegExp(r'^\s*//\s*@dart\s*=\s*\d+\.\d+');
+
final ErrorReporter _errorReporter;
- /// Initialize a finder to report invalid Dart language version override
- /// comments to the given reporter.
- InvalidLanguageVersionOverrideFinder(this._errorReporter);
+ LanguageVersionOverrideVerifier(this._errorReporter);
- /// Search the comments at the top of the given compilation unit for language
- /// version override comments and report an error for each.
- void findIn(CompilationUnit unit) {
+ void verify(CompilationUnit unit) {
+ _verifyMisplaced(unit);
+
Token beginToken = unit.beginToken;
if (beginToken.type == TokenType.SCRIPT_TAG) {
beginToken = beginToken.next;
@@ -266,4 +263,42 @@
length);
return false;
}
+
+ /// Verify that all language version overrides are before declarations.
+ void _verifyMisplaced(CompilationUnit unit) {
+ Token firstMeaningfulToken;
+ if (unit.directives.isNotEmpty) {
+ firstMeaningfulToken = unit.directives.first.beginToken;
+ } else if (unit.declarations.isNotEmpty) {
+ firstMeaningfulToken = unit.declarations.first.beginToken;
+ } else {
+ return;
+ }
+
+ var token = firstMeaningfulToken.next;
+ while (token != null) {
+ if (token.offset > firstMeaningfulToken.offset) {
+ var commentToken = token.precedingComments;
+ for (; commentToken != null; commentToken = commentToken.next) {
+ var lexeme = commentToken.lexeme;
+
+ var match = _overrideCommentLine.firstMatch(lexeme);
+ if (match != null) {
+ var atDartStart = lexeme.indexOf('@dart');
+ _errorReporter.reportErrorForOffset(
+ HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION,
+ commentToken.offset + atDartStart,
+ match.end - atDartStart,
+ );
+ }
+ }
+ }
+
+ if (token.next == token) {
+ break;
+ } else {
+ token = token.next;
+ }
+ }
+ }
}
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
index d6090cc..fcf6977 100644
--- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart
+++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -142,6 +142,8 @@
return;
}
+ expressionType = typeSystem.resolveToBound(expressionType);
+
InterfaceType iterableType;
if (expressionType is InterfaceTypeImpl) {
iterableType = expressionType.asInstanceOf(typeProvider.iterableElement);
@@ -183,6 +185,8 @@
return;
}
+ expressionType = typeSystem.resolveToBound(expressionType);
+
InterfaceType mapType;
if (expressionType is InterfaceTypeImpl) {
mapType = expressionType.asInstanceOf(typeProvider.mapElement);
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index c43623c..41ff1ec 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -2688,7 +2688,7 @@
}
} else if (context == IdentifierContext.enumValueDeclaration) {
List<Annotation> metadata = pop();
- Comment comment = _findComment(null, token);
+ Comment comment = _findComment(metadata, token);
push(ast.enumConstantDeclaration(comment, metadata, identifier));
} else {
push(identifier);
@@ -3444,6 +3444,19 @@
}
@override
+ void handleVoidKeywordWithTypeArguments(Token voidKeyword) {
+ assert(optional('void', voidKeyword));
+ debugEvent("VoidKeywordWithTypeArguments");
+ TypeArgumentList arguments = pop();
+
+ // TODO(paulberry): is this sufficient, or do we need to hook the "void"
+ // keyword up to an element?
+ handleIdentifier(voidKeyword, IdentifierContext.typeReference);
+ push(arguments);
+ handleType(voidKeyword, null);
+ }
+
+ @override
dynamic internalProblem(Message message, int charOffset, Uri uri) {
throw UnsupportedError(message.message);
}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index c5bee2a..9b8c2980 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -111,9 +111,6 @@
/// The long suffix used for HTML files.
static const String SUFFIX_HTML = "html";
- /// The deprecated file name used for analysis options files.
- static const String ANALYSIS_OPTIONS_FILE = '.analysis_options';
-
/// The file name used for analysis options files.
static const String ANALYSIS_OPTIONS_YAML_FILE = 'analysis_options.yaml';
@@ -166,8 +163,7 @@
return false;
}
String basename = (context ?? pathos.posix).basename(fileName);
- return basename == ANALYSIS_OPTIONS_FILE ||
- basename == ANALYSIS_OPTIONS_YAML_FILE;
+ return basename == ANALYSIS_OPTIONS_YAML_FILE;
}
/// Return `true` if the given [fileName] is assumed to contain Dart source
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 9297721..82d2949 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2399,9 +2399,6 @@
}
DartType iterableType = getStaticType(node.iterable);
- if (iterableType.isDynamic) {
- return false;
- }
// TODO(scheglov) use NullableDereferenceVerifier
if (_isNonNullableByDefault) {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index ab1a3b7..25334ed 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1106,7 +1106,7 @@
if (_flowAnalysis != null) {
if (!isFunctionDeclaration) {
- _flowAnalysis.flow.functionExpression_begin(node);
+ _flowAnalysis.executableDeclaration_enter(node, node.parameters, true);
}
} else {
_promoteManager.enterFunctionBody(body);
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 3f12d2d..60443f8 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -649,6 +649,9 @@
var constraints = this.constraints[t2.element];
if (constraints != null) {
if (!identical(t1, UnknownInferredType.instance)) {
+ if (t2.nullabilitySuffix == NullabilitySuffix.question) {
+ t1 = _typeSystem.promoteToNonNull(t1);
+ }
var constraint = _TypeConstraint(origin, t2.element, lower: t1);
constraints.add(constraint);
_undoBuffer.add(constraint);
@@ -1799,6 +1802,57 @@
}
}
+ /// Defines the "remainder" of `T` when `S` has been removed from
+ /// consideration by an instance check. This operation is used for type
+ /// promotion during flow analysis.
+ DartType factor(DartType T, DartType S) {
+ // * If T <: S then Never
+ if (isSubtypeOf2(T, S)) {
+ return NeverTypeImpl.instance;
+ }
+
+ var T_nullability = T.nullabilitySuffix;
+
+ // * Else if T is R? and Null <: S then factor(R, S)
+ // * Else if T is R? then factor(R, S)?
+ if (T_nullability == NullabilitySuffix.question) {
+ var R = (T as TypeImpl).withNullability(NullabilitySuffix.none);
+ var factor_RS = factor(R, S) as TypeImpl;
+ if (isSubtypeOf2(nullNone, S)) {
+ return factor_RS;
+ } else {
+ return factor_RS.withNullability(NullabilitySuffix.question);
+ }
+ }
+
+ // * Else if T is R* and Null <: S then factor(R, S)
+ // * Else if T is R* then factor(R, S)*
+ if (T_nullability == NullabilitySuffix.star) {
+ var R = (T as TypeImpl).withNullability(NullabilitySuffix.none);
+ var factor_RS = factor(R, S) as TypeImpl;
+ if (isSubtypeOf2(nullNone, S)) {
+ return factor_RS;
+ } else {
+ return factor_RS.withNullability(NullabilitySuffix.star);
+ }
+ }
+
+ // * Else if T is FutureOr<R> and Future<R> <: S then factor(R, S)
+ // * Else if T is FutureOr<R> and R <: S then factor(Future<R>, S)
+ if (T is InterfaceType && T.isDartAsyncFutureOr) {
+ var R = T.typeArguments[0];
+ var future_R = typeProvider.futureType2(R);
+ if (isSubtypeOf2(future_R, S)) {
+ return factor(R, S);
+ }
+ if (isSubtypeOf2(R, S)) {
+ return factor(future_R, S);
+ }
+ }
+
+ return T;
+ }
+
/// Given a type t, if t is an interface type with a call method
/// defined, return the function type for the call method, otherwise
/// return null.
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index 49536c7..b0e1884 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -272,7 +272,9 @@
}
@override
- void logException(dynamic exception, [StackTrace stackTrace]) {
+ void logException(dynamic exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]) {
errorSink.writeln(exception);
errorSink.writeln(stackTrace);
}
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 4d38811..8d3f33e 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -431,14 +431,6 @@
source,
isNonNullableByDefault: false,
);
- if (AnalysisEngine.ANALYSIS_OPTIONS_FILE == source.shortName) {
- reporter.reportError(AnalysisError(
- source,
- 0, // offset
- 1, // length
- AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME,
- [source.shortName]));
- }
_validators.forEach((OptionsValidator v) => v.validate(reporter, options));
return recorder.errors;
}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index a2efa50..46e0226 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -17267,6 +17267,20 @@
expectCommentText(value.documentationComment, '/// Doc');
}
+ void test_parseEnumDeclaration_withDocComment_onValue_annotated() {
+ createParser('''
+enum E {
+ /// Doc
+ @annotation
+ ONE
+}
+''');
+ var declaration = parseFullCompilationUnitMember() as EnumDeclaration;
+ var value = declaration.constants[0];
+ expectCommentText(value.documentationComment, '/// Doc');
+ expect(value.metadata, hasLength(1));
+ }
+
void test_parseExportDirective_configuration_multiple() {
createParser("export 'lib/lib.dart' if (a) 'b.dart' if (c) 'd.dart';");
ExportDirective directive = parseFullDirective();
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index c73ec4b..028096c 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -394,7 +394,9 @@
}
@override
- void logException(dynamic exception, [StackTrace stackTrace]) {
+ void logException(dynamic exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]) {
log.add("error: $exception $stackTrace");
}
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index e2e68d6..9e4eb9a 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -20,8 +20,7 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(AnalysisOptionsProviderOldTest);
- defineReflectiveTests(AnalysisOptionsProviderNewTest);
+ defineReflectiveTests(AnalysisOptionsProviderTest);
});
group('AnalysisOptionsProvider', () {
void expectMergesTo(String defaults, String overrides, String expected) {
@@ -101,24 +100,13 @@
}
@reflectiveTest
-class AnalysisOptionsProviderNewTest extends AnalysisOptionsProviderTest {
- @override
- String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
-}
-
-@reflectiveTest
-class AnalysisOptionsProviderOldTest extends AnalysisOptionsProviderTest {
- @override
- String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_FILE;
-}
-
-abstract class AnalysisOptionsProviderTest {
+class AnalysisOptionsProviderTest {
TestPathTranslator pathTranslator;
ResourceProvider resourceProvider;
AnalysisOptionsProvider provider;
- String get optionsFileName;
+ String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
void setUp() {
var rawProvider = MemoryResourceProvider();
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 7e58e58..28a121a 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -796,17 +796,6 @@
expect(result.path, filePath);
}
- void test_getOptionsFile_inParentOfRoot_old() {
- String parentPath = convertPath('/some/directory');
- String path = join(parentPath, 'path');
- String filePath = join(parentPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE);
- newFile(filePath);
-
- File result = builder.getOptionsFile(path);
- expect(result, isNotNull);
- expect(result.path, filePath);
- }
-
void test_getOptionsFile_inRoot_new() {
String path = convertPath('/some/directory/path');
String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
@@ -817,16 +806,6 @@
expect(result.path, filePath);
}
- void test_getOptionsFile_inRoot_old() {
- String path = convertPath('/some/directory/path');
- String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_FILE);
- newFile(filePath);
-
- File result = builder.getOptionsFile(path);
- expect(result, isNotNull);
- expect(result.path, filePath);
- }
-
void _assertPackages(Packages packages, Map<String, String> nameToPath) {
expect(packages, isNotNull);
expect(packages.packages, hasLength(nameToPath.length));
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 1d99fe9..a4f0f10 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -3073,7 +3073,7 @@
if (allExceptions.isNotEmpty) {
var buffer = StringBuffer();
for (var exception in allExceptions) {
- buffer.writeln('Path: ${exception.path}');
+ buffer.writeln('Path: ${exception.filePath}');
buffer.writeln('Exception: ${exception.exception}');
}
fail('Unexpected exceptions:\n$buffer');
diff --git a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
index 7fa6a02..901f3b1 100644
--- a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
@@ -35,124 +35,114 @@
_createSourceFactory();
}
- test_jsonConfig_defaultNonNullable() {
- var jsonConfigPath = '/test/.dart_tool/package_config.json';
- var jsonConfigFile = newFile(jsonConfigPath, content: '''
-{
- "configVersion": 2,
- "packages": [
- {
- "name": "test",
- "rootUri": "../",
- "packageUri": "lib/"
- },
- {
- "name": "aaa",
- "rootUri": "${toUriStr('/packages/aaa')}",
- "packageUri": "lib/",
- "languageVersion": "2.7"
- },
- {
- "name": "bbb",
- "rootUri": "${toUriStr('/packages/bbb')}",
- "packageUri": "lib/"
- }
- ]
-}
-''');
-
- var packages = parsePackageConfigJsonFile(
- resourceProvider,
- jsonConfigFile,
+ test_packages() {
+ var packages = Packages(
+ {
+ 'aaa': Package(
+ name: 'aaa',
+ rootFolder: newFolder('/packages/aaa'),
+ libFolder: newFolder('/packages/aaa/lib'),
+ languageVersion: null,
+ ),
+ 'bbb': Package(
+ name: 'bbb',
+ rootFolder: newFolder('/packages/bbb'),
+ libFolder: newFolder('/packages/bbb/lib'),
+ languageVersion: Version(2, 7, 0),
+ ),
+ 'ccc': Package(
+ name: 'ccc',
+ rootFolder: newFolder('/packages/ccc'),
+ libFolder: newFolder('/packages/ccc/lib'),
+ languageVersion: Version(2, 8, 0),
+ ),
+ },
);
+
_createSourceFactory(
packageUriResolver: _createPackageMapUriResolver(packages),
);
- _simulateNonNullableSdk();
- _buildProvider(['non-nullable']);
-
- _assertNonNullableForPath('/test/a.dart', true);
- _assertNonNullableForPath('/test/lib/b.dart', true);
- _assertNonNullableForPath('/test/test/c.dart', true);
+ provider = FeatureSetProvider.build(
+ resourceProvider: resourceProvider,
+ packages: packages,
+ packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ );
_assertNonNullableForPath('/packages/aaa/a.dart', false);
_assertNonNullableForPath('/packages/aaa/lib/b.dart', false);
_assertNonNullableForPath('/packages/aaa/test/c.dart', false);
- _assertNonNullableForPath('/packages/bbb/a.dart', true);
- _assertNonNullableForPath('/packages/bbb/lib/b.dart', true);
- _assertNonNullableForPath('/packages/bbb/test/c.dart', true);
+ _assertNonNullableForPath('/packages/bbb/a.dart', false);
+ _assertNonNullableForPath('/packages/bbb/lib/b.dart', false);
+ _assertNonNullableForPath('/packages/bbb/test/c.dart', false);
- _assertNonNullableForPath('/other/file.dart', true);
+ _assertNonNullableForPath('/packages/ccc/a.dart', false);
+ _assertNonNullableForPath('/packages/ccc/lib/b.dart', false);
+ _assertNonNullableForPath('/packages/ccc/test/c.dart', false);
+
+ _assertNonNullableForPath('/other/file.dart', false);
}
- test_nonPackageDefaultFeatureSet() {
- newFile('/test/.packages', content: '''
-test:lib/
-''');
- _simulateNonNullableSdk();
- _buildProvider(['non-nullable']);
+ test_packages_enabledExperiment_nonNullable() {
+ var packages = Packages(
+ {
+ 'aaa': Package(
+ name: 'aaa',
+ rootFolder: newFolder('/packages/aaa'),
+ libFolder: newFolder('/packages/aaa/lib'),
+ languageVersion: null,
+ ),
+ 'bbb': Package(
+ name: 'bbb',
+ rootFolder: newFolder('/packages/bbb'),
+ libFolder: newFolder('/packages/bbb/lib'),
+ languageVersion: Version(2, 7, 0),
+ ),
+ 'ccc': Package(
+ name: 'ccc',
+ rootFolder: newFolder('/packages/ccc'),
+ libFolder: newFolder('/packages/ccc/lib'),
+ languageVersion: Version(2, 8, 0),
+ ),
+ },
+ );
+
+ _createSourceFactory(
+ packageUriResolver: _createPackageMapUriResolver(packages),
+ );
provider = FeatureSetProvider.build(
resourceProvider: resourceProvider,
- packages: Packages(
- {
- 'aaa': Package(
- name: 'aaa',
- rootFolder: newFolder('/packages/aaa'),
- libFolder: newFolder('/packages/aaa/lib'),
- languageVersion: null,
- ),
- 'bbb': Package(
- name: 'bbb',
- rootFolder: newFolder('/packages/bbb'),
- libFolder: newFolder('/packages/bbb/lib'),
- languageVersion: Version(2, 7, 0),
- ),
- },
- ),
- sourceFactory: sourceFactory,
+ packages: packages,
packageDefaultFeatureSet: FeatureSet.fromEnableFlags(['non-nullable']),
nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
);
- _assertNonNullableForPath('/packages/aaa/lib/a.dart', true);
- _assertNonNullableForPath('/packages/aaa/test/b.dart', true);
+ _assertNonNullableForPath('/packages/aaa/a.dart', true);
+ _assertNonNullableForPath('/packages/aaa/lib/b.dart', true);
+ _assertNonNullableForPath('/packages/aaa/test/c.dart', true);
- _assertNonNullableForPath('/packages/bbb/lib/a.dart', false);
- _assertNonNullableForPath('/packages/bbb/test/b.dart', false);
+ _assertNonNullableForPath('/packages/bbb/a.dart', false);
+ _assertNonNullableForPath('/packages/bbb/lib/b.dart', false);
+ _assertNonNullableForPath('/packages/bbb/test/c.dart', false);
- _assertNonNullableForPath('/foo/bar.dart', false);
+ _assertNonNullableForPath('/packages/ccc/a.dart', true);
+ _assertNonNullableForPath('/packages/ccc/lib/b.dart', true);
+ _assertNonNullableForPath('/packages/ccc/test/c.dart', true);
+
+ _assertNonNullableForPath('/other/file.dart', false);
}
- test_sdk_defaultLegacy_sdkLegacy() {
- newFile('/test/.packages', content: '''
-test:lib/
-''');
- _simulateLegacySdk();
+ test_sdk() {
_buildProvider([]);
var featureSet = _getSdkFeatureSet();
expect(featureSet.isEnabled(Feature.non_nullable), isTrue);
}
- test_sdk_defaultNonNullable_sdkLegacy() {
- newFile('/test/.packages', content: '''
-test:lib/
-''');
- _simulateLegacySdk();
- _buildProvider(['non-nullable']);
-
- var featureSet = _getSdkFeatureSet();
- expect(featureSet.isEnabled(Feature.non_nullable), isTrue);
- }
-
- test_sdk_defaultNonNullable_sdkNonNullable() {
- newFile('/test/.packages', content: '''
-test:lib/
-''');
- _simulateNonNullableSdk();
+ test_sdk_enabledExperiment_nonNullable() {
_buildProvider(['non-nullable']);
var featureSet = _getSdkFeatureSet();
@@ -169,7 +159,6 @@
provider = FeatureSetProvider.build(
resourceProvider: resourceProvider,
packages: findPackagesFrom(resourceProvider, getFolder('/test')),
- sourceFactory: sourceFactory,
packageDefaultFeatureSet: featureSet,
nonPackageDefaultFeatureSet: featureSet,
);
@@ -208,17 +197,4 @@
var mathPath = sourceFactory.forUri2(mathUri).fullName;
return provider.getFeatureSet(mathPath, mathUri);
}
-
- void _replaceDartCoreObject(String content) {
- var path = sourceFactory.forUri('dart:core').fullName;
- newFile(path, content: content);
- }
-
- void _simulateLegacySdk() {
- _replaceDartCoreObject('// no marker');
- }
-
- void _simulateNonNullableSdk() {
- _replaceDartCoreObject('// bool operator ==(Object other)');
- }
}
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index c2bdaeb..07a09ca 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -63,7 +63,6 @@
var featureSetProvider = FeatureSetProvider.build(
resourceProvider: resourceProvider,
packages: Packages.empty,
- sourceFactory: sourceFactory,
packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
);
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index c5bc120..12ddb58 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -906,18 +906,27 @@
assertThat(element)..isReferencedAt('p: 1', true);
}
- test_isReferencedBy_ParameterElement_named_ofMethod_genericClass() async {
+ test_isReferencedBy_ParameterElement_genericFunctionType() async {
await _indexTestUnit('''
-class A<T> {
- void foo({T test}) {}
-}
+typedef F = void Function({int p});
-main(A<int> a) {
- a.foo(test: 0);
+void main(F f) {
+ f(p: 0);
}
''');
- Element element = findElement('test');
- assertThat(element)..isReferencedAt('test: 0', true);
+ // We should not crash because of reference to "p" - a named parameter
+ // of a generic function type.
+ }
+
+ test_isReferencedBy_ParameterElement_genericFunctionType_call() async {
+ await _indexTestUnit('''
+typedef F<T> = void Function({T test});
+
+main(F<int> f) {
+ f.call(test: 0);
+}
+''');
+ // No exceptions.
}
test_isReferencedBy_ParameterElement_named_ofConstructor_genericClass() async {
@@ -934,17 +943,18 @@
assertThat(element)..isReferencedAt('test: 0', true);
}
- test_isReferencedBy_ParameterElement_genericFunctionType() async {
+ test_isReferencedBy_ParameterElement_named_ofMethod_genericClass() async {
await _indexTestUnit('''
-typedef F = void Function({int p});
+class A<T> {
+ void foo({T test}) {}
+}
-void main() {
- F f;
- f(p: 0);
+main(A<int> a) {
+ a.foo(test: 0);
}
''');
- // We should not crash because of reference to "p" - a named parameter
- // of a generic function type.
+ Element element = findElement('test');
+ assertThat(element)..isReferencedAt('test: 0', true);
}
test_isReferencedBy_ParameterElement_optionalPositional() async {
diff --git a/pkg/analyzer/test/src/dart/element/factor_type_test.dart b/pkg/analyzer/test/src/dart/element/factor_type_test.dart
new file mode 100644
index 0000000..111da27
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/factor_type_test.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/elements_types_mixin.dart';
+import '../../../generated/test_analysis_context.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FactorTypeTest);
+ });
+}
+
+@reflectiveTest
+class FactorTypeTest with ElementsTypesMixin {
+ @override
+ TypeProvider typeProvider;
+
+ TypeSystemImpl typeSystem;
+
+ FeatureSet get testFeatureSet {
+ return FeatureSet.forTesting(
+ additionalFeatures: [Feature.non_nullable],
+ );
+ }
+
+ void setUp() {
+ var analysisContext = TestAnalysisContext(
+ featureSet: testFeatureSet,
+ );
+ typeProvider = analysisContext.typeProviderNonNullableByDefault;
+ typeSystem = analysisContext.typeSystemNonNullableByDefault;
+ }
+
+ void test_futureOr() {
+ _check(futureOrNone(intNone), intNone, 'Future<int>');
+ _check(futureOrNone(intNone), futureNone(intNone), 'int');
+
+ _check(futureOrNone(intQuestion), intNone, 'FutureOr<int?>');
+ _check(futureOrNone(intQuestion), futureNone(intNone), 'FutureOr<int?>');
+ _check(futureOrNone(intQuestion), intQuestion, 'Future<int?>');
+ _check(futureOrNone(intQuestion), futureNone(intQuestion), 'int?');
+ _check(futureOrNone(intQuestion), intStar, 'Future<int?>');
+ _check(futureOrNone(intQuestion), futureNone(intStar), 'int?');
+
+ _check(futureOrNone(intNone), numNone, 'Future<int>');
+ _check(futureOrNone(intNone), futureNone(numNone), 'int');
+ }
+
+ void test_object() {
+ _check(objectNone, objectNone, 'Never');
+ _check(objectNone, objectQuestion, 'Never');
+ _check(objectNone, objectStar, 'Never');
+
+ _check(objectNone, intNone, 'Object');
+ _check(objectNone, intQuestion, 'Object');
+ _check(objectNone, intStar, 'Object');
+
+ _check(objectQuestion, objectNone, 'Never?');
+ _check(objectQuestion, objectQuestion, 'Never');
+ _check(objectQuestion, objectStar, 'Never');
+
+ _check(objectQuestion, intNone, 'Object?');
+ _check(objectQuestion, intQuestion, 'Object');
+ _check(objectQuestion, intStar, 'Object');
+ }
+
+ test_subtype() {
+ _check(intNone, intNone, 'Never');
+ _check(intNone, intQuestion, 'Never');
+ _check(intNone, intStar, 'Never');
+
+ _check(intQuestion, intNone, 'Never?');
+ _check(intQuestion, intQuestion, 'Never');
+ _check(intQuestion, intStar, 'Never');
+
+ _check(intStar, intNone, 'Never');
+ _check(intStar, intQuestion, 'Never');
+ _check(intStar, intStar, 'Never');
+
+ _check(intNone, numNone, 'Never');
+ _check(intNone, numQuestion, 'Never');
+ _check(intNone, numStar, 'Never');
+
+ _check(intQuestion, numNone, 'Never?');
+ _check(intQuestion, numQuestion, 'Never');
+ _check(intQuestion, numStar, 'Never');
+
+ _check(intStar, numNone, 'Never');
+ _check(intStar, numQuestion, 'Never');
+ _check(intStar, numStar, 'Never');
+
+ _check(intNone, nullNone, 'int');
+ _check(intQuestion, nullNone, 'int');
+ _check(intStar, nullNone, 'int');
+
+ _check(intNone, stringNone, 'int');
+ _check(intQuestion, stringNone, 'int?');
+ _check(intStar, stringNone, 'int*');
+
+ _check(intNone, stringQuestion, 'int');
+ _check(intQuestion, stringQuestion, 'int');
+ _check(intStar, stringQuestion, 'int');
+
+ _check(intNone, stringStar, 'int');
+ _check(intQuestion, stringStar, 'int');
+ _check(intStar, stringStar, 'int');
+ }
+
+ void _check(DartType T, DartType S, String expectedStr) {
+ var result = typeSystem.factor(T, S);
+ var resultStr = _typeString(result);
+
+ expect(resultStr, expectedStr);
+ }
+
+ String _typeString(TypeImpl type) {
+ return type.getDisplayString(withNullability: true);
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index 14790a0..8a98bd6 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -5,6 +5,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'element_test.dart' as element;
+import 'factor_type_test.dart' as factor_type;
import 'function_type_test.dart' as function_type;
import 'inheritance_manager3_test.dart' as inheritance_manager3;
import 'least_upper_bound_helper_test.dart' as least_upper_bound_helper;
@@ -23,6 +24,7 @@
main() {
defineReflectiveSuite(() {
element.main();
+ factor_type.main();
function_type.main();
inheritance_manager3.main();
least_upper_bound_helper.main();
diff --git a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
index 51e24c3..7d0756e 100644
--- a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
@@ -32,13 +32,16 @@
var indexElement = findElement.method('[]');
var indexExpression = findNode.index('a[0]');
- assertElement(indexExpression, indexElement);
- assertAuxElement(indexExpression, null);
+ assertIndexExpression(
+ indexExpression,
+ readElement: indexElement,
+ writeElement: null,
+ type: 'bool',
+ );
assertParameterElement(
indexExpression.index,
indexElement.parameters[0],
);
- assertType(indexExpression, 'bool');
}
test_read_generic() async {
@@ -55,13 +58,19 @@
var indexElement = findElement.method('[]');
var indexExpression = findNode.index('a[0]');
- assertMember(indexExpression, indexElement, {'T': 'double'});
- assertAuxElement(indexExpression, null);
+ assertIndexExpression(
+ indexExpression,
+ readElement: elementMatcher(
+ indexElement,
+ substitution: {'T': 'double'},
+ ),
+ writeElement: null,
+ type: 'double',
+ );
assertParameterElement(
indexExpression.index,
indexElement.parameters[0],
);
- assertType(indexExpression, 'double');
}
test_readWrite() async {
@@ -81,23 +90,26 @@
var numPlusElement = numElement.getMethod('+');
var indexExpression = findNode.index('a[0]');
- assertElement(indexExpression, indexEqElement);
- assertAuxElement(indexExpression, indexElement);
+ assertIndexExpression(
+ indexExpression,
+ readElement: indexElement,
+ writeElement: indexEqElement,
+ type: 'num',
+ );
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
- assertType(indexExpression, 'num');
var assignment = indexExpression.parent as AssignmentExpression;
- assertElement(
+ assertAssignment(
assignment,
- elementMatcher(
+ operatorElement: elementMatcher(
numPlusElement,
isLegacy: isNullSafetySdkAndLegacyLibrary,
),
+ type: 'num',
);
- assertType(assignment, 'num');
assertParameterElement(
assignment.rightHandSide,
numPlusElement.parameters[0],
@@ -121,23 +133,32 @@
var doublePlusElement = doubleElement.getMethod('+');
var indexExpression = findNode.index('a[0]');
- assertMember(indexExpression, indexEqElement, {'T': 'double'});
- assertAuxMember(indexExpression, indexElement, {'T': 'double'});
+ assertIndexExpression(
+ indexExpression,
+ readElement: elementMatcher(
+ indexElement,
+ substitution: {'T': 'double'},
+ ),
+ writeElement: elementMatcher(
+ indexEqElement,
+ substitution: {'T': 'double'},
+ ),
+ type: 'double',
+ );
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
- assertType(indexExpression, 'double');
var assignment = indexExpression.parent as AssignmentExpression;
- assertElement(
+ assertAssignment(
assignment,
- elementMatcher(
+ operatorElement: elementMatcher(
doublePlusElement,
isLegacy: isNullSafetySdkAndLegacyLibrary,
),
+ type: 'double',
);
- assertType(assignment, 'double');
assertParameterElement(
assignment.rightHandSide,
doublePlusElement.parameters[0],
@@ -158,17 +179,23 @@
var indexEqElement = findElement.method('[]=');
var indexExpression = findNode.index('a[0]');
- assertElement(indexExpression, indexEqElement);
- assertAuxElement(indexExpression, null);
+ assertIndexExpression(
+ indexExpression,
+ readElement: null,
+ writeElement: indexEqElement,
+ type: null,
+ );
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
- assertType(indexExpression, 'num');
var assignment = indexExpression.parent as AssignmentExpression;
- assertElement(assignment, null);
- assertType(assignment, 'double');
+ assertAssignment(
+ assignment,
+ operatorElement: null,
+ type: 'double',
+ );
assertParameterElement(assignment.rightHandSide, null);
}
@@ -186,17 +213,26 @@
var indexEqElement = findElement.method('[]=');
var indexExpression = findNode.index('a[0]');
- assertMember(indexExpression, indexEqElement, {'T': 'double'});
- assertAuxElement(indexExpression, null);
+ assertIndexExpression(
+ indexExpression,
+ readElement: null,
+ writeElement: elementMatcher(
+ indexEqElement,
+ substitution: {'T': 'double'},
+ ),
+ type: null,
+ );
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
- assertType(indexExpression, 'double');
var assignment = indexExpression.parent as AssignmentExpression;
- assertElement(assignment, null);
- assertType(assignment, 'double');
+ assertAssignment(
+ assignment,
+ operatorElement: null,
+ type: 'double',
+ );
assertParameterElement(assignment.rightHandSide, null);
}
}
@@ -211,6 +247,27 @@
@override
bool get typeToStringWithNullability => true;
+ test_cascade_read_nullable() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ bool operator[](int index) => false;
+}
+
+main(A? a) {
+ a?..[0];
+}
+''');
+
+ var indexElement = findElement.method('[]');
+
+ assertIndexExpression(
+ findNode.index('..[0]'),
+ readElement: indexElement,
+ writeElement: null,
+ type: 'bool?',
+ );
+ }
+
test_read_nullable() async {
await assertNoErrorsInCode(r'''
class A {
@@ -218,6 +275,28 @@
}
main(A? a) {
+ a?[0];
+}
+''');
+
+ var indexElement = findElement.method('[]');
+
+ var indexExpression = findNode.index('a?[0]');
+ assertIndexExpression(
+ indexExpression,
+ readElement: indexElement,
+ writeElement: null,
+ type: 'bool?',
+ );
+ }
+
+ test_read_nullable_questionDotIndex() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ bool operator[](int index) => false;
+}
+
+main(A? a) {
a?.[0];
}
''');
@@ -225,9 +304,12 @@
var indexElement = findElement.method('[]');
var indexExpression = findNode.index('a?.[0]');
- assertElement(indexExpression, indexElement);
- assertAuxElement(indexExpression, null);
- assertType(indexExpression, 'bool?');
+ assertIndexExpression(
+ indexExpression,
+ readElement: indexElement,
+ writeElement: null,
+ type: 'bool?',
+ );
}
test_readWrite_nullable() async {
@@ -238,6 +320,46 @@
}
main(A? a) {
+ a?[0] += 1.2;
+}
+''');
+
+ var indexElement = findElement.method('[]');
+ var indexEqElement = findElement.method('[]=');
+ var numPlusElement = numElement.getMethod('+');
+
+ var indexExpression = findNode.index('a?[0]');
+ assertIndexExpression(
+ indexExpression,
+ readElement: indexElement,
+ writeElement: indexEqElement,
+ type: 'num',
+ );
+ assertParameterElement(
+ indexExpression.index,
+ indexEqElement.parameters[0],
+ );
+
+ var assignment = indexExpression.parent as AssignmentExpression;
+ assertAssignment(
+ assignment,
+ operatorElement: numPlusElement,
+ type: 'num?',
+ );
+ assertParameterElement(
+ assignment.rightHandSide,
+ numPlusElement.parameters[0],
+ );
+ }
+
+ test_readWrite_nullable_questionDotIndex() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ num operator[](int index) => 0;
+ void operator[]=(int index, num value) {}
+}
+
+main(A? a) {
a?.[0] += 1.2;
}
''');
@@ -247,17 +369,23 @@
var numPlusElement = numElement.getMethod('+');
var indexExpression = findNode.index('a?.[0]');
- assertElement(indexExpression, indexEqElement);
- assertAuxElement(indexExpression, indexElement);
+ assertIndexExpression(
+ indexExpression,
+ readElement: indexElement,
+ writeElement: indexEqElement,
+ type: 'num',
+ );
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
- assertType(indexExpression, 'num');
var assignment = indexExpression.parent as AssignmentExpression;
- assertElement(assignment, numPlusElement);
- assertType(assignment, 'num?');
+ assertAssignment(
+ assignment,
+ operatorElement: numPlusElement,
+ type: 'num?',
+ );
assertParameterElement(
assignment.rightHandSide,
numPlusElement.parameters[0],
@@ -271,6 +399,40 @@
}
main(A? a) {
+ a?[0] = 1.2;
+}
+''');
+
+ var indexEqElement = findElement.method('[]=');
+
+ var indexExpression = findNode.index('a?[0]');
+ assertIndexExpression(
+ indexExpression,
+ readElement: null,
+ writeElement: indexEqElement,
+ type: null,
+ );
+ assertParameterElement(
+ indexExpression.index,
+ indexEqElement.parameters[0],
+ );
+
+ var assignment = indexExpression.parent as AssignmentExpression;
+ assertAssignment(
+ assignment,
+ operatorElement: null,
+ type: 'double?',
+ );
+ assertParameterElement(assignment.rightHandSide, null);
+ }
+
+ test_write_nullable_questionDotIndex() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ void operator[]=(int index, num value) {}
+}
+
+main(A? a) {
a?.[0] = 1.2;
}
''');
@@ -278,17 +440,23 @@
var indexEqElement = findElement.method('[]=');
var indexExpression = findNode.index('a?.[0]');
- assertElement(indexExpression, indexEqElement);
- assertAuxElement(indexExpression, null);
+ assertIndexExpression(
+ indexExpression,
+ readElement: null,
+ writeElement: indexEqElement,
+ type: null,
+ );
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
- assertType(indexExpression, 'num');
var assignment = indexExpression.parent as AssignmentExpression;
- assertElement(assignment, null);
- assertType(assignment, 'double?');
+ assertAssignment(
+ assignment,
+ operatorElement: null,
+ type: 'double?',
+ );
assertParameterElement(assignment.rightHandSide, null);
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index c26a4ee..17fa5b2 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -1702,6 +1702,9 @@
[EnableString.non_nullable],
);
+ @override
+ bool get typeToStringWithNullability => true;
+
test_hasReceiver_deferredImportPrefix_loadLibrary_optIn_fromOptOut() async {
newFile('/test/lib/a.dart', content: r'''
class A {}
@@ -1724,7 +1727,7 @@
assertMethodInvocation(
invocation,
import.importedLibrary.loadLibraryFunction,
- 'Future<dynamic> Function()',
+ 'Future<dynamic>* Function()*',
);
}
@@ -1834,6 +1837,29 @@
);
}
+ test_hasReceiver_interfaceTypeQ_defined_extensionQ2() async {
+ await assertNoErrorsInCode(r'''
+extension E<T> on T? {
+ T foo() => throw 0;
+}
+
+main(int? a) {
+ a.foo();
+}
+''');
+
+ assertMethodInvocation2(
+ findNode.methodInvocation('a.foo()'),
+ element: elementMatcher(
+ findElement.method('foo', of: 'E'),
+ substitution: {'T': 'int'},
+ ),
+ typeArgumentTypes: [],
+ invokeType: 'int Function()',
+ type: 'int',
+ );
+ }
+
test_hasReceiver_interfaceTypeQ_notDefined() async {
await assertErrorsInCode(r'''
class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index be19ec4..0a7b1c4 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -94,10 +94,10 @@
void assertAssignment(
AssignmentExpression node, {
- @required ExecutableElement operatorElement,
+ @required Object operatorElement,
@required String type,
}) {
- expect(node.staticElement, same(operatorElement));
+ assertElement(node.staticElement, operatorElement);
assertType(node, type);
}
@@ -304,22 +304,29 @@
void assertIndexExpression(
IndexExpression node, {
- @required MethodElement readElement,
- @required MethodElement writeElement,
+ @required Object readElement,
+ @required Object writeElement,
@required String type,
}) {
var isRead = node.inGetterContext();
var isWrite = node.inSetterContext();
if (isRead && isWrite) {
- expect(node.auxiliaryElements?.staticElement, readElement);
- expect(node.staticElement, writeElement);
+ assertElement(node.auxiliaryElements?.staticElement, readElement);
+ assertElement(node.staticElement, writeElement);
} else if (isRead) {
- expect(node.staticElement, readElement);
+ assertElement(node.staticElement, readElement);
} else {
expect(isWrite, isTrue);
- expect(node.staticElement, writeElement);
+ assertElement(node.staticElement, writeElement);
}
- assertType(node, type);
+
+ if (isRead) {
+ assertType(node, type);
+ } else {
+ // TODO(scheglov) enforce this
+// expect(type, isNull);
+// assertTypeNull(node);
+ }
}
void assertInstanceCreation(InstanceCreationExpression creation,
@@ -447,7 +454,7 @@
void assertMethodInvocation2(
MethodInvocation node, {
- @required ExecutableElement element,
+ @required Object element,
@required List<String> typeArgumentTypes,
@required String invokeType,
@required String type,
diff --git a/pkg/analyzer/test/src/diagnostics/equal_elements_in_const_set_test.dart b/pkg/analyzer/test/src/diagnostics/equal_elements_in_const_set_test.dart
index 56e5f2b..69b5728 100644
--- a/pkg/analyzer/test/src/diagnostics/equal_elements_in_const_set_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/equal_elements_in_const_set_test.dart
@@ -177,9 +177,12 @@
}
test_nonConst_entry() async {
- await assertNoErrorsInCode('''
+ // No error, but there is a hint.
+ await assertErrorsInCode('''
var c = {1, 2, 1};
-''');
+''', [
+ error(HintCode.EQUAL_ELEMENTS_IN_SET, 15, 1),
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/equal_elements_in_set_test.dart b/pkg/analyzer/test/src/diagnostics/equal_elements_in_set_test.dart
new file mode 100644
index 0000000..261e8bf
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/equal_elements_in_set_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(EqualElementsInSetTest);
+ });
+}
+
+@reflectiveTest
+class EqualElementsInSetTest extends DriverResolutionTest {
+ test_constant_constant() async {
+ await assertErrorsInCode('''
+const a = 1;
+const b = 1;
+var s = {a, b};
+''', [
+ error(HintCode.EQUAL_ELEMENTS_IN_SET, 38, 1),
+ ]);
+ }
+
+ test_literal_constant() async {
+ await assertErrorsInCode('''
+const one = 1;
+var s = {1, one};
+''', [
+ error(HintCode.EQUAL_ELEMENTS_IN_SET, 27, 3),
+ ]);
+ }
+
+ test_literal_literal() async {
+ await assertErrorsInCode('''
+var s = {1, 1};
+''', [
+ error(HintCode.EQUAL_ELEMENTS_IN_SET, 12, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/equal_keys_in_const_map_test.dart b/pkg/analyzer/test/src/diagnostics/equal_keys_in_const_map_test.dart
index 0e9ea6b..7334278 100644
--- a/pkg/analyzer/test/src/diagnostics/equal_keys_in_const_map_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/equal_keys_in_const_map_test.dart
@@ -158,9 +158,12 @@
}
test_nonConst_entry() async {
- await assertNoErrorsInCode('''
+ // No error, but there is a hint.
+ await assertErrorsInCode('''
var c = {1: null, 2: null, 1: null};
-''');
+''', [
+ error(HintCode.EQUAL_KEYS_IN_MAP, 27, 1),
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/equal_keys_in_map_test.dart b/pkg/analyzer/test/src/diagnostics/equal_keys_in_map_test.dart
new file mode 100644
index 0000000..a546d1b
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/equal_keys_in_map_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(EqualKeysInMapTest);
+ });
+}
+
+@reflectiveTest
+class EqualKeysInMapTest extends DriverResolutionTest {
+ test_constant_constant() async {
+ await assertErrorsInCode('''
+const a = 1;
+const b = 1;
+var s = {a: 2, b: 3};
+''', [
+ error(HintCode.EQUAL_KEYS_IN_MAP, 41, 1),
+ ]);
+ }
+
+ test_literal_constant() async {
+ await assertErrorsInCode('''
+const one = 1;
+var s = {1: 2, one: 3};
+''', [
+ error(HintCode.EQUAL_KEYS_IN_MAP, 30, 3),
+ ]);
+ }
+
+ test_literal_literal() async {
+ await assertErrorsInCode('''
+var s = {1: 2, 1: 3};
+''', [
+ error(HintCode.EQUAL_KEYS_IN_MAP, 15, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_language_override_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_language_override_test.dart
index 8a9aa78..5e72381 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_language_override_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_language_override_test.dart
@@ -9,12 +9,12 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(BadDartLanguageOverrideTest);
+ defineReflectiveTests(InvalidLanguageOverrideTest);
});
}
@reflectiveTest
-class BadDartLanguageOverrideTest extends DriverResolutionTest {
+class InvalidLanguageOverrideTest extends DriverResolutionTest {
test_correct_11_12() async {
await assertNoErrorsInCode(r'''
// @dart = 11.12
@@ -77,6 +77,57 @@
''');
}
+ test_location_afterClass() async {
+ await assertErrorsInCode(r'''
+class A {
+ // @dart = 2.5
+ void test() {}
+}
+''', [
+ error(HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION, 15, 11),
+ ]);
+ }
+
+ test_location_afterDeclaration() async {
+ await assertErrorsInCode(r'''
+class A {}
+// @dart = 2.5
+''', [error(HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION, 14, 11)]);
+ }
+
+ test_location_afterDeclaration_beforeEof() async {
+ await assertErrorsInCode(r'''
+class A {}
+// @dart = 2.5
+''', [error(HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION, 14, 11)]);
+ }
+
+ test_location_afterDirective() async {
+ await assertErrorsInCode(r'''
+import 'dart:core';
+// @dart = 2.5
+class A {}
+''', [error(HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION, 23, 11)]);
+ }
+
+ test_location_beforeDeclaration() async {
+ await assertNoErrorsInCode(r'''
+// @dart = 2.5
+class A {}
+''');
+ }
+
+ test_location_notLineStart() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ /**
+ * For example '// @dart = 2.1'.
+ */
+ void test() {}
+}
+''');
+ }
+
test_missingAtSign() async {
await assertErrorsInCode(r'''
// dart = 2.0
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_null_value_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_null_value_test.dart
deleted file mode 100644
index c680ec7..0000000
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_null_value_test.dart
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2019, 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.
-
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../dart/resolution/driver_resolution.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(InvalidUseOfNullValueTest);
- });
-}
-
-@reflectiveTest
-class InvalidUseOfNullValueTest extends DriverResolutionTest {
- @override
- AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..contextFeatures = FeatureSet.fromEnableFlags(
- [EnableString.non_nullable],
- );
-
- test_as() async {
- await assertNoErrorsInCode(r'''
-m() {
- Null x;
- x as int; // ignore: unnecessary_cast
-}
-''');
- }
-
- test_await() async {
- await assertNoErrorsInCode(r'''
-m() async {
- Null x;
- await x;
-}
-''');
- }
-
- test_cascade() async {
- await assertNoErrorsInCode(r'''
-m() {
- Null x;
- x..toString;
-}
-''');
- }
-
- test_eq() async {
- await assertNoErrorsInCode(r'''
-m() {
- Null x;
- x == null;
-}
-''');
- }
-
- test_forLoop() async {
- await assertErrorsInCode(r'''
-m() {
- Null x;
- for (var y in x) {}
-}
-''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 27, 1),
- error(StaticWarningCode.INVALID_USE_OF_NULL_VALUE, 32, 1),
- ]);
- }
-
- test_is() async {
- await assertNoErrorsInCode(r'''
-m() {
- Null x;
- x is int;
-}
-''');
- }
-
- test_member() async {
- await assertNoErrorsInCode(r'''
-m() {
- Null x;
- x.runtimeType;
-}
-''');
- }
-
- test_method() async {
- await assertNoErrorsInCode(r'''
-m() {
- Null x;
- x.toString();
-}
-''');
- }
-
- test_notEq() async {
- await assertNoErrorsInCode(r'''
-m() {
- Null x;
- x != null;
-}
-''');
- }
-
- test_ternary_lhs() async {
- await assertNoErrorsInCode(r'''
-m(bool cond) {
- Null x;
- cond ? x : 1;
-}
-''');
- }
-
- test_ternary_rhs() async {
- await assertNoErrorsInCode(r'''
-m(bool cond) {
- Null x;
- cond ? 0 : x;
-}
-''');
- }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
index 4b774e1..06f4f23 100644
--- a/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
@@ -2,7 +2,9 @@
// 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.
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/driver_resolution.dart';
@@ -10,10 +12,31 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NotIterableSpreadTest);
+ defineReflectiveTests(NotIterableSpreadNullSafetyTest);
});
}
@reflectiveTest
+class NotIterableSpreadNullSafetyTest extends NotIterableSpreadTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = FeatureSet.forTesting(
+ sdkVersion: '2.7.0', additionalFeatures: [Feature.non_nullable]);
+
+ @override
+ bool get typeToStringWithNullability => true;
+
+ test_iterable_typeParameter_bound_listQuestion() async {
+ await assertNoErrorsInCode('''
+void f<T extends List<int>?>(T a) {
+ var v = [...?a];
+ v;
+}
+''');
+ }
+}
+
+@reflectiveTest
class NotIterableSpreadTest extends DriverResolutionTest {
test_iterable_list() async {
await assertNoErrorsInCode('''
@@ -28,6 +51,15 @@
''');
}
+ test_iterable_typeParameter_bound_list() async {
+ await assertNoErrorsInCode('''
+void f<T extends List<int>>(T a) {
+ var v = [...a];
+ v;
+}
+''');
+ }
+
test_notIterable_direct() async {
await assertErrorsInCode('''
var a = 0;
@@ -64,4 +96,15 @@
error(CompileTimeErrorCode.NOT_ITERABLE_SPREAD, 34, 1),
]);
}
+
+ test_notIterable_typeParameter_bound() async {
+ await assertErrorsInCode('''
+void f<T extends num>(T a) {
+ var v = [...a];
+ v;
+}
+''', [
+ error(CompileTimeErrorCode.NOT_ITERABLE_SPREAD, 43, 1),
+ ]);
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
index 2f7e415..98ccc0d 100644
--- a/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
@@ -2,7 +2,9 @@
// 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.
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/driver_resolution.dart';
@@ -10,10 +12,31 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NotMapSpreadTest);
+ defineReflectiveTests(NotMapSpreadNullSafetyTest);
});
}
@reflectiveTest
+class NotMapSpreadNullSafetyTest extends NotMapSpreadTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = FeatureSet.forTesting(
+ sdkVersion: '2.7.0', additionalFeatures: [Feature.non_nullable]);
+
+ @override
+ bool get typeToStringWithNullability => true;
+
+ test_map_typeParameter_bound_mapQuestion() async {
+ await assertNoErrorsInCode('''
+void f<T extends Map<int, String>?>(T a) {
+ var v = <int, String>{...?a};
+ v;
+}
+''');
+ }
+}
+
+@reflectiveTest
class NotMapSpreadTest extends DriverResolutionTest {
test_map() async {
await assertNoErrorsInCode('''
@@ -28,6 +51,15 @@
''');
}
+ test_map_typeParameter_bound_map() async {
+ await assertNoErrorsInCode('''
+void f<T extends Map<int, String>>(T a) {
+ var v = <int, String>{...a};
+ v;
+}
+''');
+ }
+
test_notMap_direct() async {
await assertErrorsInCode('''
var a = 0;
@@ -64,4 +96,15 @@
error(CompileTimeErrorCode.NOT_MAP_SPREAD, 44, 1),
]);
}
+
+ test_notMap_typeParameter_bound() async {
+ await assertErrorsInCode('''
+void f<T extends num>(T a) {
+ var v = <int, int>{...a};
+ v;
+}
+''', [
+ error(CompileTimeErrorCode.NOT_MAP_SPREAD, 53, 1),
+ ]);
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
index 58b1fc5..6c11828 100644
--- a/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/private_optional_parameter_test.dart
@@ -9,12 +9,12 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(RecursiveCompileTimeConstantTest);
+ defineReflectiveTests(PrivateOptionalParameterTest);
});
}
@reflectiveTest
-class RecursiveCompileTimeConstantTest extends DriverResolutionTest {
+class PrivateOptionalParameterTest extends DriverResolutionTest {
test_private() async {
await assertErrorsInCode('''
f({var _p}) {}
diff --git a/pkg/analyzer/test/src/diagnostics/recursive_compile_time_constant_test.dart b/pkg/analyzer/test/src/diagnostics/recursive_compile_time_constant_test.dart
index 2245354..05d0a4c 100644
--- a/pkg/analyzer/test/src/diagnostics/recursive_compile_time_constant_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/recursive_compile_time_constant_test.dart
@@ -47,10 +47,12 @@
''',
);
// No errors, because the cycle is not in this source.
- await assertNoErrorsInCode(r'''
+ await assertErrorsInCode(r'''
import 'constants.dart';
final z = {x: 0, y: 1};
-''');
+''', [
+ error(HintCode.EQUAL_KEYS_IN_MAP, 42, 1),
+ ]);
}
test_initializer_after_toplevel_var() async {
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 973eec9..9275a0a 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -82,7 +82,9 @@
import 'duplicate_part_test.dart' as duplicate_part;
import 'duplicate_shown_name_test.dart' as duplicate_shown_name;
import 'equal_elements_in_const_set_test.dart' as equal_elements_in_const_set;
+import 'equal_elements_in_set_test.dart' as equal_elements_in_set;
import 'equal_keys_in_const_map_test.dart' as equal_keys_in_const_map;
+import 'equal_keys_in_map_test.dart' as equal_keys_in_map;
import 'expected_one_list_type_arguments_test.dart'
as expected_one_list_type_arguments;
import 'expected_one_set_type_arguments_test.dart'
@@ -221,7 +223,6 @@
import 'invalid_uri_test.dart' as invalid_uri;
import 'invalid_use_of_covariant_in_extension_test.dart'
as invalid_use_of_covariant_in_extension;
-import 'invalid_use_of_null_value_test.dart' as invalid_use_of_null_value;
import 'invalid_use_of_protected_member_test.dart'
as invalid_use_of_protected_member;
import 'invalid_use_of_visible_for_template_member_test.dart'
@@ -443,8 +444,6 @@
import 'type_test_with_non_type_test.dart' as type_test_with_non_type;
import 'type_test_with_undefined_name_test.dart'
as type_test_with_undefined_name;
-import 'unchecked_use_of_nullable_value_test.dart'
- as unchecked_use_of_nullable_value;
import 'undefined_annotation_test.dart' as undefined_annotation;
import 'undefined_class_boolean_test.dart' as undefined_class_boolean;
import 'undefined_class_test.dart' as undefined_class;
@@ -485,8 +484,10 @@
import 'unused_shown_name_test.dart' as unused_shown_name;
import 'uri_does_not_exist_test.dart' as uri_does_not_exist;
import 'uri_with_interpolation_test.dart' as uri_with_interpolation;
+import 'use_of_nullable_value_test.dart' as use_of_nullable_value_test;
import 'use_of_void_result_test.dart' as use_of_void_result;
import 'variable_type_mismatch_test.dart' as variable_type_mismatch;
+import 'void_with_type_arguments_test.dart' as void_with_type_arguments_test;
import 'wrong_number_of_parameters_for_operator_test.dart'
as wrong_number_of_parameters_for_operator;
import 'wrong_number_of_parameters_for_setter_test.dart'
@@ -556,7 +557,9 @@
duplicate_part.main();
duplicate_shown_name.main();
equal_elements_in_const_set.main();
+ equal_elements_in_set.main();
equal_keys_in_const_map.main();
+ equal_keys_in_map.main();
expected_one_list_type_arguments.main();
expected_one_set_type_arguments.main();
expected_two_map_type_arguments.main();
@@ -646,7 +649,6 @@
invalid_type_argument_in_const_set.main();
invalid_uri.main();
invalid_use_of_covariant_in_extension.main();
- invalid_use_of_null_value.main();
invalid_use_of_protected_member.main();
invalid_use_of_visible_for_template_member.main();
invalid_use_of_visible_for_testing_member.main();
@@ -794,7 +796,6 @@
type_parameter_referenced_by_static.main();
type_test_with_non_type.main();
type_test_with_undefined_name.main();
- unchecked_use_of_nullable_value.main();
undefined_annotation.main();
undefined_class_boolean.main();
undefined_class.main();
@@ -832,8 +833,10 @@
unused_shown_name.main();
uri_does_not_exist.main();
uri_with_interpolation.main();
+ use_of_nullable_value_test.main();
use_of_void_result.main();
variable_type_mismatch.main();
+ void_with_type_arguments_test.main();
wrong_number_of_parameters_for_operator.main();
wrong_number_of_parameters_for_setter.main();
wrong_number_of_type_arguments.main();
diff --git a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
similarity index 93%
rename from pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
rename to pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
index 0c8a498..4cc8770 100644
--- a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
@@ -13,12 +13,124 @@
main() {
defineReflectiveSuite(() {
+ defineReflectiveTests(InvalidUseOfNullValueTest);
defineReflectiveTests(UncheckedUseOfNullableValueTest);
defineReflectiveTests(UncheckedUseOfNullableValueInsideExtensionTest);
});
}
@reflectiveTest
+class InvalidUseOfNullValueTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = FeatureSet.fromEnableFlags(
+ [EnableString.non_nullable],
+ );
+
+ test_as() async {
+ await assertNoErrorsInCode(r'''
+m() {
+ Null x;
+ x as int; // ignore: unnecessary_cast
+}
+''');
+ }
+
+ test_await() async {
+ await assertNoErrorsInCode(r'''
+m() async {
+ Null x;
+ await x;
+}
+''');
+ }
+
+ test_cascade() async {
+ await assertNoErrorsInCode(r'''
+m() {
+ Null x;
+ x..toString;
+}
+''');
+ }
+
+ test_eq() async {
+ await assertNoErrorsInCode(r'''
+m() {
+ Null x;
+ x == null;
+}
+''');
+ }
+
+ test_forLoop() async {
+ await assertErrorsInCode(r'''
+m() {
+ Null x;
+ for (var y in x) {}
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 27, 1),
+ error(StaticWarningCode.INVALID_USE_OF_NULL_VALUE, 32, 1),
+ ]);
+ }
+
+ test_is() async {
+ await assertNoErrorsInCode(r'''
+m() {
+ Null x;
+ x is int;
+}
+''');
+ }
+
+ test_member() async {
+ await assertNoErrorsInCode(r'''
+m() {
+ Null x;
+ x.runtimeType;
+}
+''');
+ }
+
+ test_method() async {
+ await assertNoErrorsInCode(r'''
+m() {
+ Null x;
+ x.toString();
+}
+''');
+ }
+
+ test_notEq() async {
+ await assertNoErrorsInCode(r'''
+m() {
+ Null x;
+ x != null;
+}
+''');
+ }
+
+ test_ternary_lhs() async {
+ await assertNoErrorsInCode(r'''
+m(bool cond) {
+ Null x;
+ cond ? x : 1;
+}
+''');
+ }
+
+ test_ternary_rhs() async {
+ await assertNoErrorsInCode(r'''
+m(bool cond) {
+ Null x;
+ cond ? 0 : x;
+}
+''');
+ }
+}
+
+@reflectiveTest
class UncheckedUseOfNullableValueInsideExtensionTest
extends DriverResolutionTest {
@override
diff --git a/pkg/analyzer/test/src/diagnostics/void_with_type_arguments_test.dart b/pkg/analyzer/test/src/diagnostics/void_with_type_arguments_test.dart
new file mode 100644
index 0000000..bc3d754
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/void_with_type_arguments_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(VoidWithTypeArgumentsTest);
+ });
+}
+
+@reflectiveTest
+class VoidWithTypeArgumentsTest extends DriverResolutionTest {
+ test_noArguments() async {
+ await assertNoErrorsInCode('''
+void f() {}
+''');
+ }
+
+ test_withArguments() async {
+ await assertErrorsInCode('''
+void<int> f() {}
+''', [
+ error(ParserErrorCode.VOID_WITH_TYPE_ARGUMENTS, 4, 1),
+ ]);
+ assertTypeName(findNode.typeName('int>'), intElement, 'int');
+ }
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 38c6691..1472711 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -5413,6 +5413,42 @@
''');
}
+ test_enum_value_documented_withMetadata() async {
+ var library = await checkLibrary('''
+enum E {
+ /**
+ * aaa
+ */
+ @annotation
+ a,
+ /// bbb
+ @annotation
+ b,
+}
+
+const int annotation = 0;
+''');
+ checkElementText(
+ library,
+ r'''
+enum E {
+ synthetic final int index;
+ synthetic static const List<E> values;
+ /**
+ * aaa
+ */
+ @annotation
+ static const E a;
+ /// bbb
+ @annotation
+ static const E b;
+ String toString() {}
+}
+const int annotation = 0;
+''',
+ withConstElements: false);
+ }
+
test_enum_values() async {
var library = await checkLibrary('enum E { v1, v2 }');
checkElementText(library, r'''
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 0adf387..557aef8 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -18,7 +18,6 @@
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:yaml/yaml.dart';
@@ -30,7 +29,6 @@
defineReflectiveSuite(() {
defineReflectiveTests(ContextConfigurationTest);
defineReflectiveTests(ErrorCodeValuesTest);
- defineReflectiveTests(GenerateOldOptionsErrorsTaskTest);
defineReflectiveTests(OptionsFileValidatorTest);
defineReflectiveTests(OptionsProviderTest);
});
@@ -209,42 +207,6 @@
}
@reflectiveTest
-class GenerateOldOptionsErrorsTaskTest with ResourceProviderMixin {
- final AnalysisOptionsProvider optionsProvider = AnalysisOptionsProvider();
-
- String get optionsFilePath => '/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
-
- test_does_analyze_old_options_files() {
- validate('''
-analyzer:
- strong-mode: true
- ''', [
- AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME,
- AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED
- ]);
- }
-
- test_finds_issues_in_old_options_files() {
- validate('''
-analyzer:
- strong_mode: true
- ''', [
- AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME,
- AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES
- ]);
- }
-
- void validate(String content, List<ErrorCode> expected) {
- final source = newFile(optionsFilePath, content: content).createSource();
- var options = optionsProvider.getOptionsFromSource(source);
- final OptionsFileValidator validator = OptionsFileValidator(source);
- var errors = validator.validate(options);
- expect(errors.map((AnalysisError e) => e.errorCode),
- unorderedEquals(expected));
- }
-}
-
-@reflectiveTest
class OptionsFileValidatorTest {
final OptionsFileValidator validator = OptionsFileValidator(TestSource());
final AnalysisOptionsProvider optionsProvider = AnalysisOptionsProvider();
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index f96bb3d..2850837 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -2126,6 +2126,46 @@
await check(implicitCasts: false);
}
+ test_implicitCasts_forEach() async {
+ addFile(r'''
+main(dynamic a) {
+ for (int v in a) {
+ v;
+ }
+}
+''');
+ await check();
+
+ addFile(r'''
+main(dynamic a) {
+ for (int v in /*error:FOR_IN_OF_INVALID_ELEMENT_TYPE*/a) {
+ v;
+ }
+}
+''');
+ await check(implicitCasts: false);
+ }
+
+ test_implicitCasts_forEach_async() async {
+ addFile(r'''
+main(dynamic a) async {
+ await for (int v in a) {
+ v;
+ }
+}
+''');
+ await check();
+
+ addFile(r'''
+main(dynamic a) async {
+ await for (int v in /*error:FOR_IN_OF_INVALID_ELEMENT_TYPE*/a) {
+ v;
+ }
+}
+''');
+ await check(implicitCasts: false);
+ }
+
test_implicitCasts_functionCall() async {
addFile('''num n;
f(int i) => i;
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 96b84bd..bd24cb1 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -1399,7 +1399,7 @@
### equal_elements_in_const_set
-_Two values in a constant set can't be equal._
+_Two elements in a constant set literal can't be equal._
#### Description
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index b52cf59..0f45e9f 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -269,7 +269,9 @@
}
@override
- void logException(dynamic exception, [StackTrace stackTrace]) {
+ void logException(dynamic exception,
+ [StackTrace stackTrace,
+ List<InstrumentationServiceAttachment> attachments]) {
errorSink.writeln(exception);
errorSink.writeln(stackTrace);
}
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index bacd4b0..e97abae 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -280,8 +280,7 @@
// Analyze the libraries.
for (String path in filesToAnalyze) {
var shortName = resourceProvider.pathContext.basename(path);
- if (shortName == AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE ||
- shortName == AnalysisEngine.ANALYSIS_OPTIONS_FILE) {
+ if (shortName == AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE) {
File file = resourceProvider.getFile(path);
String content = file.readAsStringSync();
LineInfo lineInfo = LineInfo.fromContent(content);
diff --git a/pkg/async_helper/lib/async_minitest.dart b/pkg/async_helper/lib/async_minitest.dart
index 3668aba..c7dcb86 100644
--- a/pkg/async_helper/lib/async_minitest.dart
+++ b/pkg/async_helper/lib/async_minitest.dart
@@ -189,6 +189,11 @@
Expect.fail("$v is not less than $n");
};
+Matcher predicate(bool fn(dynamic value), [String description = ""]) =>
+ (dynamic v) {
+ Expect.isTrue(fn(v), description);
+ };
+
void isTrue(dynamic v) {
Expect.isTrue(v);
}
@@ -223,6 +228,16 @@
});
}
+void returnsNormally(dynamic o) {
+ try {
+ Expect.type<Function()>(o);
+ o();
+ } catch (error, trace) {
+ Expect.fail(
+ "Expected function to return normally, but threw:\n$error\n\n$trace");
+ }
+}
+
void throws(dynamic v) {
_checkThrow<Object>(v, (_) {});
}
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index af946d8..8d56df5 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -65,6 +65,7 @@
static const String noMinify = '--no-minify';
static const String noSourceMaps = '--no-source-maps';
static const String preserveUris = '--preserve-uris';
+ static const String printLegacyStars = '--debug-print-legacy-stars';
static const String showPackageWarnings = '--show-package-warnings';
static const String suppressHints = '--suppress-hints';
static const String suppressWarnings = '--suppress-warnings';
@@ -94,8 +95,8 @@
static const String serverMode = '--server-mode';
- static const String runtimeNullSafety = '--runtime-null-safety';
- static const String noRuntimeNullSafety = '--no-runtime-null-safety';
+ static const String nullSafety = '--null-safety';
+ static const String noNullSafety = '--no-null-safety';
static const String newDeferredSplit = '--new-deferred-split';
static const String reportInvalidInferredDeferredTypes =
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 3a77982..65ac11c 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -513,6 +513,9 @@
FunctionEntity get generalAsCheckImplementation;
FunctionEntity get generalTypeCheckImplementation;
+ FunctionEntity get specializedIsObject;
+ FunctionEntity get specializedAsObject;
+ FunctionEntity get specializedCheckObject;
FunctionEntity get specializedIsTop;
FunctionEntity get specializedAsTop;
FunctionEntity get specializedIsBool;
@@ -1976,6 +1979,21 @@
_generalTypeCheckImplementation ??=
_findRtiFunction('_generalTypeCheckImplementation');
+ FunctionEntity _specializedIsObject;
+ @override
+ FunctionEntity get specializedIsObject =>
+ _specializedIsObject ??= _findRtiFunction('_isObject');
+
+ FunctionEntity _specializedAsObject;
+ @override
+ FunctionEntity get specializedAsObject =>
+ _specializedAsObject ??= _findRtiFunction('_asObject');
+
+ FunctionEntity _specializedCheckObject;
+ @override
+ FunctionEntity get specializedCheckObject =>
+ _specializedCheckObject ??= _findRtiFunction('_checkObject');
+
@override
FunctionEntity get specializedIsTop => _findRtiFunction('_isTop');
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 0480aea..7b300b0 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -38,7 +38,7 @@
import 'kernel/kernel_strategy.dart';
import 'kernel/loader.dart' show KernelLoaderTask, KernelResult;
import 'null_compiler_output.dart' show NullCompilerOutput;
-import 'options.dart' show CompilerOptions, DiagnosticOptions;
+import 'options.dart' show CompilerOptions;
import 'serialization/task.dart';
import 'serialization/strategies.dart';
import 'ssa/nodes.dart' show HInstruction;
@@ -144,7 +144,7 @@
if (makeReporter != null) {
_reporter = makeReporter(this, options);
} else {
- _reporter = new CompilerDiagnosticReporter(this, options);
+ _reporter = new CompilerDiagnosticReporter(this);
}
kernelFrontEndTask = new GenericTask('Front end', measurer);
frontendStrategy = new KernelFrontendStrategy(
@@ -631,7 +631,7 @@
class CompilerDiagnosticReporter extends DiagnosticReporter {
final Compiler compiler;
@override
- final DiagnosticOptions options;
+ CompilerOptions get options => compiler.options;
Entity _currentElement;
bool hasCrashed = false;
@@ -644,7 +644,7 @@
/// suppressed for each library.
Map<Uri, SuppressionInfo> suppressedWarnings = <Uri, SuppressionInfo>{};
- CompilerDiagnosticReporter(this.compiler, this.options);
+ CompilerDiagnosticReporter(this.compiler);
Entity get currentElement => _currentElement;
@@ -653,7 +653,7 @@
[Map arguments = const {}]) {
SourceSpan span = spanFromSpannable(spannable);
MessageTemplate template = MessageTemplate.TEMPLATES[messageKind];
- Message message = template.message(arguments, options.terseDiagnostics);
+ Message message = template.message(arguments, options);
return new DiagnosticMessage(span, spannable, message);
}
@@ -830,7 +830,7 @@
void pleaseReportCrash() {
print(MessageTemplate.TEMPLATES[MessageKind.PLEASE_REPORT_THE_CRASH]
- .message({'buildId': compiler.options.buildId}));
+ .message({'buildId': compiler.options.buildId}, options));
}
/// Finds the approximate [Element] for [node]. [currentElement] is used as
@@ -848,7 +848,7 @@
@override
void log(message) {
Message msg = MessageTemplate.TEMPLATES[MessageKind.GENERIC]
- .message({'text': '$message'});
+ .message({'text': '$message'}, options);
reportDiagnostic(new DiagnosticMessage(null, null, msg),
const <DiagnosticMessage>[], api.Diagnostic.VERBOSE_INFO);
}
@@ -901,7 +901,7 @@
MessageTemplate template = MessageTemplate.TEMPLATES[kind];
Message message = template.message(
{'warnings': info.warnings, 'hints': info.hints, 'uri': uri},
- options.terseDiagnostics);
+ options);
reportDiagnostic(new DiagnosticMessage(null, null, message),
const <DiagnosticMessage>[], api.Diagnostic.HINT);
});
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 512a657..2a882d5 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -418,6 +418,7 @@
new OptionHandler(Flags.minify, passThrough),
new OptionHandler(Flags.noMinify, passThrough),
new OptionHandler(Flags.preserveUris, ignoreOption),
+ new OptionHandler(Flags.printLegacyStars, passThrough),
new OptionHandler('--force-strip=.*', setStrip),
new OptionHandler(Flags.disableDiagnosticColors, (_) {
enableColors = false;
@@ -464,8 +465,8 @@
new OptionHandler(Flags.laxRuntimeTypeToString, passThrough),
new OptionHandler(Flags.benchmarkingProduction, passThrough),
new OptionHandler(Flags.benchmarkingExperiment, passThrough),
- new OptionHandler(Flags.runtimeNullSafety, setNullSafetyMode),
- new OptionHandler(Flags.noRuntimeNullSafety, setNullSafetyMode),
+ new OptionHandler(Flags.nullSafety, setNullSafetyMode),
+ new OptionHandler(Flags.noNullSafety, setNullSafetyMode),
// TODO(floitsch): remove conditional directives flag.
// We don't provide the info-message yet, since we haven't publicly
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index c85a784..34edd57 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -19,6 +19,8 @@
import 'generated/shared_messages.dart' as shared_messages;
import '../constants/values.dart' show ConstantValue;
import '../commandline_options.dart';
+import '../elements/types.dart';
+import '../options.dart';
import 'invariant.dart' show failedAt;
import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
@@ -76,7 +78,6 @@
INVALID_PACKAGE_URI,
INVALID_STRING_FROM_ENVIRONMENT_DEFAULT_VALUE_TYPE,
JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS,
- JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR,
JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
JS_INTEROP_FIELD_NOT_SUPPORTED,
JS_INTEROP_NON_EXTERNAL_MEMBER,
@@ -232,13 +233,6 @@
howToFix: "Try marking the enclosing class as js-interop or "
"remove the js-interop annotation from the member."),
- MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR:
- const MessageTemplate(
- MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR,
- "Constructor '#{constructor}' in js-interop class '#{cls}' is "
- "not external.",
- howToFix: "Try adding the 'external' to '#{constructor}'."),
-
MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER: const MessageTemplate(
MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
"Member '#{member}' in js-interop class '#{cls}' is not external.",
@@ -667,8 +661,8 @@
@override
String toString() => template;
- Message message([Map arguments = const {}, bool terse = false]) {
- return new Message(this, arguments, terse);
+ Message message(Map arguments, CompilerOptions options) {
+ return new Message(this, arguments, options);
}
bool get hasHowToFix => howToFix != null && howToFix != DONT_KNOW_HOW_TO_FIX;
@@ -677,10 +671,12 @@
class Message {
final MessageTemplate template;
final Map arguments;
- final bool terse;
+ final CompilerOptions _options;
+ bool get terse => _options?.terseDiagnostics ?? false;
+ bool get _printLegacyStars => _options?.printLegacyStars ?? false;
String message;
- Message(this.template, this.arguments, this.terse) {
+ Message(this.template, this.arguments, this._options) {
assert(() {
computeMessage();
return true;
@@ -725,8 +721,10 @@
@override
int get hashCode => throw new UnsupportedError('Message.hashCode');
- static String convertToString(value) {
- if (value is ConstantValue) {
+ String convertToString(value) {
+ if (value is DartType) {
+ value = value.toStructuredText(printLegacyStars: _printLegacyStars);
+ } else if (value is ConstantValue) {
value = value.toDartText();
} else {
value = tokenToString(value);
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 9dafa6c..a7a5404 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -128,7 +128,10 @@
bool _equals(DartType other, _Assumptions assumptions);
@override
- String toString() => _DartTypeToStringVisitor().run(this);
+ String toString() => toStructuredText();
+
+ String toStructuredText({bool printLegacyStars = false}) =>
+ _DartTypeToStringVisitor(printLegacyStars).run(this);
}
/// Pairs of [FunctionTypeVariable]s that are currently assumed to be
@@ -1418,12 +1421,15 @@
}
class _DartTypeToStringVisitor extends DartTypeVisitor<void, void> {
+ final bool _printLegacyStars;
final List _fragments = []; // Strings and _DeferredNames
bool _lastIsIdentifier = false;
List<FunctionTypeVariable> _boundVariables;
Map<FunctionTypeVariable, _DeferredName> _variableToName;
Set<FunctionType> _genericFunctions;
+ _DartTypeToStringVisitor(this._printLegacyStars);
+
String run(DartType type) {
_visit(type);
if (_variableToName != null &&
@@ -1484,7 +1490,10 @@
// We do not emit the '*' token for legacy types because this is a purely
// internal notion. The language specification does not define a '*' token
// in the type language, and no such token should be surfaced to users.
- // TODO(fishythefish): Add a flag to enable printing '*'.
+ // For debugging, pass `--debug-print-legacy-stars` to emit the '*'.
+ if (_printLegacyStars) {
+ _token('*');
+ }
}
@override
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 2a8247f..5d6d6ac 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -2251,34 +2251,34 @@
AbstractValue _narrowType(
JClosedWorld closedWorld, AbstractValue type, DartType annotation,
{bool isNullable: true}) {
- annotation = annotation.withoutNullability;
AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
- AbstractValue otherType;
- if (closedWorld.dartTypes.isTopType(annotation)) {
- return type;
- } else if (annotation is InterfaceType) {
- if (annotation.element == closedWorld.commonElements.objectClass) {
- return type;
+
+ AbstractValue _intersectionWith(AbstractValue otherType) {
+ if (isNullable) {
+ otherType = abstractValueDomain.includeNull(otherType);
}
- otherType = abstractValueDomain.createNonNullSubtype(annotation.element);
- } else if (annotation is VoidType) {
+ return type == null
+ ? otherType
+ : abstractValueDomain.intersection(type, otherType);
+ }
+
+ // TODO(joshualitt): FutureOrType, TypeVariableType, and FunctionTypeVariable
+ // can be narrowed.
+ // TODO(fishythefish): Use nullability.
+ annotation = annotation.withoutNullability;
+ if (closedWorld.dartTypes.isTopType(annotation) ||
+ annotation is FutureOrType ||
+ annotation is TypeVariableType ||
+ annotation is FunctionTypeVariable) {
return type;
+ } else if (annotation is NeverType) {
+ return _intersectionWith(abstractValueDomain.emptyType);
+ } else if (annotation is InterfaceType) {
+ return _intersectionWith(
+ abstractValueDomain.createNonNullSubtype(annotation.element));
} else if (annotation is FunctionType) {
- otherType = closedWorld.abstractValueDomain.functionType;
- } else if (annotation is FutureOrType) {
- // TODO(johnniwinther): Narrow FutureOr types.
- return type;
+ return _intersectionWith(abstractValueDomain.functionType);
} else {
- assert(
- annotation is TypeVariableType || annotation is FunctionTypeVariable);
- // TODO(ngeoffray): Narrow to bound.
- return type;
+ throw 'Unexpected annotation type $annotation';
}
- if (isNullable) {
- otherType = abstractValueDomain.includeNull(otherType);
- }
- if (type == null) {
- return otherType;
- }
- return abstractValueDomain.intersection(type, otherType);
}
diff --git a/pkg/compiler/lib/src/inferrer/type_system.dart b/pkg/compiler/lib/src/inferrer/type_system.dart
index 597ae50..1234917 100644
--- a/pkg/compiler/lib/src/inferrer/type_system.dart
+++ b/pkg/compiler/lib/src/inferrer/type_system.dart
@@ -317,43 +317,42 @@
/// type.
TypeInformation narrowType(TypeInformation type, DartType annotation,
{bool isNullable: true}) {
+ TypeInformation _narrowTo(AbstractValue otherType) {
+ if (_abstractValueDomain.isExact(type.type).isDefinitelyTrue) return type;
+ if (isNullable) {
+ otherType = _abstractValueDomain.includeNull(otherType);
+ }
+ TypeInformation newType =
+ new NarrowTypeInformation(_abstractValueDomain, type, otherType);
+ allocatedTypes.add(newType);
+ return newType;
+ }
+
+ // TODO(fishythefish): Use nullability.
annotation = annotation.withoutNullability;
- AbstractValue otherType;
if (annotation is VoidType) return type;
if (_closedWorld.dartTypes.isTopType(annotation)) {
if (isNullable) return type;
// If the input is already narrowed to be not-null, there is no value
// in adding another narrowing node.
if (_isNonNullNarrow(type)) return type;
- otherType = _abstractValueDomain.excludeNull(dynamicType.type);
+ return _narrowTo(_abstractValueDomain.excludeNull(dynamicType.type));
+ } else if (annotation is NeverType) {
+ return _narrowTo(_abstractValueDomain.emptyType);
} else if (annotation is InterfaceType) {
- InterfaceType interface = annotation;
- if (interface.element == _closedWorld.commonElements.objectClass) {
- if (isNullable) return type;
- if (_isNonNullNarrow(type)) return type;
- otherType = _abstractValueDomain.excludeNull(dynamicType.type);
- } else {
- otherType =
- _abstractValueDomain.createNonNullSubtype(interface.element);
- }
+ return _narrowTo(
+ _abstractValueDomain.createNonNullSubtype(annotation.element));
} else if (annotation is FunctionType) {
- otherType = functionType.type;
+ return _narrowTo(functionType.type);
} else if (annotation is FutureOrType) {
// TODO(johnniwinther): Support narrowing of FutureOr.
return type;
- } else {
- assert(annotation is TypeVariableType);
+ } else if (annotation is TypeVariableType) {
// TODO(ngeoffray): Narrow to bound.
return type;
+ } else {
+ throw 'Unexpected annotation type $annotation';
}
- if (isNullable) {
- otherType = _abstractValueDomain.includeNull(otherType);
- }
- if (_abstractValueDomain.isExact(type.type).isDefinitelyTrue) return type;
- TypeInformation newType =
- new NarrowTypeInformation(_abstractValueDomain, type, otherType);
- allocatedTypes.add(newType);
- return newType;
}
ParameterTypeInformation getInferredTypeOfParameter(Local parameter) {
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 3301d8f..dbe085e 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -1013,8 +1013,11 @@
@override
ir.DartType visitExpressionStatement(ir.ExpressionStatement node) {
- visitNode(node.expression);
- return null;
+ if (completes(visitNode(node.expression))) {
+ return null;
+ } else {
+ return const DoesNotCompleteType();
+ }
}
void handleAsExpression(ir.AsExpression node, ir.DartType operandType) {}
diff --git a/pkg/compiler/lib/src/ir/types.dart b/pkg/compiler/lib/src/ir/types.dart
index 74f42e6..a43e4fe 100644
--- a/pkg/compiler/lib/src/ir/types.dart
+++ b/pkg/compiler/lib/src/ir/types.dart
@@ -12,14 +12,14 @@
/// Support for subtype checks of kernel based [DartType]s.
class KernelDartTypes extends DartTypes {
final IrToElementMap elementMap;
- @override
- final bool useNullSafety;
- @override
- final bool useLegacySubtyping;
+ final CompilerOptions _options;
- KernelDartTypes(this.elementMap, CompilerOptions options)
- : useNullSafety = options.useNullSafety,
- useLegacySubtyping = options.useLegacySubtyping;
+ KernelDartTypes(this.elementMap, this._options);
+
+ @override
+ bool get useNullSafety => _options.useNullSafety;
+ @override
+ bool get useLegacySubtyping => _options.useLegacySubtyping;
@override
InterfaceType getThisType(ClassEntity cls) {
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 05a38b0..42fea65 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -832,6 +832,9 @@
_commonElements.specializedIsTop,
_commonElements.specializedAsTop,
// no specializedCheckTop
+ _commonElements.specializedIsObject,
+ _commonElements.specializedAsObject,
+ _commonElements.specializedCheckObject,
], globalClasses: [
_commonElements.closureClass, // instanceOrFunctionType uses this.
])
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 4511fdf..9144014 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -266,7 +266,7 @@
// 15.1.4 Constructor Properties of the Global Object
"Object", "Function", "Array", "String", "Boolean", "Number", "Date",
- "RegExp", "Error", "EvalError", "RangeError", "ReferenceError",
+ "RegExp", "Symbol", "Error", "EvalError", "RangeError", "ReferenceError",
"SyntaxError", "TypeError", "URIError",
// 15.1.5 Other Properties of the Global Object
@@ -2599,16 +2599,6 @@
return runtimeTypeName(_commonElements.jsJavaScriptFunctionClass);
case JsGetName.FUTURE_CLASS_TYPE_NAME:
return runtimeTypeName(_commonElements.futureClass);
- case JsGetName.BOOL_RECIPE:
- return runtimeTypeName(_commonElements.boolClass);
- case JsGetName.DOUBLE_RECIPE:
- return runtimeTypeName(_commonElements.doubleClass);
- case JsGetName.INT_RECIPE:
- return runtimeTypeName(_commonElements.intClass);
- case JsGetName.NUM_RECIPE:
- return runtimeTypeName(_commonElements.numClass);
- case JsGetName.STRING_RECIPE:
- return runtimeTypeName(_commonElements.stringClass);
case JsGetName.RTI_FIELD_IS:
return instanceFieldPropertyName(_commonElements.rtiIsField);
default:
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
index ca9bcf9..7b3745f 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
@@ -390,22 +390,23 @@
}
void processCheckedType(DartType type) {
- if (type is InterfaceType) {
+ var typeWithoutNullability = type.withoutNullability;
+ if (typeWithoutNullability is InterfaceType) {
// Register that if [cls] needs type arguments then so do the entities
// that declare type variables occurring in [type].
- ClassEntity cls = type.element;
- registerDependencies(_getClassNode(cls), type);
+ ClassEntity cls = typeWithoutNullability.element;
+ registerDependencies(_getClassNode(cls), typeWithoutNullability);
}
- if (type is FutureOrType) {
- // [type] is `FutureOr<X>`.
+ if (typeWithoutNullability is FutureOrType) {
+ // [typeWithoutNullability] is `FutureOr<X>`.
// For the implied `is Future<X>` test, register that if `Future` needs
// type arguments then so do the entities that declare type variables
// occurring in `type.typeArgument`.
- registerDependencies(
- _getClassNode(commonElements.futureClass), type.typeArgument);
+ registerDependencies(_getClassNode(commonElements.futureClass),
+ typeWithoutNullability.typeArgument);
// Process `type.typeArgument` for the implied `is X` test.
- processCheckedType(type.typeArgument);
+ processCheckedType(typeWithoutNullability.typeArgument);
}
}
@@ -486,11 +487,12 @@
}
void processType(DartType type, {bool direct: true}) {
- if (type is FutureOrType) {
+ var typeWithoutNullability = type.withoutNullability;
+ if (typeWithoutNullability is FutureOrType) {
_getClassNode(commonElements.futureClass).markIndirectTest();
- processType(type.typeArgument, direct: false);
+ processType(typeWithoutNullability.typeArgument, direct: false);
} else {
- type.forEachTypeVariable((TypeVariableType type) {
+ typeWithoutNullability.forEachTypeVariable((TypeVariableType type) {
processTypeVariableType(type, direct: direct);
});
}
@@ -568,10 +570,12 @@
/// If [type] is of the form `FutureOr<X>`, also register the implicit
/// is-tests of `Future<X>` and `X`.
void addImplicitCheck(DartType type) {
- if (implicitIsChecks.add(type)) {
- if (type is FutureOrType) {
- addImplicitCheck(commonElements.futureType(type.typeArgument));
- addImplicitCheck(type.typeArgument);
+ var typeWithoutNullability = type.withoutNullability;
+ if (implicitIsChecks.add(typeWithoutNullability)) {
+ if (typeWithoutNullability is FutureOrType) {
+ addImplicitCheck(
+ commonElements.futureType(typeWithoutNullability.typeArgument));
+ addImplicitCheck(typeWithoutNullability.typeArgument);
}
}
}
@@ -581,9 +585,11 @@
}
world.isChecks.forEach((DartType type) {
- if (type is FutureOrType) {
- addImplicitCheck(commonElements.futureType(type.typeArgument));
- addImplicitCheck(type.typeArgument);
+ var typeWithoutNullability = type.withoutNullability;
+ if (typeWithoutNullability is FutureOrType) {
+ addImplicitCheck(
+ commonElements.futureType(typeWithoutNullability.typeArgument));
+ addImplicitCheck(typeWithoutNullability.typeArgument);
}
});
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index f11f556..c0c4dff 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -1942,7 +1942,13 @@
globals.add(new js.Property(js.string(LEAF_TAGS), new js.LiteralNull()));
}
- js.ObjectInitializer globalsObject = new js.ObjectInitializer(globals);
+ globals.add(js.Property(
+ js.string(ARRAY_RTI_PROPERTY),
+ js.js(r'typeof Symbol == "function" && typeof Symbol() == "symbol"'
+ r' ? Symbol("$ti")'
+ r' : "$ti"')));
+
+ js.ObjectInitializer globalsObject = js.ObjectInitializer(globals);
return js.js.statement('var init = #;', globalsObject);
}
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 5158656..cf04b75 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -9,6 +9,7 @@
import 'package:js_runtime/shared/embedded_names.dart'
show
+ ARRAY_RTI_PROPERTY,
DEFERRED_INITIALIZED,
DEFERRED_LIBRARY_PARTS,
DEFERRED_PART_URIS,
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 2cf6805..5e5fdd6 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -2250,28 +2250,34 @@
@override
DartType getAsyncOrSyncStarElementType(
AsyncMarker asyncMarker, DartType returnType) {
+ var returnTypeWithoutNullability = returnType.withoutNullability;
switch (asyncMarker) {
case AsyncMarker.SYNC:
return returnType;
case AsyncMarker.SYNC_STAR:
- if (returnType is InterfaceType) {
- if (returnType.element == elementMap.commonElements.iterableClass) {
- return returnType.typeArguments.first;
+ if (returnTypeWithoutNullability is InterfaceType) {
+ if (returnTypeWithoutNullability.element ==
+ elementMap.commonElements.iterableClass) {
+ return returnTypeWithoutNullability.typeArguments.first;
}
}
return dynamicType;
case AsyncMarker.ASYNC:
- if (returnType is FutureOrType) return returnType.typeArgument;
- if (returnType is InterfaceType) {
- if (returnType.element == elementMap.commonElements.futureClass) {
- return returnType.typeArguments.first;
+ if (returnTypeWithoutNullability is FutureOrType) {
+ return returnTypeWithoutNullability.typeArgument;
+ }
+ if (returnTypeWithoutNullability is InterfaceType) {
+ if (returnTypeWithoutNullability.element ==
+ elementMap.commonElements.futureClass) {
+ return returnTypeWithoutNullability.typeArguments.first;
}
}
return dynamicType;
case AsyncMarker.ASYNC_STAR:
- if (returnType is InterfaceType) {
- if (returnType.element == elementMap.commonElements.streamClass) {
- return returnType.typeArguments.first;
+ if (returnTypeWithoutNullability is InterfaceType) {
+ if (returnTypeWithoutNullability.element ==
+ elementMap.commonElements.streamClass) {
+ return returnTypeWithoutNullability.typeArguments.first;
}
}
return dynamicType;
@@ -2461,26 +2467,6 @@
}
}
-/// [BehaviorBuilder] for kernel based elements.
-class JsBehaviorBuilder extends BehaviorBuilder {
- @override
- final ElementEnvironment elementEnvironment;
- @override
- final CommonElements commonElements;
- @override
- final DiagnosticReporter reporter;
- @override
- final NativeBasicData nativeBasicData;
- final CompilerOptions _options;
-
- JsBehaviorBuilder(this.elementEnvironment, this.commonElements,
- this.nativeBasicData, this.reporter, this._options);
-
- @override
- bool get trustJSInteropTypeAnnotations =>
- _options.trustJSInteropTypeAnnotations;
-}
-
/// [EntityLookup] implementation used to deserialize [JsKernelToElementMap].
///
/// Since data objects and environments are registered together with their
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 1512e6b..ff92060 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -50,6 +50,7 @@
/// A kernel [Target] to configure the Dart Front End for dart2js.
class Dart2jsTarget extends Target {
+ @override
final TargetFlags flags;
@override
final String name;
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 2df6dcb..1c49912 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -1475,7 +1475,7 @@
if (supertype != null) {
return true;
}
- return data.callType is FunctionType;
+ return data.callType?.withoutNullability is FunctionType;
}
@override
@@ -1869,14 +1869,15 @@
final DiagnosticReporter reporter;
@override
final NativeBasicData nativeBasicData;
- final CompilerOptions _options;
+ @override
+ final CompilerOptions options;
KernelBehaviorBuilder(this.elementEnvironment, this.commonElements,
- this.nativeBasicData, this.reporter, this._options);
+ this.nativeBasicData, this.reporter, this.options);
@override
bool get trustJSInteropTypeAnnotations =>
- _options.trustJSInteropTypeAnnotations;
+ options.trustJSInteropTypeAnnotations;
}
class KernelNativeMemberResolver implements NativeMemberResolver {
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index bfdf6ee..a218e6a 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -105,7 +105,10 @@
_options.librariesSpecificationUri,
dependencies,
_options.packageConfig,
- experimentalFlags: _options.languageExperiments);
+ experimentalFlags: _options.languageExperiments,
+ nnbdMode: _options.useLegacySubtyping
+ ? fe.NnbdMode.Weak
+ : fe.NnbdMode.Strong);
component = await fe.compile(
initializedCompilerState,
false,
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index 98a9541..81256fb 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -162,19 +162,6 @@
constructor, memberName);
}
- // TODO(33834): It is a breaking change (at least against in some of
- // our own tests) but JS-interop constructors should be required to be
- // external since we otherwise allow creating a Dart object that tries
- // to pass as a JS-interop class.
- /*if (!constructor.isExternal) {
- reporter.reportErrorMessage(constructor,
- MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR, {
- 'cls': cls.name,
- 'constructor':
- constructor.name.isEmpty ? '${cls.name}.' : constructor.name
- });
- }*/
-
if (constructor.isFactoryConstructor && isAnonymous) {
if (constructor.parameterStructure.positionalParameters > 0) {
reporter.reportErrorMessage(
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 3f064b5..21fc93c 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -9,6 +9,7 @@
import '../elements/types.dart';
import '../js/js.dart' as js;
import '../js_backend/native_data.dart' show NativeBasicData;
+import '../options.dart';
import '../serialization/serialization.dart';
import '../universe/side_effects.dart' show SideEffects;
import 'js.dart';
@@ -737,6 +738,8 @@
NativeBasicData get nativeBasicData;
bool get trustJSInteropTypeAnnotations;
ElementEnvironment get elementEnvironment;
+ CompilerOptions get options;
+ DartTypes get dartTypes => commonElements.dartTypes;
NativeBehavior _behavior;
@@ -796,6 +799,7 @@
/// We assume that JS-interop APIs cannot instantiate Dart types or
/// non-JSInterop native types.
void _capture(DartType type, bool isJsInterop) {
+ type = type.withoutNullability;
if (type is FunctionType) {
FunctionType functionType = type;
_capture(functionType.returnType, isJsInterop);
@@ -813,9 +817,7 @@
_behavior.typesInstantiated.add(type);
}
- if (!trustJSInteropTypeAnnotations ||
- type is DynamicType ||
- type == commonElements.objectType) {
+ if (!trustJSInteropTypeAnnotations || dartTypes.isTopType(type)) {
// By saying that only JS-interop types can be created, we prevent
// pulling in every other native type (e.g. all of dart:html) when a
// JS interop API returns dynamic or when we don't trust the type
@@ -842,6 +844,18 @@
_behavior.sideEffects.setAllSideEffects();
}
+ void _addReturnType(DartType type) {
+ _behavior.typesReturned.add(type.withoutNullability);
+
+ // Breakdown nullable type into TypeWithoutNullability|Null.
+ // Pre-nnbd Declared types are nullable, so we also add null in that case.
+ if (type is NullableType ||
+ type is LegacyType ||
+ (!options.useNullSafety && type is! VoidType)) {
+ _behavior.typesReturned.add(commonElements.nullType);
+ }
+ }
+
NativeBehavior buildFieldLoadBehavior(
DartType type,
Iterable<String> createsAnnotations,
@@ -850,11 +864,9 @@
{bool isJsInterop}) {
_behavior = new NativeBehavior();
// TODO(sigmund,sra): consider doing something better for numeric types.
- _behavior.typesReturned.add(!isJsInterop || trustJSInteropTypeAnnotations
+ _addReturnType(!isJsInterop || trustJSInteropTypeAnnotations
? type
: commonElements.dynamicType);
- // Declared types are nullable.
- _behavior.typesReturned.add(commonElements.nullType);
_capture(type, isJsInterop);
_overrideWithAnnotations(
createsAnnotations, returnsAnnotations, lookupType);
@@ -888,13 +900,9 @@
// an interop call returns a DOM type and declares a dynamic return type,
// but otherwise we would include a lot of code by default).
// TODO(sigmund,sra): consider doing something better for numeric types.
- _behavior.typesReturned.add(!isJsInterop || trustJSInteropTypeAnnotations
+ _addReturnType(!isJsInterop || trustJSInteropTypeAnnotations
? returnType
: commonElements.dynamicType);
- if (type.returnType is! VoidType) {
- // Declared types are nullable.
- _behavior.typesReturned.add(commonElements.nullType);
- }
_capture(type, isJsInterop);
for (DartType type in type.optionalParameterTypes) {
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 99c5833..7355060 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -239,6 +239,9 @@
/// Location of the kernel platform `.dill` files.
Uri platformBinaries;
+ /// Whether to print legacy types as T* rather than T.
+ bool printLegacyStars = false;
+
/// URI where the compiler should generate the output source map file.
Uri sourceMapUri;
@@ -332,13 +335,13 @@
/// When null-safety is enabled, whether the compiler should emit code with
/// weak or strong semantics.
- bool useWeakNullSafetySemantics = false;
+ bool _useWeakNullSafetySemantics = true;
/// Whether to use legacy subtype semantics rather than null-safe semantics.
/// This is `true` if null-safety is disabled, i.e. all code is legacy code,
/// or if weak null-safety semantics are being used, since we do not emit
/// warnings.
- bool get useLegacySubtyping => !useNullSafety || useWeakNullSafetySemantics;
+ bool get useLegacySubtyping => !useNullSafety || _useWeakNullSafetySemantics;
/// The path to the file that contains the profiled allocations.
///
@@ -437,6 +440,7 @@
..outputUri = _extractUriOption(options, '--out=')
..platformBinaries =
platformBinaries ?? _extractUriOption(options, '--platform-binaries=')
+ ..printLegacyStars = _hasOption(options, Flags.printLegacyStars)
..sourceMapUri = _extractUriOption(options, '--source-map=')
..omitImplicitChecks = _hasOption(options, Flags.omitImplicitChecks)
..omitAsCasts = _hasOption(options, Flags.omitAsCasts)
@@ -464,11 +468,7 @@
..codegenShards = _extractIntOption(options, '${Flags.codegenShards}=')
..cfeOnly = _hasOption(options, Flags.cfeOnly)
..debugGlobalInference = _hasOption(options, Flags.debugGlobalInference)
- // TODO(sigmund): if no flag is specified, the default should depend on
- // whether the entry point library is opted-in (see
- // https://github.com/dart-lang/language/pull/779)
- ..useWeakNullSafetySemantics =
- _hasOption(options, Flags.noRuntimeNullSafety);
+ .._useWeakNullSafetySemantics = !_hasOption(options, Flags.nullSafety);
}
void validate() {
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index ee11cdb..d1c2c14 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -391,6 +391,8 @@
return options.useNullSafety;
case 'LEGACY':
return options.useLegacySubtyping;
+ case 'PRINT_LEGACY_STARS':
+ return options.printLegacyStars;
default:
return null;
}
@@ -5246,7 +5248,8 @@
inputs.addAll(arguments);
AbstractValue typeMask;
- if (target is FunctionEntity) {
+ if (selector.isGetter && target.isGetter ||
+ !selector.isGetter && target is FunctionEntity) {
typeMask = _typeInferenceMap.getReturnTypeOf(target);
} else {
typeMask = _abstractValueDomain.dynamicType;
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 321de33..cddfa66 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -4543,8 +4543,9 @@
HInstruction get typeInput => inputs[0];
HInstruction get checkedInput => inputs[1];
- AbstractBool evaluate(JClosedWorld closedWorld) =>
- _isTestResult(checkedInput, dartType, checkedAbstractValue, closedWorld);
+ AbstractBool evaluate(JClosedWorld closedWorld, bool useNullSafety) =>
+ _isTestResult(checkedInput, dartType, checkedAbstractValue, closedWorld,
+ useNullSafety);
@override
accept(HVisitor visitor) => visitor.visitIsTest(this);
@@ -4577,8 +4578,9 @@
HInstruction get checkedInput => inputs[0];
- AbstractBool evaluate(JClosedWorld closedWorld) =>
- _isTestResult(checkedInput, dartType, checkedAbstractValue, closedWorld);
+ AbstractBool evaluate(JClosedWorld closedWorld, bool useNullSafety) =>
+ _isTestResult(checkedInput, dartType, checkedAbstractValue, closedWorld,
+ useNullSafety);
@override
accept(HVisitor visitor) => visitor.visitIsTestSimple(this);
@@ -4596,11 +4598,36 @@
String toString() => 'HIsTestSimple()';
}
-AbstractBool _isTestResult(HInstruction expression, DartType dartType,
- AbstractValueWithPrecision checkedAbstractValue, JClosedWorld closedWorld) {
+AbstractBool _isTestResult(
+ HInstruction expression,
+ DartType dartType,
+ AbstractValueWithPrecision checkedAbstractValue,
+ JClosedWorld closedWorld,
+ bool useNullSafety) {
AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
AbstractValue subsetType = expression.instructionType;
AbstractValue supersetType = checkedAbstractValue.abstractValue;
+
+ if (useNullSafety &&
+ expression.isNull(abstractValueDomain).isDefinitelyTrue) {
+ if (closedWorld.dartTypes.isTopType(dartType) ||
+ dartType is NullableType ||
+ dartType.isNull) {
+ return AbstractBool.True;
+ }
+ if (dartType is TypeVariableType || dartType is FunctionTypeVariable) {
+ return AbstractBool.Maybe;
+ }
+ if (dartType is LegacyType) {
+ DartType baseType = dartType.baseType;
+ if (baseType is NeverType) return AbstractBool.True;
+ if (baseType is TypeVariableType || baseType is FunctionTypeVariable) {
+ return AbstractBool.Maybe;
+ }
+ }
+ return AbstractBool.False;
+ }
+
if (checkedAbstractValue.isPrecise &&
abstractValueDomain.isIn(subsetType, supersetType).isDefinitelyTrue) {
return AbstractBool.True;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index e8c6a86..5c12d0b 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -2123,6 +2123,9 @@
@override
HInstruction visitAsCheck(HAsCheck node) {
+ // TODO(fishythefish): Correctly constant fold `null as T` (also in
+ // [visitAsCheckSimple]) when running with strong NNBD. We might get this
+ // for free if nullability is precisely propagated to the typemasks.
if (node.isRedundant(_closedWorld)) return node.checkedInput;
// See if this check can be lowered to a simple one.
@@ -2153,7 +2156,7 @@
@override
HInstruction visitIsTest(HIsTest node) {
- AbstractBool result = node.evaluate(_closedWorld);
+ AbstractBool result = node.evaluate(_closedWorld, _options.useNullSafety);
if (result.isDefinitelyFalse) {
return _graph.addConstantBool(false, _closedWorld);
}
@@ -2199,7 +2202,7 @@
@override
HInstruction visitIsTestSimple(HIsTestSimple node) {
- AbstractBool result = node.evaluate(_closedWorld);
+ AbstractBool result = node.evaluate(_closedWorld, _options.useNullSafety);
if (result.isDefinitelyFalse) {
return _graph.addConstantBool(false, _closedWorld);
}
diff --git a/pkg/compiler/tool/generate_kernel.dart b/pkg/compiler/tool/generate_kernel.dart
index 9a61b87..39fba2c 100644
--- a/pkg/compiler/tool/generate_kernel.dart
+++ b/pkg/compiler/tool/generate_kernel.dart
@@ -28,9 +28,7 @@
..target = new Dart2jsTarget("dart2js", new TargetFlags())
..packagesFileUri = Uri.base.resolve('.packages')
..setExitCodeOnProblem = true
- ..linkedDependencies = [
- Uri.base.resolve(nativeToUriPath(flags['platform']))
- ];
+ ..additionalDills = [Uri.base.resolve(nativeToUriPath(flags['platform']))];
if (flags.rest.isEmpty) {
var script = relativizeUri(Uri.base, Platform.script, false);
diff --git a/pkg/dartfix/lib/src/driver.dart b/pkg/dartfix/lib/src/driver.dart
index 11e3616..1bb0668 100644
--- a/pkg/dartfix/lib/src/driver.dart
+++ b/pkg/dartfix/lib/src/driver.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'dart:io' show File, Platform, stdin;
+import 'dart:io' show File, Platform;
import 'package:analysis_server_client/handler/connection_handler.dart';
import 'package:analysis_server_client/handler/notification_handler.dart';
@@ -16,8 +16,12 @@
import 'package:dartfix/src/context.dart';
import 'package:dartfix/src/options.dart';
import 'package:dartfix/src/util.dart';
+import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
+import 'migrate/display.dart';
+import 'util.dart';
+
class Driver {
Context context;
_Handler handler;
@@ -140,20 +144,7 @@
/// Return `true` if the changes should be applied.
bool shouldApplyFixes(EditDartfixResult result) {
- if (result.edits.isEmpty) {
- logger.stdout('');
- logger.stdout(result.otherSuggestions.isNotEmpty
- ? 'None of the recommended changes can be automatically applied.'
- : 'There are no recommended changes.');
- return false;
- }
- if (overwrite || force) {
- return true;
- }
- logger.stdout('');
- logger.stdout('Would you like to apply these changes? (yes/no)');
- var response = stdin.readLineSync();
- return response.toLowerCase() == 'yes';
+ return overwrite || force;
}
void showDescriptions(String title, List<DartFixSuggestion> suggestions) {
@@ -241,8 +232,6 @@
Progress progress;
if (options.showHelp) {
progress = logger.progress('${ansi.emphasized('Listing fixes')}');
- } else if (options.isUpgrade) {
- progress = logger.progress('${ansi.emphasized('Calculating changes')}');
} else {
progress = logger.progress('${ansi.emphasized('Calculating fixes')}');
}
@@ -280,57 +269,28 @@
editCount += fileEdit.edits.length;
}
logger.stdout('Found $editCount changes in ${fileEdits.length} files.');
+
+ previewFixes(logger, result);
+
//
- // Print instructions for opening the preview tool.
+ // Stop the server.
//
- var urls = result.urls;
- if (urls != null) {
- // Server has already started the preview server.
- if (result.hasErrors) {
- // TODO(brianwilkerson) When we have previews for fixes, tailor the
- // message to be appropriate for fixes.
- logger.stdout('');
- String warning = ansi.emphasized('WARNING');
- logger.stdout('$warning: The unmodified code contains errors that '
- 'might affect the accuracy of the upgrade.');
- options.overwrite = false;
- }
- if (options.isUpgrade && options.upgradeOptions.preview) {
- logger.stdout('');
- String open;
- if (urls.length == 1) {
- open = ansi.emphasized('Please open this URL');
- } else {
- open = ansi.emphasized('Please open these URLs');
- }
- logger.stdout('$open in your browser to see the changes:');
- for (var url in urls) {
- logger.stdout(' $url');
- }
- logger.stdout('');
- String enter = ansi.emphasized('ENTER');
- logger.stdout('When done previewing, press $enter.');
- stdin.readLineSync();
- }
- //
- // Stop the server.
- //
- serverStopped = server.stop();
- if (shouldApplyFixes(result)) {
- applyFixes();
- logger.stdout('Changes have been applied.');
- } else {
- logger.stdout('No changes applied.');
- }
- await serverStopped;
+ serverStopped = server.stop();
+
+ logger.stdout('');
+
+ // Check if we should apply fixes.
+ if (result.edits.isEmpty) {
+ logger.stdout(result.otherSuggestions.isNotEmpty
+ ? 'None of the recommended changes can be automatically applied.'
+ : 'There are no recommended changes.');
+ } else if (shouldApplyFixes(result)) {
+ applyFixes();
+ logger.stdout('Changes have been applied.');
} else {
- //
- // Stop the server.
- //
- serverStopped = server.stop();
- await printAndApplyFixes();
- await serverStopped;
+ logger.stdout('Re-run with --overwrite to apply the above changes.');
}
+ await serverStopped;
} finally {
// If we didn't already try to stop the server, then stop it now.
if (serverStopped == null) {
@@ -398,6 +358,53 @@
The --$option option is not supported by analysis server version $version.
Please upgrade to a newer version of the Dart SDK to use this option.''');
}
+
+ void previewFixes(
+ Logger logger,
+ EditDartfixResult results,
+ ) {
+ final Ansi ansi = logger.ansi;
+
+ Map<String, List<DartFixSuggestion>> fileSuggestions = {};
+ for (DartFixSuggestion suggestion in results.suggestions) {
+ String file = suggestion.location.file;
+ fileSuggestions.putIfAbsent(file, () => <DartFixSuggestion>[]);
+ fileSuggestions[file].add(suggestion);
+ }
+
+ // present a diff-like view
+ for (SourceFileEdit sourceFileEdit in results.edits) {
+ String file = sourceFileEdit.file;
+ String relPath = path.relative(file);
+ int count = sourceFileEdit.edits.length;
+
+ logger.stdout('');
+ logger.stdout('${ansi.emphasized(relPath)} '
+ '($count ${pluralize('change', count)}):');
+
+ String source;
+ try {
+ source = File(file).readAsStringSync();
+ } catch (_) {}
+
+ if (source == null) {
+ logger.stdout(' (unable to retrieve source for file)');
+ } else {
+ SourcePrinter sourcePrinter = SourcePrinter(source);
+
+ List<SourceEdit> edits = sortEdits(sourceFileEdit);
+
+ // Apply edits.
+ sourcePrinter.applyEdits(edits);
+
+ // Render the changed lines.
+ sourcePrinter.processChangedLines((lineNumber, lineText) {
+ String prefix = ' line ${lineNumber.toString().padRight(3)} •';
+ logger.stdout('$prefix ${lineText.trim()}');
+ });
+ }
+ }
+ }
}
class _Handler
@@ -454,15 +461,15 @@
if (version > expectedVersion) {
logger.stdout('''
This version of dartfix is incompatible with the current Dart SDK.
-Try installing a newer version of dartfix by running
+Try installing a newer version of dartfix by running:
pub global activate dartfix
''');
} else {
logger.stdout('''
-This version of dartfix is too new to be used with the current Dart SDK.
-Try upgrading the Dart SDK to a newer version
-or installing an older version of dartfix using
+This version of dartfix is too new to be used with the current Dart SDK. Try
+upgrading the Dart SDK to a newer version or installing an older version of
+dartfix using:
pub global activate dartfix <version>
''');
diff --git a/pkg/dartfix/lib/src/migrate/apply.dart b/pkg/dartfix/lib/src/migrate/apply.dart
index 0120c5c..290c345 100644
--- a/pkg/dartfix/lib/src/migrate/apply.dart
+++ b/pkg/dartfix/lib/src/migrate/apply.dart
@@ -4,14 +4,11 @@
import 'package:analysis_server_client/protocol.dart';
+import '../util.dart';
+
/// Perform the indicated source edits to the given source, returning the
/// resulting transformed text.
String applyEdits(SourceFileEdit sourceFileEdit, String source) {
- // Sort edits in reverse offset order.
- List<SourceEdit> edits = sourceFileEdit.edits.toList();
- edits.sort((a, b) {
- return b.offset - a.offset;
- });
-
+ List<SourceEdit> edits = sortEdits(sourceFileEdit);
return SourceEdit.applySequence(source, edits);
}
diff --git a/pkg/dartfix/lib/src/migrate/display.dart b/pkg/dartfix/lib/src/migrate/display.dart
index 2099835..d14fd8e 100644
--- a/pkg/dartfix/lib/src/migrate/display.dart
+++ b/pkg/dartfix/lib/src/migrate/display.dart
@@ -41,9 +41,21 @@
SourcePrinter(this.source);
- void deleteRange(int offset, int length) {
- // \u001b[31m - red
+ void applyEdits(List<SourceEdit> edits) {
+ for (SourceEdit edit in edits) {
+ if (edit.replacement.isNotEmpty) {
+ // an addition
+ insertText(edit.offset + edit.length, edit.replacement);
+ }
+ if (edit.length != 0) {
+ // a removal
+ deleteRange(edit.offset, edit.length);
+ }
+ }
+ }
+
+ void deleteRange(int offset, int length) {
source = source.substring(0, offset) +
red +
reversed +
diff --git a/pkg/dartfix/lib/src/migrate/migrate.dart b/pkg/dartfix/lib/src/migrate/migrate.dart
index 8d6a497..d008d1a 100644
--- a/pkg/dartfix/lib/src/migrate/migrate.dart
+++ b/pkg/dartfix/lib/src/migrate/migrate.dart
@@ -13,6 +13,7 @@
import 'package:cli_util/cli_logging.dart';
import 'package:path/path.dart' as path;
+import '../util.dart';
import 'apply.dart';
import 'display.dart';
import 'options.dart';
@@ -60,17 +61,46 @@
logger.stdout('Migrating ${options.directory}');
logger.stdout('');
- Progress progress =
- logger.progress('${ansi.emphasized('Analyzing project')}');
-
- Server server =
- Server(listener: logger.isVerbose ? _ServerListener(logger) : null);
+ Progress getProgress(String message) => options.debug
+ ? SimpleProgress(logger, message)
+ : logger.progress(message);
Map<String, List<AnalysisError>> fileErrors = {};
+ bool enableAsserts = false;
+ String instrumentationLogFile;
+ bool profileServer = false;
+ String serverPath = options.serverPath;
+ int servicesPort;
+ String sdkPath = options.sdkPath;
+ bool stdioPassthrough = false;
+
+ if (options.debug) {
+ enableAsserts = true;
+ profileServer = true;
+ servicesPort = 9500;
+ stdioPassthrough = true;
+ instrumentationLogFile = path.join(
+ Directory.systemTemp.createTempSync('migration_debug').path,
+ 'instrumentationLog');
+ logger.stdout('Instrumentation log file: ${instrumentationLogFile}');
+ }
+
+ Progress progress = getProgress('${ansi.emphasized('Analyzing project')}');
+
+ Server server = Server(
+ listener: logger.isVerbose ? _ServerListener(logger) : null,
+ stdioPassthrough: stdioPassthrough);
try {
await server.start(
- clientId: 'dart $name', clientVersion: _dartSdkVersion);
+ clientId: 'dart $name',
+ clientVersion: _dartSdkVersion,
+ enableAsserts: enableAsserts,
+ instrumentationLogFile: instrumentationLogFile,
+ profileServer: profileServer,
+ serverPath: serverPath,
+ servicesPort: servicesPort,
+ sdkPath: sdkPath);
_ServerNotifications serverNotifications = _ServerNotifications(server);
await serverNotifications.listenToServer(server);
@@ -106,7 +136,7 @@
int issueCount =
fileErrors.values.map((list) => list.length).reduce((a, b) => a + b);
logger.stdout(
- '$issueCount analysis ${_pluralize('issue', issueCount)} found:');
+ '$issueCount analysis ${pluralize('issue', issueCount)} found:');
_displayIssues(
logger,
options.directory,
@@ -134,9 +164,8 @@
// Calculate migration suggestions.
logger.stdout('');
- progress = logger
- .progress('${ansi.emphasized('Generating migration suggestions')}');
-
+ progress =
+ getProgress('${ansi.emphasized('Generating migration suggestions')}');
Map<String, dynamic> json;
try {
@@ -163,8 +192,8 @@
migrationResults.edits.map((edit) => edit.file).toList();
logger.stdout('Found ${allEdits.length} '
- 'suggested ${_pluralize('change', allEdits.length)} in '
- '${files.length} ${_pluralize('file', files.length)}.');
+ 'suggested ${pluralize('change', allEdits.length)} in '
+ '${files.length} ${pluralize('file', files.length)}.');
logger.stdout('');
@@ -175,24 +204,30 @@
logger.stdout('');
logger.stdout(
- 'Applied ${allEdits.length} ${_pluralize('edit', allEdits.length)}.');
+ 'Applied ${allEdits.length} ${pluralize('edit', allEdits.length)}.');
+ // Note: do not open the web preview if apply-changes is specified, as we
+ // currently cannot tell the web preview to disable the "apply migration"
+ // button.
return 0;
}
if (options.webPreview) {
String url = migrationResults.urls.first;
- logger.stdout(ansi.emphasized('Migration results available:'));
- logger.stdout('Visit $url to see the migration results.');
+ logger.stdout(ansi.emphasized('View migration results:'));
// TODO(devoncarew): Open a browser automatically.
+ logger.stdout('''
+Visit:
+
+ ${ansi.emphasized(url)}
- logger.stdout('');
- logger.stdout('To apply these changes, re-run the tool with '
- '--${MigrateOptions.applyChangesOption}.');
+to see the migration results. Use the interactive web view to review, improve, or apply
+the results (alternatively, to apply the results without using the web preview, re-run
+the tool with --${MigrateOptions.applyChangesOption}).
+''');
- logger.stdout('');
logger.stdout('When finished with the preview, hit ctrl-c '
'to terminate this process.');
@@ -284,7 +319,7 @@
logger.stdout('');
logger.stdout('${ansi.emphasized(relPath)} '
- '($count ${_pluralize('change', count)}):');
+ '($count ${pluralize('change', count)}):');
String source;
try {
@@ -296,24 +331,10 @@
} else {
SourcePrinter sourcePrinter = SourcePrinter(source);
- // Sort edits in reverse offset order.
- List<SourceEdit> edits = sourceFileEdit.edits;
- edits.sort((a, b) {
- return b.offset - a.offset;
- });
+ List<SourceEdit> edits = sortEdits(sourceFileEdit);
- for (SourceEdit edit in sourceFileEdit.edits) {
- if (edit.replacement.isNotEmpty) {
- // an addition
- sourcePrinter.insertText(
- edit.offset + edit.length, edit.replacement);
- }
-
- if (edit.length != 0) {
- // a removal
- sourcePrinter.deleteRange(edit.offset, edit.length);
- }
- }
+ // Apply edits.
+ sourcePrinter.applyEdits(edits);
// Render the changed lines.
sourcePrinter.processChangedLines((lineNumber, lineText) {
@@ -333,7 +354,7 @@
for (SourceFileEdit sourceFileEdit in migrationResults.edits) {
String relPath = path.relative(sourceFileEdit.file, from: directory);
int count = sourceFileEdit.edits.length;
- logger.stdout(' $relPath ($count ${_pluralize('change', count)})');
+ logger.stdout(' $relPath ($count ${pluralize('change', count)})');
String source;
try {
@@ -441,5 +462,3 @@
return version;
}
-
-String _pluralize(String word, int count) => count == 1 ? word : '${word}s';
diff --git a/pkg/dartfix/lib/src/migrate/options.dart b/pkg/dartfix/lib/src/migrate/options.dart
index d72394a..20e2e67 100644
--- a/pkg/dartfix/lib/src/migrate/options.dart
+++ b/pkg/dartfix/lib/src/migrate/options.dart
@@ -9,17 +9,27 @@
import 'package:path/path.dart' as path;
class MigrateOptions {
- static const ignoreErrorsOption = 'ignore-errors';
static const applyChangesOption = 'apply-changes';
+ static const debugOption = 'debug';
+ static const ignoreErrorsOption = 'ignore-errors';
+ static const sdkPathOption = 'sdk-path';
+ static const serverPathOption = 'server-path';
+ static const webPreviewOption = 'web-preview';
- final String directory;
final bool applyChanges;
+ final bool debug;
+ final String directory;
final bool ignoreErrors;
+ final String serverPath;
+ final String sdkPath;
final bool webPreview;
MigrateOptions(ArgResults argResults, this.directory)
: applyChanges = argResults[applyChangesOption] as bool,
+ debug = argResults[debugOption] as bool,
ignoreErrors = argResults[ignoreErrorsOption] as bool,
+ sdkPath = argResults[sdkPathOption] as String,
+ serverPath = argResults[serverPathOption] as String,
webPreview = argResults['web-preview'] as bool;
String get directoryAbsolute => Directory(path.canonicalize(directory)).path;
@@ -37,14 +47,32 @@
help: 'Apply the proposed null safety changes to the files on disk.',
);
argParser.addFlag(
+ debugOption,
+ defaultsTo: false,
+ hide: true,
+ negatable: true,
+ help: 'Show (very verbose) debugging information to stdout during '
+ 'migration',
+ );
+ argParser.addFlag(
ignoreErrorsOption,
defaultsTo: false,
negatable: false,
help: 'Attempt to perform null safety analysis even if there are '
'analysis errors in the project.',
);
+ argParser.addOption(
+ sdkPathOption,
+ hide: true,
+ help: 'Override the SDK path used for migration.',
+ );
+ argParser.addOption(
+ serverPathOption,
+ hide: true,
+ help: 'Override the analysis server path used for migration.',
+ );
argParser.addFlag(
- 'web-preview',
+ webPreviewOption,
defaultsTo: true,
negatable: true,
help: 'Show an interactive preview of the proposed null safety changes '
diff --git a/pkg/dartfix/lib/src/options.dart b/pkg/dartfix/lib/src/options.dart
index 24a5d37..b6d2cbb 100644
--- a/pkg/dartfix/lib/src/options.dart
+++ b/pkg/dartfix/lib/src/options.dart
@@ -21,11 +21,9 @@
const _binaryName = 'dartfix';
const _colorOption = 'color';
-const _dependencies = 'migrate-dependencies';
// options only supported by server 1.22.2 and greater
const _helpOption = 'help';
-const _previewOption = 'preview';
const _serverSnapshot = 'server';
// options not supported yet by any server
@@ -36,7 +34,6 @@
final Context context;
Logger logger;
- UpgradeOptions upgradeOptions;
List<String> targets;
final String sdkPath;
final String serverSnapshot;
@@ -66,8 +63,6 @@
: null,
verbose = results[_verboseOption] as bool;
- bool get isUpgrade => upgradeOptions != null;
-
String makeAbsoluteAndNormalize(String target) {
if (!path.isAbsolute(target)) {
target = path.join(context.workingDir, target);
@@ -118,21 +113,6 @@
help: 'Use ansi colors when printing messages.',
defaultsTo: Ansi.terminalSupportsAnsi);
- //
- // Commands.
- //
- parser.addCommand('upgrade')
- ..addFlag(_dependencies,
- help: 'Upgrade dependencies automatically (not yet implemented)',
- defaultsTo: false,
- negatable: true,
- hide: true)
- ..addFlag(_previewOption,
- help: 'Open the preview tool to view changes.',
- defaultsTo: true,
- negatable: true,
- hide: true);
-
context ??= Context();
ArgResults results;
@@ -177,43 +157,6 @@
context.exit(19);
}
- var command = results.command;
- if (command != null) {
- if (command.name == 'upgrade') {
- options.upgradeOptions = UpgradeOptions._fromCommand(results.command);
- var rest = command.rest;
- if (rest.isNotEmpty) {
- if (rest[0] == 'sdk') {
- if (results.wasParsed(includeFixOption)) {
- logger.stderr('Cannot define includeFixes when using upgrade.');
- context.exit(22);
- }
- if (results.wasParsed(excludeFixOption)) {
- logger.stderr('Cannot define excludeFixes when using upgrade.');
- context.exit(22);
- }
- if (results.wasParsed(pedanticOption) && options.pedanticFixes) {
- logger.stderr('Cannot use pedanticFixes when using upgrade.');
- context.exit(22);
- }
- // TODO(jcollins-g): prevent non-nullable outside of upgrade
- // command.
- options.includeFixes.add('non-nullable');
- if (rest.length > 1) {
- options.targets = command.rest.sublist(1);
- } else {
- options.targets = [Directory.current.path];
- }
- } else {
- logger
- .stderr('Missing or invalid specification of what to upgrade.');
- logger.stderr("(Currently 'sdk' is the only supported option.)");
- context.exit(22);
- }
- }
- }
- }
-
// Check for files and/or directories to analyze.
if (options.targets == null || options.targets.isEmpty) {
logger.stderr('Expected at least one file or directory to analyze.');
@@ -265,13 +208,3 @@
: '');
}
}
-
-/// Command line options for `dartfix upgrade`.
-class UpgradeOptions {
- final bool dependencies;
- final bool preview;
-
- UpgradeOptions._fromCommand(ArgResults results)
- : dependencies = results[_dependencies] as bool,
- preview = results[_previewOption] as bool;
-}
diff --git a/pkg/dartfix/lib/src/util.dart b/pkg/dartfix/lib/src/util.dart
index b3935f8..07ad858 100644
--- a/pkg/dartfix/lib/src/util.dart
+++ b/pkg/dartfix/lib/src/util.dart
@@ -56,3 +56,14 @@
? message.substring(0, message.length - 1)
: message;
}
+
+String pluralize(String word, int count) => count == 1 ? word : '${word}s';
+
+List<SourceEdit> sortEdits(SourceFileEdit sourceFileEdit) {
+ // Sort edits in reverse offset order.
+ List<SourceEdit> edits = sourceFileEdit.edits.toList();
+ edits.sort((a, b) {
+ return b.offset - a.offset;
+ });
+ return edits;
+}
diff --git a/pkg/dartfix/test/src/options_test.dart b/pkg/dartfix/test/src/options_test.dart
index ff91250..9843fab 100644
--- a/pkg/dartfix/test/src/options_test.dart
+++ b/pkg/dartfix/test/src/options_test.dart
@@ -139,29 +139,6 @@
test('verbose', () {
parse(['--verbose', 'foo'], verbose: true);
});
-
- group('upgrade', () {
- group('sdk', () {
- test('no target', () {
- var options = parse(['upgrade', 'sdk'], includeFixes: ['non-nullable']);
- expect(options.targets, hasLength(1));
- });
-
- test('target', () {
- var target = p('/pkg/foo');
- var options =
- parse(['upgrade', 'sdk', target], includeFixes: ['non-nullable']);
- expect(options.targets, [target]);
- });
-
- test('dependencies', () {
- var options = parse(
- ['upgrade', 'sdk', '--migrate-dependencies', p('/pkg/foo')],
- includeFixes: ['non-nullable']);
- expect(options.upgradeOptions.dependencies, isTrue);
- });
- });
- });
}
void expectContains(Iterable<String> collection, String suffix) {
@@ -172,9 +149,3 @@
}
fail('Expected one of $collection\n to end with "$suffix"');
}
-
-void expectOneFileTarget(Options options, String fileName) {
- expect(options.targets, hasLength(1));
- final target = options.targets[0];
- expect(target.endsWith(fileName), isTrue);
-}
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_command.dart b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
index 435c241..cc4011d 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_command.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
@@ -66,9 +66,6 @@
/// This is required for a modular build process.
final bool summarizeApi;
- /// Whether to preserve metdata only accessible via mirrors.
- final bool emitMetadata;
-
// Whether to enable assertions.
final bool enableAsserts;
@@ -98,7 +95,6 @@
{this.sourceMap = true,
this.inlineSourceMap = false,
this.summarizeApi = true,
- this.emitMetadata = false,
this.enableAsserts = true,
this.replCompile = false,
this.summaryModules = const {},
@@ -112,7 +108,6 @@
sourceMap: args['source-map'] as bool,
inlineSourceMap: args['inline-source-map'] as bool,
summarizeApi: args['summarize'] as bool,
- emitMetadata: args['emit-metadata'] as bool,
enableAsserts: args['enable-asserts'] as bool,
experiments: parseExperimentalArguments(
args['enable-experiment'] as List<String>),
@@ -139,8 +134,6 @@
help: 'emit source mapping', defaultsTo: true, hide: hide)
..addFlag('inline-source-map',
help: 'emit source mapping inline', defaultsTo: false, hide: hide)
- ..addFlag('emit-metadata',
- help: 'emit metadata annotations queriable via mirrors', hide: hide)
..addFlag('enable-asserts',
help: 'enable assertions', defaultsTo: true, hide: hide)
..addOption('module-name',
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index b7524cc..04b3e86 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -255,11 +255,11 @@
var compileSdk = argResults['compile-sdk'] == true;
var oldCompilerState = compilerState;
- List<Component> doneInputSummaries;
+ List<Component> doneAdditionalDills;
fe.IncrementalCompiler incrementalCompiler;
fe.WorkerInputComponent cachedSdkInput;
var recordUsedInputs = argResults['used-inputs-file'] != null;
- var inputSummaries = summaryModules.keys.toList();
+ var additionalDills = summaryModules.keys.toList();
if (!useIncrementalCompiler) {
compilerState = await fe.initializeCompiler(
oldCompilerState,
@@ -268,7 +268,7 @@
compileSdk ? null : sourcePathToUri(sdkSummaryPath),
sourcePathToUri(packageFile),
sourcePathToUri(librarySpecPath),
- inputSummaries,
+ additionalDills,
DevCompilerTarget(TargetFlags(
trackWidgetCreation: trackWidgetCreation,
enableNullSafety: options.enableNullSafety)),
@@ -290,7 +290,7 @@
}
}
- doneInputSummaries = List<Component>(summaryModules.length);
+ doneAdditionalDills = List<Component>(summaryModules.length);
compilerState = await fe.initializeIncrementalCompiler(
oldCompilerState,
{
@@ -298,13 +298,13 @@
'multiRootScheme=${fileSystem.markerScheme}',
'multiRootRoots=${fileSystem.roots}',
},
- doneInputSummaries,
+ doneAdditionalDills,
compileSdk,
sourcePathToUri(getSdkPath()),
compileSdk ? null : sourcePathToUri(sdkSummaryPath),
sourcePathToUri(packageFile),
sourcePathToUri(librarySpecPath),
- inputSummaries,
+ additionalDills,
inputDigests,
DevCompilerTarget(TargetFlags(
trackWidgetCreation: trackWidgetCreation,
@@ -332,7 +332,7 @@
var incrementalComponent = await incrementalCompiler.computeDelta(
entryPoints: inputs, fullComponent: true);
result = fe.DdcResult(incrementalComponent, cachedSdkInput.component,
- doneInputSummaries, incrementalCompiler.userCode.loader.hierarchy);
+ doneAdditionalDills, incrementalCompiler.userCode.loader.hierarchy);
}
compilerState.options.onDiagnostic = null; // See http://dartbug.com/36983.
@@ -348,10 +348,6 @@
if (!librariesFromDill.contains(lib)) compiledLibraries.libraries.add(lib);
}
- if (!options.emitMetadata && _checkForDartMirrorsImport(compiledLibraries)) {
- return CompilerResult(1, kernelState: compilerState);
- }
-
// Output files can be written in parallel, so collect the futures.
var outFiles = <Future>[];
if (argResults['summarize'] as bool) {
@@ -390,13 +386,13 @@
final importToSummary = Map<Library, Component>.identity();
final summaryToModule = Map<Component, String>.identity();
- for (var i = 0; i < result.inputSummaries.length; i++) {
- var summary = result.inputSummaries[i];
- var moduleImport = summaryModules[inputSummaries[i]];
- for (var l in summary.libraries) {
+ for (var i = 0; i < result.additionalDills.length; i++) {
+ var additionalDill = result.additionalDills[i];
+ var moduleImport = summaryModules[additionalDills[i]];
+ for (var l in additionalDill.libraries) {
assert(!importToSummary.containsKey(l));
- importToSummary[l] = summary;
- summaryToModule[summary] = moduleImport;
+ importToSummary[l] = additionalDill;
+ summaryToModule[additionalDill] = moduleImport;
}
}
@@ -631,21 +627,6 @@
final defaultLibrarySpecPath = p.join(getSdkPath(), 'lib', 'libraries.json');
-bool _checkForDartMirrorsImport(Component component) {
- for (var library in component.libraries) {
- if (library.importUri.scheme == 'dart') continue;
- for (var dep in library.dependencies) {
- var uri = dep.targetLibrary.importUri;
- if (uri.scheme == 'dart' && uri.path == 'mirrors') {
- print('${library.importUri}: Error: Cannot import "dart:mirrors" '
- 'in web applications (https://goo.gl/R1anEs).');
- return true;
- }
- }
- }
- return false;
-}
-
/// Returns the absolute path to the default `.packages` file, or `null` if one
/// could not be found.
///
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 1ff7e3c..e36af94 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -348,15 +348,15 @@
// emitted before dart.defineLazy.
if (_constLazyAccessors.isNotEmpty) {
var constTableBody = runtimeStatement(
- 'defineLazy(#, { # })', [_constTable, _constLazyAccessors]);
+ 'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors]);
moduleItems.insert(_constTableInsertionIndex, constTableBody);
_constLazyAccessors.clear();
}
// Add assert locations
_uriMap.forEach((location, id) {
- moduleItems
- .add(js.statement('var # = #;', [id, js.escapedString(location)]));
+ moduleItems.insert(_constTableInsertionIndex,
+ js.statement('var # = #;', [id, js.escapedString(location)]));
});
moduleItems.addAll(afterClassDefItems);
@@ -588,13 +588,18 @@
var finishGenericTypeTest = _emitClassTypeTests(c, className, body);
+ // Attach caches on all canonicalized types not in our runtime.
+ // Types in the runtime will have caches attached in their constructors.
+ if (!isSdkInternalRuntime(_currentLibrary)) {
+ body.add(runtimeStatement('addTypeCaches(#)', [className]));
+ }
+
_emitVirtualFieldSymbols(c, body);
_emitClassSignature(c, className, body);
_initExtensionSymbols(c);
if (!c.isMixinDeclaration) {
_defineExtensionMembers(className, body);
}
- _emitClassMetadata(c.annotations, className, body);
var classDef = js_ast.Statement.from(body);
var typeFormals = c.typeParameters;
@@ -1156,19 +1161,6 @@
}
}
- void _emitClassMetadata(List<Expression> metadata,
- js_ast.Expression className, List<js_ast.Statement> body) {
- // Metadata
- if (_options.emitMetadata && metadata.isNotEmpty) {
- body.add(js.statement('#[#.metadata] = #;', [
- className,
- runtimeModule,
- _arrowFunctionWithLetScope(() => js_ast.ArrayInitializer(
- metadata.map(_instantiateAnnotation).toList()))
- ]));
- }
- }
-
/// Ensure `dartx.` symbols we will use are present.
void _initExtensionSymbols(Class c) {
if (_extensionTypes.hasNativeSubtype(c) || c == _coreTypes.objectClass) {
@@ -1266,7 +1258,7 @@
for (var member in classProcedures) {
// Static getters/setters/methods cannot be called with dynamic dispatch,
// nor can they be torn off.
- if (!_options.emitMetadata && member.isStatic) continue;
+ if (member.isStatic) continue;
var name = member.name.name;
var reifiedType = _memberRuntimeType(member, c) as FunctionType;
@@ -1287,14 +1279,11 @@
if (needsSignature) {
js_ast.Expression type;
if (member.isAccessor) {
- type = _emitAnnotatedResult(
- _emitType(member.isGetter
- ? reifiedType.returnType
- : reifiedType.positionalParameters[0]),
- member.annotations,
- member);
+ type = _emitType(member.isGetter
+ ? reifiedType.returnType
+ : reifiedType.positionalParameters[0]);
} else {
- type = _emitAnnotatedFunctionType(reifiedType, member);
+ type = visitFunctionType(reifiedType, member: member);
}
var property = js_ast.Property(_declareMemberName(member), type);
var signatures = getSignatureList(member);
@@ -1323,7 +1312,7 @@
for (var field in classFields) {
// Only instance fields need to be saved for dynamic dispatch.
var isStatic = field.isStatic;
- if (!_options.emitMetadata && isStatic) continue;
+ if (isStatic) continue;
var memberName = _declareMemberName(field);
var fieldSig = _emitFieldSignature(field, c);
@@ -1333,24 +1322,6 @@
emitSignature('Field', instanceFields);
emitSignature('StaticField', staticFields);
- if (_options.emitMetadata) {
- var constructors = <js_ast.Property>[];
- var allConstructors = [
- ...c.constructors,
- ...c.procedures.where((p) => p.isFactory),
- ];
- for (var ctor in allConstructors) {
- var memberName = _constructorName(ctor.name.name);
- var type = _emitAnnotatedFunctionType(
- ctor.function
- .computeThisFunctionType(c.enclosingLibrary.nonNullable)
- .withoutTypeParameters,
- ctor);
- constructors.add(js_ast.Property(memberName, type));
- }
- emitSignature('Constructor', constructors);
- }
-
// Add static property dart._runtimeType to Object.
// All other Dart classes will (statically) inherit this property.
if (c == _coreTypes.objectClass) {
@@ -1364,16 +1335,6 @@
js_ast.Expression _emitFieldSignature(Field field, Class fromClass) {
var type = _typeFromClass(field.type, field.enclosingClass, fromClass);
var args = [_emitType(type)];
- var annotations = field.annotations;
- if (_options.emitMetadata &&
- annotations != null &&
- annotations.isNotEmpty) {
- var savedUri = _currentUri;
- _currentUri = field.enclosingClass.fileUri;
- args.add(js_ast.ArrayInitializer(
- annotations.map(_instantiateAnnotation).toList()));
- _currentUri = savedUri;
- }
return runtimeCall(
field.isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
}
@@ -2061,9 +2022,6 @@
]) as js_ast.Fun);
}
- js_ast.Expression _instantiateAnnotation(Expression node) =>
- _visitExpression(node);
-
void _registerExtensionType(
Class c, String jsPeerName, List<js_ast.Statement> body) {
var className = _emitTopLevelName(c);
@@ -2148,10 +2106,13 @@
}
_staticTypeContext.leaveMember(field);
}
- _currentUri = _currentLibrary.fileUri;
-
_currentUri = savedUri;
- return runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]);
+
+ return runtimeStatement('defineLazy(#, { # }, #)', [
+ objExpr,
+ accessors,
+ js.boolean(!_currentLibrary.isNonNullableByDefault)
+ ]);
}
js_ast.Fun _emitStaticFieldInitializer(Field field) {
@@ -2175,19 +2136,6 @@
return body;
}
- js_ast.ArrowFun _arrowFunctionWithLetScope(
- js_ast.Expression Function() visitBody) {
- var savedLetVariables = _letVariables;
- _letVariables = [];
-
- var expr = visitBody();
- var letVars = _initLetVariables();
-
- _letVariables = savedLetVariables;
- return js_ast.ArrowFun(
- [], letVars == null ? expr : js_ast.Block([letVars, expr.toReturn()]));
- }
-
js_ast.PropertyAccess _emitTopLevelName(NamedNode n, {String suffix = ''}) {
return _emitJSInterop(n) ?? _emitTopLevelNameNoInterop(n, suffix: suffix);
}
@@ -2534,18 +2482,6 @@
var nameExpr = _emitTopLevelName(p);
body.add(js.statement('# = #',
[nameExpr, js_ast.NamedFunction(_emitTemporaryId(p.name.name), fn)]));
- // Function types of top-level/static functions are only needed when
- // dart:mirrors is enabled.
- // TODO(jmesserly): do we even need this for mirrors, since statics are not
- // commonly reflected on?
- if (_options.emitMetadata && _reifyFunctionType(p.function)) {
- body.add(_emitFunctionTagged(
- nameExpr,
- p.function
- .computeThisFunctionType(p.enclosingLibrary.nonNullable),
- topLevel: true)
- .toStatement());
- }
_currentUri = savedUri;
_staticTypeContext.leaveMember(p);
@@ -2881,24 +2817,6 @@
return _emitNullabilityWrapper(typeRep, type.nullability);
}
- js_ast.Expression _emitAnnotatedFunctionType(
- FunctionType type, Member member) {
- var result = visitFunctionType(type, member: member);
-
- var annotations = member.annotations;
- if (_options.emitMetadata && annotations.isNotEmpty) {
- // TODO(jmesserly): should we disable source info for annotations?
- var savedUri = _currentUri;
- _currentUri = member.enclosingClass.fileUri;
- result = js_ast.ArrayInitializer([
- result,
- for (var annotation in annotations) _instantiateAnnotation(annotation)
- ]);
- _currentUri = savedUri;
- }
- return result;
- }
-
/// Emits an expression that lets you access statics on a [type] from code.
js_ast.Expression _emitConstructorAccess(InterfaceType type) {
return _emitJSInterop(type.classNode) ??
@@ -2917,21 +2835,6 @@
return _emitTopLevelName(c);
}
- // Wrap a result - usually a type - with its metadata. The runtime is
- // responsible for unpacking this.
- js_ast.Expression _emitAnnotatedResult(
- js_ast.Expression result, List<Expression> metadata, Member member) {
- if (_options.emitMetadata && metadata.isNotEmpty) {
- // TODO(jmesserly): should we disable source info for annotations?
- var savedUri = _currentUri;
- _currentUri = member.enclosingClass.fileUri;
- result = js_ast.ArrayInitializer(
- [result, for (var value in metadata) _instantiateAnnotation(value)]);
- _currentUri = savedUri;
- }
- return result;
- }
-
/// Emits named parameters in the form '{name: type}'.
js_ast.ObjectInitializer _emitTypeProperties(Iterable<NamedType> types) {
return js_ast.ObjectInitializer(types
@@ -2943,17 +2846,8 @@
///
/// Annotatable contexts include typedefs and method/function declarations.
js_ast.ArrayInitializer _emitTypeNames(List<DartType> types,
- List<VariableDeclaration> parameters, Member member) {
- var result = <js_ast.Expression>[];
- for (var i = 0; i < types.length; ++i) {
- var type = _emitType(types[i]);
- if (parameters != null) {
- type = _emitAnnotatedResult(type, parameters[i].annotations, member);
- }
- result.add(type);
- }
- return js_ast.ArrayInitializer(result);
- }
+ List<VariableDeclaration> parameters, Member member) =>
+ js_ast.ArrayInitializer([for (var type in types) _emitType(type)]);
@override
js_ast.Expression visitTypeParameterType(TypeParameterType type) =>
@@ -3279,7 +3173,8 @@
body.add(js.statement('if (# == null) return false;', [jsParam]));
} else if (_annotatedNullCheck(p.annotations)) {
body.add(_nullParameterCheck(jsParam));
- } else if (_mustBeNonNullable(p.type)) {
+ } else if (_mustBeNonNullable(p.type) &&
+ !_annotatedNotNull(p.annotations)) {
// TODO(vsm): Remove if / when CFE does this:
// https://github.com/dart-lang/sdk/issues/40597
// The check on `p.type` is per:
@@ -3335,6 +3230,9 @@
bool _annotatedNullCheck(List<Expression> annotations) =>
annotations.any(_nullableInference.isNullCheckAnnotation);
+ bool _annotatedNotNull(List<Expression> annotations) =>
+ annotations.any(_nullableInference.isNotNullAnnotation);
+
bool _reifyGenericFunction(Member m) =>
m == null ||
m.enclosingLibrary.importUri.scheme != 'dart' ||
@@ -4857,21 +4755,35 @@
if (target.isFactory) return _emitFactoryInvocation(node);
// Optimize some internal SDK calls.
- if (isSdkInternalRuntime(target.enclosingLibrary) &&
- node.arguments.positional.length == 1) {
- var name = target.name.name;
- var firstArg = node.arguments.positional[0];
- if (name == 'getGenericClass' && firstArg is TypeLiteral) {
- var type = firstArg.type;
- if (type is InterfaceType) {
- return _emitTopLevelNameNoInterop(type.classNode, suffix: '\$');
+ if (isSdkInternalRuntime(target.enclosingLibrary)) {
+ if (node.arguments.positional.length == 1) {
+ var name = target.name.name;
+ var firstArg = node.arguments.positional[0];
+ if (name == 'getGenericClass' && firstArg is TypeLiteral) {
+ var type = firstArg.type;
+ if (type is InterfaceType) {
+ return _emitTopLevelNameNoInterop(type.classNode, suffix: '\$');
+ }
}
- }
- if (name == 'unwrapType' && firstArg is TypeLiteral) {
- return _emitType(firstArg.type);
- }
- if (name == 'extensionSymbol' && firstArg is StringLiteral) {
- return getExtensionSymbolInternal(firstArg.value);
+ if (name == 'unwrapType' && firstArg is TypeLiteral) {
+ return _emitType(firstArg.type);
+ }
+ if (name == 'extensionSymbol' && firstArg is StringLiteral) {
+ return getExtensionSymbolInternal(firstArg.value);
+ }
+ } else if (node.arguments.positional.length == 2) {
+ var name = target.name.name;
+ var firstArg = node.arguments.positional[0];
+ var secondArg = node.arguments.positional[1];
+ if (name == '_jsInstanceOf' && secondArg is TypeLiteral) {
+ return js.call('# instanceof #',
+ [_visitExpression(firstArg), _emitType(secondArg.type)]);
+ }
+
+ if (name == '_equalType' && secondArg is TypeLiteral) {
+ return js.call('# === #',
+ [_visitExpression(firstArg), _emitType(secondArg.type)]);
+ }
}
}
if (target == _coreTypes.identicalProcedure) {
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 82341ab..acf7573 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -23,6 +23,7 @@
class DevCompilerTarget extends Target {
DevCompilerTarget(this.flags);
+ @override
final TargetFlags flags;
WidgetCreatorTracker _widgetTracker;
diff --git a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
index 22cd4cc..1a63f96 100644
--- a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
@@ -1,6 +1,6 @@
-ERROR|COMPILE_TIME_ERROR|BODY_MIGHT_COMPLETE_NORMALLY|lib/_internal/js_runtime/lib/js_helper.dart|2688|17|17|The body might complete normally, which would cause 'null' to be returned, but the return type is a potentially non-nullable type.
-ERROR|COMPILE_TIME_ERROR|BODY_MIGHT_COMPLETE_NORMALLY|lib/_internal/js_runtime/lib/js_helper.dart|3628|5|11|The body might complete normally, which would cause 'null' to be returned, but the return type is a potentially non-nullable type.
-ERROR|COMPILE_TIME_ERROR|BODY_MIGHT_COMPLETE_NORMALLY|lib/_internal/js_runtime/lib/js_helper.dart|3656|5|6|The body might complete normally, which would cause 'null' to be returned, but the return type is a potentially non-nullable type.
+ERROR|COMPILE_TIME_ERROR|BODY_MIGHT_COMPLETE_NORMALLY|lib/_internal/js_runtime/lib/js_helper.dart|2689|17|17|The body might complete normally, which would cause 'null' to be returned, but the return type is a potentially non-nullable type.
+ERROR|COMPILE_TIME_ERROR|BODY_MIGHT_COMPLETE_NORMALLY|lib/_internal/js_runtime/lib/js_helper.dart|3629|5|11|The body might complete normally, which would cause 'null' to be returned, but the return type is a potentially non-nullable type.
+ERROR|COMPILE_TIME_ERROR|BODY_MIGHT_COMPLETE_NORMALLY|lib/_internal/js_runtime/lib/js_helper.dart|3657|5|6|The body might complete normally, which would cause 'null' to be returned, but the return type is a potentially non-nullable type.
ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1637|7|5|Superinterfaces don't have a valid override for '&': int.& (int Function(int)), JSNumber.& (num Function(num)).
ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1637|7|5|Superinterfaces don't have a valid override for '<<': int.<< (int Function(int)), JSNumber.<< (num Function(num)).
ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1637|7|5|Superinterfaces don't have a valid override for '>>': int.>> (int Function(int)), JSNumber.>> (num Function(num)).
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index c9b519d..07bb9a3 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -7,7 +7,8 @@
import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
show DiagnosticMessageHandler;
-import 'package:kernel/ast.dart' as kernel show Library;
+import 'package:kernel/default_language_version.dart' as kernel
+ show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
import 'package:kernel/target/targets.dart' show Target;
@@ -24,6 +25,8 @@
import 'standard_file_system.dart' show StandardFileSystem;
+import '../api_unstable/util.dart';
+
export 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
show DiagnosticMessage;
@@ -65,29 +68,14 @@
/// will be used.
Uri packagesFileUri;
- /// URIs of input summary files (excluding the SDK summary; typically these
- /// will be "file:" URIs).
+ /// URIs of additional dill files.
///
- /// These files should be summary files generated by this package (and not the
- /// similarly named summary files from `package:analyzer`.)
+ /// These will be loaded and linked into the output.
///
- /// Summaries may be provided in any order, but they should be acyclic and
- /// closed: any libraries that they reference should be defined in either one
- /// of [inputSummaries] or [sdkSummary].
- List<Uri> inputSummaries = [];
-
- /// URIs of other kernel components to link.
- ///
- /// Commonly used to link the code for the SDK libraries that was compiled
- /// separately. For example, dart2js needs to link the SDK so it can
- /// optimize and tree-shake the code for the application, whereas the VM
- /// always embeds the SDK internally and doesn't need it as part of the
- /// program.
- ///
- /// The components provided here should be closed and acyclic: any libraries
- /// that they reference should be defined in a component in
- /// [linkedDependencies] or any of the [inputSummaries] or [sdkSummary].
- List<Uri> linkedDependencies = [];
+ /// The components provided here should be closed: any libraries that they
+ /// reference should be defined in a component in [additionalDills] or
+ /// [sdkSummary].
+ List<Uri> additionalDills = [];
/// URI of the SDK summary file (typically a "file:" URI).
///
@@ -116,7 +104,7 @@
/// When this option is `true`, [sdkSummary] must be null.
bool compileSdk = false;
- @deprecated
+ @Deprecated("Unused internally.")
bool chaseDependencies;
/// Patch files to apply on the core libraries for a specific target platform.
@@ -133,6 +121,7 @@
/// directly, while relative URIs are resolved from the [sdkRoot].
// TODO(sigmund): provide also a flag to load this data from a file (like
// libraries.json)
+ @Deprecated("Unused internally.")
Map<String, List<Uri>> targetPatches = <String, List<Uri>>{};
/// Enable or disable experimental features. Features mapping to `true` are
@@ -167,6 +156,7 @@
/// Deprecated. Has no affect on front-end.
// TODO(dartbug.com/37514) Remove this field once DDK removes its uses of it.
+ @Deprecated("Unused internally.")
bool enableAsserts = false;
/// Whether to show verbose messages (mainly for debugging and performance
@@ -243,9 +233,68 @@
/// The current sdk version string, e.g. "2.6.0-edge.sha1hash".
/// For instance used for language versioning (specifying the maximum
/// version).
- String currentSdkVersion = "${kernel.Library.defaultLanguageVersionMajor}"
+ String currentSdkVersion = "${kernel.defaultLanguageVersionMajor}"
"."
- "${kernel.Library.defaultLanguageVersionMinor}";
+ "${kernel.defaultLanguageVersionMinor}";
+
+ bool equivalent(CompilerOptions other,
+ {bool ignoreOnDiagnostic: true,
+ bool ignoreVerbose: true,
+ bool ignoreVerify: true,
+ bool ignoreDebugDump: true}) {
+ if (sdkRoot != other.sdkRoot) return false;
+ if (librariesSpecificationUri != other.librariesSpecificationUri) {
+ return false;
+ }
+ if (!ignoreOnDiagnostic) {
+ if (onDiagnostic != other.onDiagnostic) return false;
+ }
+ if (packagesFileUri != other.packagesFileUri) return false;
+ if (!equalLists(additionalDills, other.additionalDills)) return false;
+ if (sdkSummary != other.sdkSummary) return false;
+ if (!equalMaps(declaredVariables, other.declaredVariables)) return false;
+ if (fileSystem != other.fileSystem) return false;
+ if (compileSdk != compileSdk) return false;
+ // chaseDependencies aren't used anywhere, so ignored here.
+ // targetPatches aren't used anywhere, so ignored here.
+ if (!equalMaps(experimentalFlags, other.experimentalFlags)) return false;
+ if (!equalMaps(environmentDefines, other.environmentDefines)) return false;
+ if (errorOnUnevaluatedConstant != other.errorOnUnevaluatedConstant) {
+ return false;
+ }
+ if (target != other.target) {
+ if (target.runtimeType != other.target.runtimeType) return false;
+ if (target.name != other.target.name) return false;
+ if (target.flags != other.target.flags) return false;
+ }
+ // enableAsserts is not used anywhere, so ignored here.
+ if (!ignoreVerbose) {
+ if (verbose != other.verbose) return false;
+ }
+ if (!ignoreVerify) {
+ if (verify != other.verify) return false;
+ }
+ if (!ignoreDebugDump) {
+ if (debugDump != other.debugDump) return false;
+ }
+ if (omitPlatform != other.omitPlatform) return false;
+ if (setExitCodeOnProblem != other.setExitCodeOnProblem) return false;
+ if (embedSourceText != other.embedSourceText) return false;
+ if (throwOnErrorsForDebugging != other.throwOnErrorsForDebugging) {
+ return false;
+ }
+ if (throwOnWarningsForDebugging != other.throwOnWarningsForDebugging) {
+ return false;
+ }
+ if (skipForDebugging != other.skipForDebugging) return false;
+ if (bytecode != other.bytecode) return false;
+ if (writeFileOnCrashReport != other.writeFileOnCrashReport) return false;
+ if (nnbdMode != other.nnbdMode) return false;
+ if (performNnbdChecks != other.performNnbdChecks) return false;
+ if (currentSdkVersion != other.currentSdkVersion) return false;
+
+ return true;
+ }
}
/// Parse experimental flag arguments of the form 'flag' or 'no-flag' into a map
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 110685b..9945733 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -19,6 +19,25 @@
variance,
}
+const int enableConstantUpdate2018MajorVersion = 2;
+const int enableConstantUpdate2018MinorVersion = 4;
+const int enableControlFlowCollectionsMajorVersion = 2;
+const int enableControlFlowCollectionsMinorVersion = 2;
+const int enableExtensionMethodsMajorVersion = 2;
+const int enableExtensionMethodsMinorVersion = 6;
+const int enableNonNullableMajorVersion = 2;
+const int enableNonNullableMinorVersion = 8;
+const int enableNonfunctionTypeAliasesMajorVersion = 2;
+const int enableNonfunctionTypeAliasesMinorVersion = 8;
+const int enableSetLiteralsMajorVersion = 2;
+const int enableSetLiteralsMinorVersion = 2;
+const int enableSpreadCollectionsMajorVersion = 2;
+const int enableSpreadCollectionsMinorVersion = 2;
+const int enableTripleShiftMajorVersion = 2;
+const int enableTripleShiftMinorVersion = 8;
+const int enableVarianceMajorVersion = 2;
+const int enableVarianceMinorVersion = 8;
+
ExperimentalFlag parseExperimentalFlag(String flag) {
switch (flag) {
case "constant-update-2018":
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index 783bee2..a5fe70a 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -54,6 +54,24 @@
incrementalSerializer);
}
+ /// Initialize the incremental compiler specifically for expression
+ /// compilation where the dill is external and we cannot expect to have access
+ /// to the sources.
+ ///
+ /// The resulting incremental compiler allows for expression compilation,
+ /// but not for general compilation. Note that computeDelta will have to be
+ /// called once to setup properly though.
+ ///
+ /// Notice that the component has to include the platform, and that no other
+ /// platform will be loaded.
+ factory IncrementalKernelGenerator.forExpressionCompilationOnly(
+ CompilerOptions options, Uri entryPoint, Component component) {
+ return new IncrementalCompiler.forExpressionCompilationOnly(
+ new CompilerContext(
+ new ProcessedOptions(options: options, inputs: [entryPoint])),
+ component);
+ }
+
/// Returns a component whose libraries are the recompiled libraries,
/// or - in the case of [fullComponent] - a full Component.
Future<Component> computeDelta({List<Uri> entryPoints, bool fullComponent});
diff --git a/pkg/front_end/lib/src/api_prototype/kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
index 8de9131..8519ca0 100644
--- a/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
@@ -82,8 +82,8 @@
/// must be acyclic.
///
/// This API is intended for modular compilation. Dependencies to other modules
-/// are specified using [CompilerOptions.inputSummaries]. Any dependency
-/// of [sources] that is not listed in [CompilerOptions.inputSummaries] and
+/// are specified using [CompilerOptions.additionalDills]. Any dependency
+/// of [sources] that is not listed in [CompilerOptions.additionalDills] and
/// [CompilerOptions.sdkSummary] is treated as an additional source file for the
/// module.
///
diff --git a/pkg/front_end/lib/src/api_prototype/summary_generator.dart b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
index 9103689..5385311 100644
--- a/pkg/front_end/lib/src/api_prototype/summary_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
@@ -17,8 +17,8 @@
/// Intended to be a part of a modular compilation process.
///
/// Any dependency of [sources] that is not listed in
-/// [CompilerOptions.inputSummaries] and [CompilerOptions.sdkSummary] is treated
-/// as an additional source file for the build unit.
+/// [CompilerOptions.additionalDills] and [CompilerOptions.sdkSummary] is
+/// treated as an additional source file for the build unit.
///
/// Any `part` declarations found in [sources] must refer to part files which
/// are also listed in the build unit sources, otherwise an error results. (It
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index 2e14914..eacc6bb 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -64,7 +64,7 @@
Uri sdkSummary,
Uri packagesFile,
Uri librariesSpecificationUri,
- List<Uri> summaryInputs,
+ List<Uri> additionalDills,
Map<Uri, List<int>> workerInputDigests,
Target target,
FileSystem fileSystem,
@@ -72,19 +72,19 @@
bool outlineOnly,
Map<String, String> environmentDefines,
{bool trackNeededDillLibraries: false}) async {
- List<Component> outputLoadedInputSummaries =
- new List<Component>(summaryInputs.length);
+ List<Component> outputLoadedAdditionalDills =
+ new List<Component>(additionalDills.length);
Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
parseExperimentalArguments(experiments),
onError: (e) => throw e);
return modular.initializeIncrementalCompiler(
oldState,
tags,
- outputLoadedInputSummaries,
+ outputLoadedAdditionalDills,
sdkSummary,
packagesFile,
librariesSpecificationUri,
- summaryInputs,
+ additionalDills,
workerInputDigests,
target,
fileSystem: fileSystem,
@@ -100,8 +100,7 @@
Uri sdkSummary,
Uri librariesSpecificationUri,
Uri packagesFile,
- List<Uri> summaryInputs,
- List<Uri> linkedInputs,
+ List<Uri> additionalDills,
Target target,
FileSystem fileSystem,
Iterable<String> experiments,
@@ -115,8 +114,7 @@
..sdkSummary = sdkSummary
..packagesFileUri = packagesFile
..librariesSpecificationUri = librariesSpecificationUri
- ..inputSummaries = summaryInputs
- ..linkedDependencies = linkedInputs
+ ..additionalDills = additionalDills
..target = target
..fileSystem = fileSystem
..environmentDefines = environmentDefines
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 0088540..9cb036e 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -33,6 +33,8 @@
import '../base/libraries_specification.dart' show LibrariesSpecification;
+import '../base/nnbd_mode.dart' show NnbdMode;
+
import '../fasta/compiler_context.dart' show CompilerContext;
import '../kernel_generator_impl.dart' show generateKernelInternal;
@@ -109,6 +111,8 @@
export '../api_prototype/standard_file_system.dart' show DataFileSystemEntity;
+export '../base/nnbd_mode.dart' show NnbdMode;
+
export '../compute_platform_binaries_location.dart'
show computePlatformBinariesLocation;
@@ -129,28 +133,30 @@
InitializedCompilerState oldState,
Target target,
Uri librariesSpecificationUri,
- List<Uri> linkedDependencies,
+ List<Uri> additionalDills,
Uri packagesFileUri,
{List<Uri> dependencies,
Map<ExperimentalFlag, bool> experimentalFlags,
- bool verify: false}) {
- linkedDependencies.sort((a, b) => a.toString().compareTo(b.toString()));
+ bool verify: false,
+ NnbdMode nnbdMode}) {
+ additionalDills.sort((a, b) => a.toString().compareTo(b.toString()));
if (oldState != null &&
oldState.options.packagesFileUri == packagesFileUri &&
oldState.options.librariesSpecificationUri == librariesSpecificationUri &&
- equalLists(oldState.options.linkedDependencies, linkedDependencies) &&
+ equalLists(oldState.options.additionalDills, additionalDills) &&
equalMaps(oldState.options.experimentalFlags, experimentalFlags)) {
return oldState;
}
CompilerOptions options = new CompilerOptions()
..target = target
- ..linkedDependencies = linkedDependencies
+ ..additionalDills = additionalDills
..librariesSpecificationUri = librariesSpecificationUri
..packagesFileUri = packagesFileUri
..experimentalFlags = experimentalFlags
..verify = verify;
+ if (nnbdMode != null) options.nnbdMode = nnbdMode;
ProcessedOptions processedOpts = new ProcessedOptions(options: options);
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 412e59f..eaf6e00 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -72,17 +72,17 @@
class DdcResult {
final Component component;
final Component sdkSummary;
- final List<Component> inputSummaries;
+ final List<Component> additionalDills;
final ClassHierarchy classHierarchy;
- DdcResult(
- this.component, this.sdkSummary, this.inputSummaries, this.classHierarchy)
+ DdcResult(this.component, this.sdkSummary, this.additionalDills,
+ this.classHierarchy)
: assert(classHierarchy != null);
Set<Library> computeLibrariesFromDill() {
Set<Library> librariesFromDill = new Set<Library>();
- for (Component c in inputSummaries) {
+ for (Component c in additionalDills) {
for (Library lib in c.libraries) {
librariesFromDill.add(lib);
}
@@ -104,19 +104,19 @@
Uri sdkSummary,
Uri packagesFile,
Uri librariesSpecificationUri,
- List<Uri> inputSummaries,
+ List<Uri> additionalDills,
Target target,
{FileSystem fileSystem,
Map<ExperimentalFlag, bool> experiments,
Map<String, String> environmentDefines}) async {
- inputSummaries.sort((a, b) => a.toString().compareTo(b.toString()));
+ additionalDills.sort((a, b) => a.toString().compareTo(b.toString()));
if (oldState != null &&
oldState.options.compileSdk == compileSdk &&
oldState.options.sdkSummary == sdkSummary &&
oldState.options.packagesFileUri == packagesFile &&
oldState.options.librariesSpecificationUri == librariesSpecificationUri &&
- equalLists(oldState.options.inputSummaries, inputSummaries) &&
+ equalLists(oldState.options.additionalDills, additionalDills) &&
equalMaps(oldState.options.experimentalFlags, experiments) &&
equalMaps(oldState.options.environmentDefines, environmentDefines)) {
// Reuse old state.
@@ -128,7 +128,7 @@
..sdkRoot = sdkRoot
..sdkSummary = sdkSummary
..packagesFileUri = packagesFile
- ..inputSummaries = inputSummaries
+ ..additionalDills = additionalDills
..librariesSpecificationUri = librariesSpecificationUri
..target = target
..fileSystem = fileSystem ?? StandardFileSystem.instance
@@ -147,13 +147,13 @@
Future<InitializedCompilerState> initializeIncrementalCompiler(
InitializedCompilerState oldState,
Set<String> tags,
- List<Component> doneInputSummaries,
+ List<Component> doneAdditionalDills,
bool compileSdk,
Uri sdkRoot,
Uri sdkSummary,
Uri packagesFile,
Uri librariesSpecificationUri,
- List<Uri> inputSummaries,
+ List<Uri> additionalDills,
Map<Uri, List<int>> workerInputDigests,
Target target,
{FileSystem fileSystem,
@@ -163,11 +163,11 @@
return modular.initializeIncrementalCompiler(
oldState,
tags,
- doneInputSummaries,
+ doneAdditionalDills,
sdkSummary,
packagesFile,
librariesSpecificationUri,
- inputSummaries,
+ additionalDills,
workerInputDigests,
target,
compileSdk: compileSdk,
@@ -198,7 +198,7 @@
// These should be cached.
Component sdkSummary = await processedOpts.loadSdkSummary(null);
- List<Component> summaries = await processedOpts.loadInputSummaries(null);
+ List<Component> summaries = await processedOpts.loadAdditionalDills(null);
return new DdcResult(
component, sdkSummary, summaries, compilerResult.classHierarchy);
}
diff --git a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
index 3916c39..16c2863 100644
--- a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
+++ b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
@@ -31,19 +31,19 @@
/// as necessary based on [workerInputDigests].
///
/// Notes:
-/// * [outputLoadedInputSummaries] should be given as an empty list of the same
-/// size as the [inputSummaries]. The input summaries are loaded (or taken
+/// * [outputLoadedAdditionalDills] should be given as an empty list of the same
+/// size as the [additionalDills]. The input summaries are loaded (or taken
/// from cache) and placed in this list in order, i.e. the `i`-th entry in
-/// [outputLoadedInputSummaries] after this call corresponds to the component
-/// loaded from the `i`-th entry in [inputSummaries].
+/// [outputLoadedAdditionalDills] after this call corresponds to the component
+/// loaded from the `i`-th entry in [additionalDills].
Future<InitializedCompilerState> initializeIncrementalCompiler(
InitializedCompilerState oldState,
Set<String> tags,
- List<Component> outputLoadedInputSummaries,
+ List<Component> outputLoadedAdditionalDills,
Uri sdkSummary,
Uri packagesFile,
Uri librariesSpecificationUri,
- List<Uri> inputSummaries,
+ List<Uri> additionalDills,
Map<Uri, List<int>> workerInputDigests,
Target target,
{bool compileSdk: false,
@@ -129,8 +129,8 @@
// although it's not entirely obvious why.
// It likely has to do with several outlines containing the same
// libraries. Once that stops (and we check for it) we can probably
- // remove this, and instead only do it when about to reuse an outline
- // in the 'inputSummaries.add(component);' line further down.
+ // remove this, and instead only do it when about to reuse a component
+ // further down.
for (WorkerInputComponent cachedInput in workerInputCache.values) {
cachedInput.component.adoptChildren();
}
@@ -154,13 +154,13 @@
// Notice that the ordering of the input summaries matter, so we need to
// keep them in order.
- if (outputLoadedInputSummaries.length != inputSummaries.length) {
+ if (outputLoadedAdditionalDills.length != additionalDills.length) {
throw new ArgumentError("Invalid length.");
}
- Set<Uri> inputSummariesSet = new Set<Uri>();
- for (int i = 0; i < inputSummaries.length; i++) {
- Uri summaryUri = inputSummaries[i];
- inputSummariesSet.add(summaryUri);
+ Set<Uri> additionalDillsSet = new Set<Uri>();
+ for (int i = 0; i < additionalDills.length; i++) {
+ Uri summaryUri = additionalDills[i];
+ additionalDillsSet.add(summaryUri);
WorkerInputComponent cachedInput = workerInputCache[summaryUri];
List<int> digest = workerInputDigests[summaryUri];
if (digest == null) {
@@ -187,30 +187,30 @@
}
}
component.computeCanonicalNames(); // this isn't needed, is it?
- outputLoadedInputSummaries[i] = component;
+ outputLoadedAdditionalDills[i] = component;
}
}
for (int i = 0; i < loadFromDillIndexes.length; i++) {
int index = loadFromDillIndexes[i];
- Uri summaryUri = inputSummaries[index];
- List<int> digest = workerInputDigests[summaryUri];
+ Uri additionalDillUri = additionalDills[index];
+ List<int> digest = workerInputDigests[additionalDillUri];
if (digest == null) {
- throw new StateError("Expected to get digest for $summaryUri");
+ throw new StateError("Expected to get digest for $additionalDillUri");
}
List<int> bytes =
- await fileSystem.entityForUri(summaryUri).readAsBytes();
+ await fileSystem.entityForUri(additionalDillUri).readAsBytes();
WorkerInputComponent cachedInput = new WorkerInputComponent(
digest,
await processedOpts.loadComponent(bytes, nameRoot,
alwaysCreateNewNamedNodes: true));
- workerInputCache[summaryUri] = cachedInput;
- outputLoadedInputSummaries[index] = cachedInput.component;
+ workerInputCache[additionalDillUri] = cachedInput;
+ outputLoadedAdditionalDills[index] = cachedInput.component;
for (Library lib in cachedInput.component.libraries) {
if (workerInputCacheLibs.containsKey(lib.importUri)) {
Uri fromSummary = workerInputCacheLibs[lib.importUri];
- if (inputSummariesSet.contains(fromSummary)) {
+ if (additionalDillsSet.contains(fromSummary)) {
throw new StateError(
"Asked to load several summaries that contain the same "
"library.");
@@ -223,17 +223,17 @@
}
}
} else {
- workerInputCacheLibs[lib.importUri] = summaryUri;
+ workerInputCacheLibs[lib.importUri] = additionalDillUri;
}
if (trackNeededDillLibraries) {
- libraryToInputDill[lib.importUri] = summaryUri;
+ libraryToInputDill[lib.importUri] = additionalDillUri;
}
}
}
incrementalCompiler
- .setModulesToLoadOnNextComputeDelta(outputLoadedInputSummaries);
+ .setModulesToLoadOnNextComputeDelta(outputLoadedAdditionalDills);
return new InitializedCompilerState(options, processedOpts,
workerInputCache: workerInputCache,
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 458cda1..b0cacef 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -109,17 +109,13 @@
/// types unless legacy mode is enabled.
Component _sdkSummaryComponent;
- /// The summary for each uri in `options.inputSummaries`.
+ /// The component for each uri in `options.additionalDills`.
///
/// A summary, also referred to as "outline" internally, is a [Component]
/// where all method bodies are left out. In essence, it contains just API
/// signatures and constants. The summaries should include inferred top-level
/// types unless legacy mode is enabled.
- List<Component> _inputSummariesComponents;
-
- /// Other components that are meant to be linked and compiled with the input
- /// sources.
- List<Component> _linkedDependencies;
+ List<Component> _additionalDillComponents;
/// The location of the SDK, or `null` if the location hasn't been determined
/// yet.
@@ -288,7 +284,7 @@
return false;
}
- for (Uri source in _raw.linkedDependencies) {
+ for (Uri source in _raw.additionalDills) {
// TODO(ahe): Remove this check, the compiler itself should handle and
// recover from this.
if (!await fileSystem.entityForUri(source).exists()) {
@@ -360,42 +356,27 @@
_sdkSummaryComponent = platform;
}
- /// Get the summary programs for each of the underlying `inputSummaries`
+ /// Get the components for each of the underlying `additionalDill`
/// provided via [CompilerOptions].
// TODO(sigmund): move, this doesn't feel like an "option".
- Future<List<Component>> loadInputSummaries(CanonicalName nameRoot) async {
- if (_inputSummariesComponents == null) {
- List<Uri> uris = _raw.inputSummaries;
+ Future<List<Component>> loadAdditionalDills(CanonicalName nameRoot) async {
+ if (_additionalDillComponents == null) {
+ List<Uri> uris = _raw.additionalDills;
if (uris == null || uris.isEmpty) return const <Component>[];
// TODO(sigmund): throttle # of concurrent operations.
List<List<int>> allBytes = await Future.wait(
uris.map((uri) => _readAsBytes(fileSystem.entityForUri(uri))));
- _inputSummariesComponents =
+ _additionalDillComponents =
allBytes.map((bytes) => loadComponent(bytes, nameRoot)).toList();
}
- return _inputSummariesComponents;
+ return _additionalDillComponents;
}
- void set inputSummariesComponents(List<Component> components) {
- if (_inputSummariesComponents != null) {
- throw new StateError("inputSummariesComponents already loaded.");
+ void set loadAdditionalDillsComponents(List<Component> components) {
+ if (_additionalDillComponents != null) {
+ throw new StateError("inputAdditionalDillsComponents already loaded.");
}
- _inputSummariesComponents = components;
- }
-
- /// Load each of the [CompilerOptions.linkedDependencies] components.
- // TODO(sigmund): move, this doesn't feel like an "option".
- Future<List<Component>> loadLinkDependencies(CanonicalName nameRoot) async {
- if (_linkedDependencies == null) {
- List<Uri> uris = _raw.linkedDependencies;
- if (uris == null || uris.isEmpty) return const <Component>[];
- // TODO(sigmund): throttle # of concurrent operations.
- List<List<int>> allBytes = await Future.wait(
- uris.map((uri) => _readAsBytes(fileSystem.entityForUri(uri))));
- _linkedDependencies =
- allBytes.map((bytes) => loadComponent(bytes, nameRoot)).toList();
- }
- return _linkedDependencies;
+ _additionalDillComponents = components;
}
/// Helper to load a .dill file from [uri] using the existing [nameRoot].
@@ -709,8 +690,7 @@
sb.writeln('FileSystem: ${_fileSystem.runtimeType} '
'(provided: ${_raw.fileSystem.runtimeType})');
- writeList('Input Summaries', _raw.inputSummaries);
- writeList('Linked Dependencies', _raw.linkedDependencies);
+ writeList('Additional Dills', _raw.additionalDills);
sb.writeln('Packages uri: ${_raw.packagesFileUri}');
sb.writeln('Packages: ${_packages}');
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 8943783..46e5327 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -16,6 +16,7 @@
templateMissingExplicitTypeArguments,
messageNotATypeContext,
LocatedMessage,
+ templateExtendingRestricted,
templateNotAType,
templateTypeArgumentMismatch,
templateTypeArgumentsOnTypeVariable,
@@ -226,6 +227,13 @@
LibraryBuilder library, int charOffset, Uri fileUri) {
TypeDeclarationBuilder declaration = this.declaration;
if (declaration is ClassBuilder) {
+ if (declaration.isNullClass && !library.mayImplementRestrictedTypes) {
+ library.addProblem(
+ templateExtendingRestricted.withArguments(declaration.name),
+ charOffset,
+ noLength,
+ fileUri);
+ }
return declaration.buildSupertype(library, arguments);
} else if (declaration is TypeAliasBuilder) {
TypeDeclarationBuilder declarationBuilder =
diff --git a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
index 28d20c0..184af64 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
@@ -4,8 +4,6 @@
library fasta.function_type_alias_builder;
-import 'package:front_end/src/fasta/builder/fixed_type_builder.dart';
-import 'package:front_end/src/fasta/builder/named_type_builder.dart';
import 'package:kernel/ast.dart'
show
DartType,
@@ -21,6 +19,8 @@
import 'package:kernel/type_algebra.dart'
show FreshTypeParameters, getFreshTypeParameters, substitute;
+import 'package:kernel/src/future_or.dart';
+
import '../fasta_codes.dart'
show noLength, templateCyclicTypedef, templateTypeArgumentMismatch;
@@ -29,10 +29,12 @@
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
import 'class_builder.dart';
+import 'fixed_type_builder.dart';
import 'formal_parameter_builder.dart';
import 'function_type_builder.dart';
import 'library_builder.dart';
import 'metadata_builder.dart';
+import 'named_type_builder.dart';
import 'nullability_builder.dart';
import 'type_builder.dart';
import 'type_declaration_builder.dart';
@@ -237,16 +239,23 @@
NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
DartType thisType = buildThisType(library);
if (thisType is InvalidType) return thisType;
+ // TODO(dmitryas): Remove the following comment when FutureOr has its own
+ // encoding and isn't represented as an InterfaceType.
+
+ // The following won't work if the right-hand side of the typedef is a
+ // FutureOr.
+ Nullability rhsNullability = thisType.nullability;
if (typedef.typeParameters.isEmpty && arguments == null) {
Nullability nullability = isNullAlias
? Nullability.nullable
: nullabilityBuilder.build(library);
- return thisType.withNullability(nullability);
+ return thisType
+ .withNullability(uniteNullabilities(rhsNullability, nullability));
}
// Otherwise, substitute.
return buildTypesWithBuiltArguments(
library,
- nullabilityBuilder.build(library),
+ uniteNullabilities(rhsNullability, nullabilityBuilder.build(library)),
buildTypeArguments(library, arguments));
}
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 047a3f9..cf98a1f 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -43,6 +43,7 @@
{bool filter(Uri uri), int byteCount: 0}) {
List<Library> componentLibraries = component.libraries;
List<Uri> requestedLibraries = <Uri>[];
+ List<Uri> requestedLibrariesFileUri = <Uri>[];
DillTarget target = this.target;
for (int i = 0; i < componentLibraries.length; i++) {
Library library = componentLibraries[i];
@@ -51,11 +52,13 @@
libraries.add(library);
target.addLibrary(library);
requestedLibraries.add(uri);
+ requestedLibrariesFileUri.add(library.fileUri);
}
}
List<DillLibraryBuilder> result = <DillLibraryBuilder>[];
for (int i = 0; i < requestedLibraries.length; i++) {
- result.add(read(requestedLibraries[i], -1));
+ result.add(read(requestedLibraries[i], -1,
+ fileUri: requestedLibrariesFileUri[i]));
}
target.uriToSource.addAll(component.uriToSource);
this.byteCount += byteCount;
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 5fd3fb8..dc0344c 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -144,6 +144,8 @@
Map<String, Package> previousPackagesMap;
Map<String, Package> currentPackagesMap;
bool hasToCheckPackageUris = false;
+ final bool initializedForExpressionCompilationOnly;
+ bool computeDeltaRunOnce = false;
Map<Uri, List<DiagnosticMessageFromJson>> remainingComponentProblems =
new Map<Uri, List<DiagnosticMessageFromJson>>();
List<Component> modulesToLoad;
@@ -159,25 +161,34 @@
IncrementalCompiler.fromComponent(
this.context, this.componentToInitializeFrom,
- [bool outlineOnly, IncrementalSerializer incrementalSerializer])
+ [bool outlineOnly, this.incrementalSerializer])
: ticker = context.options.ticker,
initializeFromDillUri = null,
this.outlineOnly = outlineOnly ?? false,
- this.incrementalSerializer = incrementalSerializer {
+ this.initializedForExpressionCompilationOnly = false {
enableExperimentsBasedOnEnvironment();
}
IncrementalCompiler(this.context,
[this.initializeFromDillUri,
bool outlineOnly,
- IncrementalSerializer incrementalSerializer])
+ this.incrementalSerializer])
: ticker = context.options.ticker,
componentToInitializeFrom = null,
this.outlineOnly = outlineOnly ?? false,
- this.incrementalSerializer = incrementalSerializer {
+ this.initializedForExpressionCompilationOnly = false {
enableExperimentsBasedOnEnvironment();
}
+ IncrementalCompiler.forExpressionCompilationOnly(
+ this.context, this.componentToInitializeFrom)
+ : ticker = context.options.ticker,
+ initializeFromDillUri = null,
+ this.outlineOnly = false,
+ this.incrementalSerializer = null,
+ this.initializedForExpressionCompilationOnly = true {
+ enableExperimentsBasedOnEnvironment();
+ }
void enableExperimentsBasedOnEnvironment() {
// Note that these are all experimental. Use at your own risk.
Set<String> enabledExperiments = getExperimentEnvironment();
@@ -198,6 +209,11 @@
ticker.reset();
entryPoints ??= context.options.inputs;
return context.runInContext<Component>((CompilerContext c) async {
+ if (computeDeltaRunOnce && initializedForExpressionCompilationOnly) {
+ throw new StateError("Initialized for expression compilation: "
+ "cannot do another general compile.");
+ }
+ computeDeltaRunOnce = true;
// Initial setup: Load platform, initialize from dill or component etc.
UriTranslator uriTranslator = await setupPackagesAndUriTranslator(c);
IncrementalCompilerData data =
@@ -953,6 +969,9 @@
// changed and only set this to true if it did.
hasToCheckPackageUris = hasToCheckPackageUris || bypassCache;
ticker.logMs("Read packages file");
+ if (initializedForExpressionCompilationOnly) {
+ hasToCheckPackageUris = false;
+ }
return uriTranslator;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index c53b67a..a302ce4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -895,12 +895,12 @@
FunctionBuilder builder = member;
if (extensionThis != null) {
- typeInferrer?.flowAnalysis?.initialize(extensionThis);
+ typeInferrer?.flowAnalysis?.declare(extensionThis, true);
}
if (formals?.parameters != null) {
for (int i = 0; i < formals.parameters.length; i++) {
FormalParameterBuilder parameter = formals.parameters[i];
- typeInferrer?.flowAnalysis?.initialize(parameter.variable);
+ typeInferrer?.flowAnalysis?.declare(parameter.variable, true);
}
for (int i = 0; i < formals.parameters.length; i++) {
FormalParameterBuilder parameter = formals.parameters[i];
@@ -1373,7 +1373,7 @@
if (formals != null) {
for (int i = 0; i < formals.length; i++) {
FormalParameterBuilder parameter = formals[i];
- typeInferrer?.flowAnalysis?.initialize(parameter.variable);
+ typeInferrer?.flowAnalysis?.declare(parameter.variable, true);
}
}
if (_initializers != null) {
@@ -3185,6 +3185,17 @@
}
@override
+ void handleVoidKeywordWithTypeArguments(Token token) {
+ assert(checkState(token, <ValueKind>[
+ /* arguments */ ValueKinds.TypeArgumentsOrNull,
+ ]));
+
+ debugEvent("handleVoidKeywordWithTypeArguments");
+ pop(); // arguments.
+ handleVoidKeyword(token);
+ }
+
+ @override
void handleAsOperator(Token operator) {
debugEvent("AsOperator");
DartType type = buildDartType(pop());
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 2266c1e..2436056 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -225,7 +225,6 @@
final List<DelayedMember> delayedMemberChecks = <DelayedMember>[];
- // TODO(dmitryas): Consider removing this.
final CoreTypes coreTypes;
Types types;
@@ -254,28 +253,27 @@
getNodeFromClassBuilder(loader.computeClassBuilderFromTargetClass(cls));
}
- InterfaceType asSupertypeOf(InterfaceType subtype, Class supertype) {
+ Supertype asSupertypeOf(InterfaceType subtype, Class supertype) {
if (subtype.classNode == supertype) {
- return subtype;
+ return new Supertype(supertype, subtype.typeArguments);
}
ClassHierarchyNode clsNode = getNodeFromClass(subtype.classNode);
ClassHierarchyNode supertypeNode = getNodeFromClass(supertype);
- List<DartType> superclasses = clsNode.superclasses;
+ List<Supertype> superclasses = clsNode.superclasses;
int depth = supertypeNode.depth;
if (depth < superclasses.length) {
- DartType superclass = superclasses[depth];
- if (superclass is InterfaceType && superclass.classNode == supertype) {
+ Supertype superclass = superclasses[depth];
+ if (superclass.classNode == supertype) {
return Substitution.fromInterfaceType(subtype)
- .substituteType(superclass);
+ .substituteSupertype(superclass);
}
}
- List<DartType> superinterfaces = clsNode.interfaces;
+ List<Supertype> superinterfaces = clsNode.interfaces;
for (int i = 0; i < superinterfaces.length; i++) {
- DartType superinterface = superinterfaces[i];
- if (superinterface is InterfaceType &&
- superinterface.classNode == supertype) {
+ Supertype superinterface = superinterfaces[i];
+ if (superinterface.classNode == supertype) {
return Substitution.fromInterfaceType(subtype)
- .substituteType(superinterface);
+ .substituteSupertype(superinterface);
}
}
return null;
@@ -298,7 +296,9 @@
superclass.typeParameters.length, coreTypes.nullType));
}
}
- return asSupertypeOf(type, superclass);
+ return asSupertypeOf(type, superclass)
+ .asInterfaceType
+ .withNullability(type.nullability);
}
List<DartType> getKernelTypeArgumentsAsInstanceOf(
@@ -1365,9 +1365,9 @@
/// superclasses.
List<ClassMember> interfaceSetters;
- List<DartType> superclasses;
+ List<Supertype> superclasses;
- List<DartType> interfaces;
+ List<Supertype> interfaces;
int maxInheritancePath;
@@ -1375,18 +1375,20 @@
// This should be Object.
classMembers = localMembers;
classSetters = localSetters;
- superclasses = new List<DartType>(0);
- interfaces = new List<DartType>(0);
+ superclasses = new List<Supertype>(0);
+ interfaces = new List<Supertype>(0);
maxInheritancePath = 0;
} else {
maxInheritancePath = supernode.maxInheritancePath + 1;
- superclasses = new List<DartType>(supernode.superclasses.length + 1);
- DartType supertype = classBuilder.supertype.build(classBuilder.library);
- if (supertype is! InterfaceType) {
+ superclasses = new List<Supertype>(supernode.superclasses.length + 1);
+ Supertype supertype = classBuilder.supertype.buildSupertype(
+ classBuilder.library, classBuilder.charOffset, classBuilder.fileUri);
+ if (supertype == null) {
// If the superclass is not an interface type we use Object instead.
// A similar normalization is performed on [supernode] above.
- supertype = hierarchy.coreTypes.objectNonNullableRawType;
+ supertype =
+ new Supertype(hierarchy.coreTypes.objectClass, const <DartType>[]);
}
superclasses.setRange(0, superclasses.length - 1,
substSupertypes(supertype, supernode.superclasses));
@@ -1404,11 +1406,14 @@
}
if (directInterfaceBuilders != null) {
for (int i = 0; i < directInterfaceBuilders.length; i++) {
- recordSupertype(
- directInterfaceBuilders[i].build(classBuilder.library));
+ Supertype interface = directInterfaceBuilders[i].buildSupertype(
+ classBuilder.library,
+ classBuilder.charOffset,
+ classBuilder.fileUri);
+ if (interface != null) recordSupertype(interface);
}
}
- List<DartType> superclassInterfaces = supernode.interfaces;
+ List<Supertype> superclassInterfaces = supernode.interfaces;
if (superclassInterfaces != null) {
superclassInterfaces = substSupertypes(supertype, superclassInterfaces);
}
@@ -1423,7 +1428,7 @@
mergeInterfaces(supernode, directInterfaceBuilders);
interfaceMembers = result.mergedMembers;
interfaceSetters = result.mergedSetters;
- interfaces = <DartType>[];
+ interfaces = <Supertype>[];
if (superclassInterfaces != null) {
for (int i = 0; i < superclassInterfaces.length; i++) {
addInterface(interfaces, superclasses, superclassInterfaces[i]);
@@ -1431,10 +1436,12 @@
}
for (int i = 0; i < directInterfaceBuilders.length; i++) {
- DartType directInterface =
- directInterfaceBuilders[i].build(classBuilder.library);
- addInterface(interfaces, superclasses, directInterface);
- if (directInterface is InterfaceType) {
+ Supertype directInterface = directInterfaceBuilders[i].buildSupertype(
+ classBuilder.library,
+ classBuilder.charOffset,
+ classBuilder.fileUri);
+ if (directInterface != null) {
+ addInterface(interfaces, superclasses, directInterface);
ClassHierarchyNode interfaceNode =
hierarchy.getNodeFromClass(directInterface.classNode);
if (interfaceNode != null) {
@@ -1442,13 +1449,13 @@
maxInheritancePath = interfaceNode.maxInheritancePath + 1;
}
- List<DartType> types =
+ List<Supertype> types =
substSupertypes(directInterface, interfaceNode.superclasses);
for (int i = 0; i < types.length; i++) {
addInterface(interfaces, superclasses, types[i]);
}
if (interfaceNode.interfaces != null) {
- List<DartType> types =
+ List<Supertype> types =
substSupertypes(directInterface, interfaceNode.interfaces);
for (int i = 0; i < types.length; i++) {
addInterface(interfaces, superclasses, types[i]);
@@ -1511,39 +1518,35 @@
);
}
- DartType recordSupertype(DartType supertype) {
+ Supertype recordSupertype(Supertype supertype) {
debug?.log("In ${this.classBuilder.fullNameForErrors} "
"recordSupertype(${supertype})");
- if (supertype is InterfaceType) {
- Class cls = supertype.classNode;
- if (cls.isMixinApplication) {
- recordSupertype(cls.mixedInType.asInterfaceType);
+ Class cls = supertype.classNode;
+ if (cls.isMixinApplication) {
+ recordSupertype(cls.mixedInType);
+ }
+ List<TypeParameter> typeVariableBuilders = cls.typeParameters;
+ if (typeVariableBuilders == null) {
+ substitutions[cls] = Substitution.empty;
+ assert(cls.typeParameters.isEmpty);
+ } else {
+ List<DartType> arguments = supertype.typeArguments;
+ List<DartType> typeArguments = new List<DartType>(arguments.length);
+ List<TypeParameter> typeParameters =
+ new List<TypeParameter>(arguments.length);
+ for (int i = 0; i < arguments.length; i++) {
+ typeParameters[i] = typeVariableBuilders[i];
+ typeArguments[i] = arguments[i];
}
- List<TypeParameter> typeVariableBuilders = cls.typeParameters;
- if (typeVariableBuilders == null) {
- substitutions[cls] = Substitution.empty;
- assert(cls.typeParameters.isEmpty);
- } else {
- List<DartType> arguments = supertype.typeArguments;
- List<DartType> typeArguments = new List<DartType>(arguments.length);
- List<TypeParameter> typeParameters =
- new List<TypeParameter>(arguments.length);
- for (int i = 0; i < arguments.length; i++) {
- typeParameters[i] = typeVariableBuilders[i];
- typeArguments[i] = arguments[i];
- }
- substitutions[cls] =
- Substitution.fromPairs(typeParameters, typeArguments);
- }
+ substitutions[cls] =
+ Substitution.fromPairs(typeParameters, typeArguments);
}
return supertype;
}
- List<DartType> substSupertypes(
- DartType supertype, List<DartType> supertypes) {
- if (supertype is! InterfaceType) return supertypes;
- InterfaceType cls = supertype;
- List<TypeParameter> typeVariables = cls.classNode.typeParameters;
+ List<Supertype> substSupertypes(
+ Supertype supertype, List<Supertype> supertypes) {
+ List<TypeParameter> typeVariables = supertype.classNode.typeParameters;
if (typeVariables.isEmpty) {
debug?.log("In ${this.classBuilder.fullNameForErrors} "
"$supertypes aren't substed");
@@ -1553,16 +1556,16 @@
return supertypes;
}
Map<TypeParameter, DartType> map = <TypeParameter, DartType>{};
- List<DartType> arguments = cls.typeArguments;
+ List<DartType> arguments = supertype.typeArguments;
for (int i = 0; i < typeVariables.length; i++) {
map[typeVariables[i]] = arguments[i];
}
Substitution substitution = Substitution.fromMap(map);
- List<DartType> result;
+ List<Supertype> result;
for (int i = 0; i < supertypes.length; i++) {
- DartType supertype = supertypes[i];
- DartType substituted =
- recordSupertype(substitution.substituteType(supertype));
+ Supertype supertype = supertypes[i];
+ Supertype substituted =
+ recordSupertype(substitution.substituteSupertype(supertype));
if (supertype != substituted) {
debug?.log("In ${this.classBuilder.fullNameForErrors} $supertype"
" -> $substituted");
@@ -1597,63 +1600,60 @@
}
}
- DartType addInterface(
- List<DartType> interfaces, List<DartType> superclasses, DartType type) {
+ Supertype addInterface(List<Supertype> interfaces,
+ List<Supertype> superclasses, Supertype type) {
+ if (type == null) return null;
if (!classBuilder.library.isNonNullableByDefault) {
- type = legacyErasure(hierarchy.coreTypes, type);
+ type = legacyErasureSupertype(hierarchy.coreTypes, type);
}
- if (type is InterfaceType) {
- ClassHierarchyNode node = hierarchy.getNodeFromClass(type.classNode);
- if (node == null) return null;
- int depth = node.depth;
- int myDepth = superclasses.length;
- DartType superclass = depth < myDepth ? superclasses[depth] : null;
- if (superclass is InterfaceType &&
- superclass.classNode == type.classNode) {
- // This is a potential conflict.
- if (classBuilder.library.isNonNullableByDefault) {
- superclass = nnbdTopMerge(
- hierarchy.coreTypes,
- norm(hierarchy.coreTypes, superclass),
- norm(hierarchy.coreTypes, type));
- if (superclass == null) {
- // This is a conflict.
- // TODO(johnniwinther): Report errors here instead of through
- // the computation of the [ClassHierarchy].
- superclass = superclasses[depth];
- } else {
- superclasses[depth] = superclass;
- }
- }
- return superclass;
- } else {
- for (int i = 0; i < interfaces.length; i++) {
- // This is a quadratic algorithm, but normally, the number of
- // interfaces is really small.
- DartType interface = interfaces[i];
- if (interface is InterfaceType &&
- interface.classNode == type.classNode) {
- // This is a potential conflict.
- if (classBuilder.library.isNonNullableByDefault) {
- interface = nnbdTopMerge(
- hierarchy.coreTypes,
- norm(hierarchy.coreTypes, interface),
- norm(hierarchy.coreTypes, type));
- if (interface == null) {
- // This is a conflict.
- // TODO(johnniwinther): Report errors here instead of through
- // the computation of the [ClassHierarchy].
- interface = interfaces[i];
- } else {
- interfaces[i] = interface;
- }
- }
- return interface;
- }
+ ClassHierarchyNode node = hierarchy.getNodeFromClass(type.classNode);
+ if (node == null) return null;
+ int depth = node.depth;
+ int myDepth = superclasses.length;
+ Supertype superclass = depth < myDepth ? superclasses[depth] : null;
+ if (superclass != null && superclass.classNode == type.classNode) {
+ // This is a potential conflict.
+ if (classBuilder.library.isNonNullableByDefault) {
+ superclass = nnbdTopMergeSupertype(
+ hierarchy.coreTypes,
+ normSupertype(hierarchy.coreTypes, superclass),
+ normSupertype(hierarchy.coreTypes, type));
+ if (superclass == null) {
+ // This is a conflict.
+ // TODO(johnniwinther): Report errors here instead of through
+ // the computation of the [ClassHierarchy].
+ superclass = superclasses[depth];
+ } else {
+ superclasses[depth] = superclass;
}
}
- interfaces.add(type);
+ return superclass;
+ } else {
+ for (int i = 0; i < interfaces.length; i++) {
+ // This is a quadratic algorithm, but normally, the number of
+ // interfaces is really small.
+ Supertype interface = interfaces[i];
+ if (interface.classNode == type.classNode) {
+ // This is a potential conflict.
+ if (classBuilder.library.isNonNullableByDefault) {
+ interface = nnbdTopMergeSupertype(
+ hierarchy.coreTypes,
+ normSupertype(hierarchy.coreTypes, interface),
+ normSupertype(hierarchy.coreTypes, type));
+ if (interface == null) {
+ // This is a conflict.
+ // TODO(johnniwinther): Report errors here instead of through
+ // the computation of the [ClassHierarchy].
+ interface = interfaces[i];
+ } else {
+ interfaces[i] = interface;
+ }
+ }
+ return interface;
+ }
+ }
}
+ interfaces.add(type);
return null;
}
@@ -1893,11 +1893,11 @@
/// All superclasses of [classBuilder] excluding itself. The classes are
/// sorted by depth from the root (Object) in ascending order.
- final List<DartType> superclasses;
+ final List<Supertype> superclasses;
/// The list of all classes implemented by [classBuilder] and its supertypes
/// excluding any classes from [superclasses].
- final List<DartType> interfaces;
+ final List<Supertype> interfaces;
/// The longest inheritance path from [classBuilder] to `Object`.
final int maxInheritancePath;
@@ -1923,17 +1923,13 @@
List<ClassHierarchyNode> result = new List<ClassHierarchyNode>(
1 + superclasses.length + interfaces.length);
for (int i = 0; i < superclasses.length; i++) {
- DartType type = superclasses[i];
- if (type is InterfaceType) {
- result[i] = hierarchy.getNodeFromClass(type.classNode);
- }
+ Supertype type = superclasses[i];
+ result[i] = hierarchy.getNodeFromClass(type.classNode);
}
for (int i = 0; i < interfaces.length; i++) {
- DartType type = interfaces[i];
- if (type is InterfaceType) {
- result[i + superclasses.length] =
- hierarchy.getNodeFromClass(type.classNode);
- }
+ Supertype type = interfaces[i];
+ result[i + superclasses.length] =
+ hierarchy.getNodeFromClass(type.classNode);
}
return result..last = this;
}
@@ -1950,20 +1946,20 @@
}
sb..writeln(" superclasses:");
int depth = 0;
- for (DartType superclass in superclasses) {
+ for (Supertype superclass in superclasses) {
sb.write(" " * (depth + 2));
if (depth != 0) sb.write("-> ");
- sb.write(typeToText(superclass));
+ sb.write(typeToText(superclass.asInterfaceType));
sb.writeln();
depth++;
}
if (interfaces != null) {
sb.write(" interfaces:");
bool first = true;
- for (DartType i in interfaces) {
+ for (Supertype i in interfaces) {
if (!first) sb.write(",");
sb.write(" ");
- sb.write(typeToText(i));
+ sb.write(typeToText(i.asInterfaceType));
first = false;
}
sb.writeln();
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index a9bf4c6..f91bfea 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -791,6 +791,7 @@
// This is matched by the call to [forEach_end] in
// [inferElement], [inferMapEntry] or [inferForInStatement].
+ inferrer.flowAnalysis.declare(variable, true);
inferrer.flowAnalysis.forEach_bodyBegin(node, variable, variable.type);
VariableDeclaration tempVariable =
@@ -1049,6 +1050,7 @@
@override
StatementInferenceResult visitFunctionDeclaration(
covariant FunctionDeclarationImpl node) {
+ inferrer.flowAnalysis.declare(node.variable, true);
inferrer.flowAnalysis.functionExpression_begin(node);
inferrer.inferMetadataKeepingHelper(
node.variable, node.variable.annotations);
@@ -5372,8 +5374,9 @@
inferredType = inferrer.inferDeclarationType(
initializerResult.inferredType,
forSyntheticVariable: node.name == null);
- inferrer.flowAnalysis.initialize(node);
+ inferrer.flowAnalysis.declare(node, true);
} else {
+ inferrer.flowAnalysis.declare(node, false);
inferredType = const DynamicType();
}
if (node.isImplicitlyTyped) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index 2cda2a5..97a844a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -24,9 +24,6 @@
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
-import 'package:kernel/binary/limited_ast_to_binary.dart'
- show LimitedBinaryPrinter;
-
import 'package:kernel/text/ast_to_text.dart' show Printer;
/// Print the given [component]. Do nothing if it is `null`. If the
@@ -52,9 +49,7 @@
File output = new File.fromUri(uri);
IOSink sink = output.openWrite();
try {
- BinaryPrinter printer = filter == null
- ? new BinaryPrinter(sink)
- : new LimitedBinaryPrinter(sink, filter ?? (_) => true, false);
+ BinaryPrinter printer = new BinaryPrinter(sink, libraryFilter: filter);
printer.writeComponentFile(component);
} finally {
await sink.close();
@@ -67,11 +62,10 @@
bool includeSources: true,
bool includeOffsets: true}) {
ByteSink byteSink = new ByteSink();
- BinaryPrinter printer = filter == null
- ? new BinaryPrinter(byteSink,
- includeSources: includeSources, includeOffsets: includeOffsets)
- : new LimitedBinaryPrinter(byteSink, filter, !includeSources,
- includeOffsets: includeOffsets);
+ BinaryPrinter printer = new BinaryPrinter(byteSink,
+ libraryFilter: filter,
+ includeSources: includeSources,
+ includeOffsets: includeOffsets);
printer.writeComponentFile(component);
return byteSink.builder.takeBytes();
}
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index e0516e5..d293e88 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -377,6 +377,11 @@
}
@override
+ void handleVoidKeywordWithTypeArguments(Token token) {
+ debugEvent("VoidKeywordWithTypeArguments");
+ }
+
+ @override
void handleNoInitializers() {
debugEvent("NoInitializers");
}
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 43d0792..33555b8 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -1386,6 +1386,13 @@
}
@override
+ void handleVoidKeywordWithTypeArguments(Token token) {
+ debugEvent("VoidKeyword");
+ /*List<TypeBuilder> arguments =*/ pop();
+ push(libraryBuilder.addVoidType(token.charOffset));
+ }
+
+ @override
void beginFormalParameter(Token token, MemberKind kind, Token requiredToken,
Token covariantToken, Token varFinalOrConst) {
if (requiredToken != null && !libraryBuilder.isNonNullableByDefault) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 51842c7..6e651ce 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -51,6 +51,9 @@
VariableDeclaration,
VoidType;
+import 'package:kernel/default_language_version.dart' as kernel
+ show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
+
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
@@ -165,9 +168,8 @@
import 'source_loader.dart' show SourceLoader;
-// TODO(johnniwinther,jensj): Replace this with the correct scheme.
-const int enableNonNullableDefaultMajorVersion = 2;
-const int enableNonNullableDefaultMinorVersion = 8;
+import '../../api_prototype/experimental_flags.dart'
+ show enableNonNullableMajorVersion, enableNonNullableMinorVersion;
class SourceLibraryBuilder extends LibraryBuilderImpl {
static const String MALFORMED_URI_SCHEME = "org-dartlang-malformed-uri";
@@ -383,8 +385,8 @@
@override
bool get isNonNullableByDefault =>
loader.target.enableNonNullable &&
- languageVersion.major >= enableNonNullableDefaultMajorVersion &&
- languageVersion.minor >= enableNonNullableDefaultMinorVersion &&
+ languageVersion.major >= enableNonNullableMajorVersion &&
+ languageVersion.minor >= enableNonNullableMinorVersion &&
!isOptOutPackage(library.importUri) &&
!isOptOutTest(library.importUri);
@@ -3958,10 +3960,10 @@
this.fileUri, this.charOffset, this.charCount, this.isExplicit);
@override
- int get major => Library.defaultLanguageVersionMajor;
+ int get major => kernel.defaultLanguageVersionMajor;
@override
- int get minor => Library.defaultLanguageVersionMinor;
+ int get minor => kernel.defaultLanguageVersionMinor;
@override
bool get valid => false;
@@ -3983,10 +3985,10 @@
const ImplicitLanguageVersion();
@override
- int get major => Library.defaultLanguageVersionMajor;
+ int get major => kernel.defaultLanguageVersionMajor;
@override
- int get minor => Library.defaultLanguageVersionMinor;
+ int get minor => kernel.defaultLanguageVersionMinor;
@override
bool get valid => true;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 23f77b1..3a83aa2 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -2369,7 +2369,8 @@
argMessage.messageObject, argMessage.charOffset, argMessage.length);
} else {
// Argument counts and names match. Compare types.
- int numPositionalArgs = arguments.positional.length;
+ int positionalShift = isImplicitExtensionMember ? 1 : 0;
+ int numPositionalArgs = arguments.positional.length - positionalShift;
for (int i = 0; i < formalTypes.length; i++) {
DartType formalType = formalTypes[i];
DartType expectedType = substitution != null
@@ -2379,7 +2380,7 @@
Expression expression;
NamedExpression namedExpression;
if (i < numPositionalArgs) {
- expression = arguments.positional[i];
+ expression = arguments.positional[positionalShift + i];
positionalArgumentTypes.add(actualType);
} else {
namedExpression = arguments.named[i - numPositionalArgs];
@@ -2393,7 +2394,8 @@
// invocations.
errorTemplate: templateArgumentTypeNotAssignable);
if (namedExpression == null) {
- arguments.positional[i] = expression..parent = arguments;
+ arguments.positional[positionalShift + i] = expression
+ ..parent = arguments;
} else {
namedExpression.value = expression..parent = namedExpression;
}
@@ -2460,7 +2462,7 @@
function.positionalParameters;
for (int i = 0; i < positionalParameters.length; i++) {
VariableDeclaration parameter = positionalParameters[i];
- flowAnalysis.initialize(parameter);
+ flowAnalysis.declare(parameter, true);
inferMetadataKeepingHelper(parameter, parameter.annotations);
if (parameter.initializer != null) {
ExpressionInferenceResult initializerResult = inferExpression(
@@ -2470,7 +2472,7 @@
}
}
for (VariableDeclaration parameter in function.namedParameters) {
- flowAnalysis.initialize(parameter);
+ flowAnalysis.declare(parameter, true);
inferMetadataKeepingHelper(parameter, parameter.annotations);
ExpressionInferenceResult initializerResult =
inferExpression(parameter.initializer, parameter.type, !isTopLevel);
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index a430146..4c59273 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -83,19 +83,10 @@
dillTarget.loader.appendLibraries(sdkSummary);
}
- // TODO(sigmund): provide better error reporting if input summaries or
- // linked dependencies were listed out of order (or provide mechanism to
- // sort them).
- for (Component inputSummary in await options.loadInputSummaries(nameRoot)) {
- loadedComponents.add(inputSummary);
- dillTarget.loader.appendLibraries(inputSummary);
- }
-
- // Linked dependencies are meant to be part of the component so they are not
- // marked external.
- for (Component dependency in await options.loadLinkDependencies(nameRoot)) {
- loadedComponents.add(dependency);
- dillTarget.loader.appendLibraries(dependency);
+ for (Component additionalDill
+ in await options.loadAdditionalDills(nameRoot)) {
+ loadedComponents.add(additionalDill);
+ dillTarget.loader.appendLibraries(additionalDill);
}
await dillTarget.buildOutlines();
diff --git a/pkg/front_end/lib/src/testing/compiler_common.dart b/pkg/front_end/lib/src/testing/compiler_common.dart
index 7adb555..e47eb41 100644
--- a/pkg/front_end/lib/src/testing/compiler_common.dart
+++ b/pkg/front_end/lib/src/testing/compiler_common.dart
@@ -34,8 +34,7 @@
/// Wraps [kernelForProgram] with some default testing options (see [setup]).
Future<CompilerResult> compileScript(dynamic scriptOrSources,
{String fileName: 'main.dart',
- List<String> inputSummaries: const [],
- List<String> linkedDependencies: const [],
+ List<String> additionalDills: const [],
CompilerOptions options,
bool retainDataForTesting: false,
bool requireMain: true}) async {
@@ -47,8 +46,7 @@
assert(scriptOrSources is Map);
sources = scriptOrSources;
}
- await setup(options, sources,
- inputSummaries: inputSummaries, linkedDependencies: linkedDependencies);
+ await setup(options, sources, additionalDills: additionalDills);
return await kernelForProgramInternal(toTestUri(fileName), options,
retainDataForTesting: retainDataForTesting, requireMain: requireMain);
}
@@ -57,12 +55,9 @@
///
/// Wraps [kernelForModule] with some default testing options (see [setup]).
Future<Component> compileUnit(List<String> inputs, Map<String, dynamic> sources,
- {List<String> inputSummaries: const [],
- List<String> linkedDependencies: const [],
- CompilerOptions options}) async {
+ {List<String> additionalDills: const [], CompilerOptions options}) async {
options ??= new CompilerOptions();
- await setup(options, sources,
- inputSummaries: inputSummaries, linkedDependencies: linkedDependencies);
+ await setup(options, sources, additionalDills: additionalDills);
return (await kernelForModule(inputs.map(toTestUri).toList(), options))
.component;
}
@@ -71,11 +66,11 @@
///
/// Wraps [summaryFor] with some default testing options (see [setup]).
Future<List<int>> summarize(List<String> inputs, Map<String, dynamic> sources,
- {List<String> inputSummaries: const [],
+ {List<String> additionalDills: const [],
CompilerOptions options,
bool truncate: false}) async {
options ??= new CompilerOptions();
- await setup(options, sources, inputSummaries: inputSummaries);
+ await setup(options, sources, additionalDills: additionalDills);
return await summaryFor(inputs.map(toTestUri).toList(), options,
truncate: truncate);
}
@@ -91,8 +86,7 @@
///
/// * specify the location of the sdk summaries.
Future<Null> setup(CompilerOptions options, Map<String, dynamic> sources,
- {List<String> inputSummaries: const [],
- List<String> linkedDependencies: const []}) async {
+ {List<String> additionalDills: const []}) async {
MemoryFileSystem fs = new MemoryFileSystem(_defaultDir);
sources.forEach((name, data) {
MemoryFileSystemEntity entity = fs.entityForUri(toTestUri(name));
@@ -111,8 +105,7 @@
options
..verify = true
..fileSystem = new HybridFileSystem(fs)
- ..inputSummaries = inputSummaries.map(toTestUri).toList()
- ..linkedDependencies = linkedDependencies.map(toTestUri).toList()
+ ..additionalDills = additionalDills.map(toTestUri).toList()
..packagesFileUri = toTestUri('.packages');
if (options.sdkSummary == null) {
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index f3c7e88..2ae59d3 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -415,6 +415,8 @@
InvalidVoid/script2: Fail
JsInteropIndexNotSupported/analyzerCode: Fail # Web compiler specific
JsInteropIndexNotSupported/example: Fail # Web compiler specific
+JsInteropNonExternalConstructor/analyzerCode: Fail # Web compiler specific
+JsInteropNonExternalConstructor/example: Fail # Web compiler specific
LanguageVersionInvalidInDotPackages/analyzerCode: Fail
LanguageVersionMismatchInPart/analyzerCode: Fail
LanguageVersionMismatchInPart/part_wrapped_script: Fail # Part in (now) part.
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index faa3186..8b833caa 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -971,6 +971,14 @@
- "void x; main() {}"
- "foo(void x) {} main() { foo(null); }"
+VoidWithTypeArguments:
+ template: "Type 'void' can't have type arguments."
+ tip: "Try removing the type arguments."
+ index: 100
+ analyzerCode: ParserErrorCode.VOID_WITH_TYPE_ARGUMENTS
+ script:
+ - "void<int> f() {}"
+
# TODO(danrubel): Review where this error is generated and consider generating
# FieldInitializedOutsideDeclaringClass instead of this in some situations.
InvalidInitializer:
@@ -3974,7 +3982,10 @@
NonNullableOptOut:
template: "Null safety features are disabled for this library."
- tip: "Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`."
+ # Used to be this:
+ # tip: "Try removing the `@dart=` annotation or setting the language version higher."
+ # Once the version number is locked in, we can write something like that again.
+ tip: "Try removing the `@dart=` annotation or setting the language version higher."
NonNullableOptOutComment:
template: "This is the annotation that opts out this library from null safety features."
@@ -4008,6 +4019,10 @@
template: "JS interop classes do not support [] and []= operator methods."
tip: "Try replacing with a normal method."
+JsInteropNonExternalConstructor:
+ template: "JS interop classes do not support non-external constructors."
+ tip: "Try annotating with `external`."
+
DefaultListConstructorError:
template: "Can't use the default List constructor."
tip: "Try using List.filled instead."
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart
new file mode 100644
index 0000000..8bde84a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart
@@ -0,0 +1 @@
+void<int> f() {}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.expect
new file mode 100644
index 0000000..b18d71f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.expect
@@ -0,0 +1,28 @@
+Problems reported:
+
+parser/error_recovery/issue_39958_01:1:5: Type 'void' can't have type arguments.
+void<int> f() {}
+ ^
+
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null)
+ handleRecoverableError(VoidWithTypeArguments, <, <)
+ beginTypeArguments(<)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(>)
+ handleType(int, null)
+ endTypeArguments(1, <, >)
+ handleVoidKeywordWithTypeArguments(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ endBlockFunctionBody(0, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.intertwined.expect
new file mode 100644
index 0000000..da6f501
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.intertwined.expect
@@ -0,0 +1,40 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, , Instance of 'VoidType', null, f)
+ listener: beginTopLevelMethod(, null)
+ reportRecoverableError(<, VoidWithTypeArguments)
+ listener: handleRecoverableError(VoidWithTypeArguments, <, <)
+ listener: beginTypeArguments(<)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(>)
+ listener: handleType(int, null)
+ listener: endTypeArguments(1, <, >)
+ listener: handleVoidKeywordWithTypeArguments(void)
+ ensureIdentifier(>, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(0, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.parser.expect
new file mode 100644
index 0000000..9820aec
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.parser.expect
@@ -0,0 +1,3 @@
+void<int> f() {}
+
+void[KeywordToken]<[BeginToken]int[StringToken]>[SimpleToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.scanner.expect
new file mode 100644
index 0000000..9820aec
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_01.dart.scanner.expect
@@ -0,0 +1,3 @@
+void<int> f() {}
+
+void[KeywordToken]<[BeginToken]int[StringToken]>[SimpleToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart
new file mode 100644
index 0000000..58b5740
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart
@@ -0,0 +1 @@
+dynamic<int> f() {}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.expect
new file mode 100644
index 0000000..ea1fdaf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.expect
@@ -0,0 +1,22 @@
+beginCompilationUnit(dynamic)
+ beginMetadataStar(dynamic)
+ endMetadataStar(0)
+ beginTopLevelMember(dynamic)
+ beginTopLevelMethod(, null)
+ handleIdentifier(dynamic, typeReference)
+ beginTypeArguments(<)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(>)
+ handleType(int, null)
+ endTypeArguments(1, <, >)
+ handleType(dynamic, null)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ endBlockFunctionBody(0, {, })
+ endTopLevelMethod(dynamic, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.intertwined.expect
new file mode 100644
index 0000000..23ab86d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.intertwined.expect
@@ -0,0 +1,39 @@
+parseUnit(dynamic)
+ skipErrorTokens(dynamic)
+ listener: beginCompilationUnit(dynamic)
+ syntheticPreviousToken(dynamic)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(dynamic)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(dynamic)
+ parseTopLevelMethod(, null, , Instance of 'SimpleTypeWith1Argument', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleIdentifier(dynamic, typeReference)
+ listener: beginTypeArguments(<)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(>)
+ listener: handleType(int, null)
+ listener: endTypeArguments(1, <, >)
+ listener: handleType(dynamic, null)
+ ensureIdentifier(>, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(0, {, })
+ listener: endTopLevelMethod(dynamic, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(dynamic)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.parser.expect
new file mode 100644
index 0000000..fc0bc4d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.parser.expect
@@ -0,0 +1,3 @@
+dynamic<int> f() {}
+
+dynamic[KeywordToken]<[BeginToken]int[StringToken]>[SimpleToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.scanner.expect
new file mode 100644
index 0000000..fc0bc4d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_02.dart.scanner.expect
@@ -0,0 +1,3 @@
+dynamic<int> f() {}
+
+dynamic[KeywordToken]<[BeginToken]int[StringToken]>[SimpleToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart
new file mode 100644
index 0000000..1a13723
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart
@@ -0,0 +1 @@
+int<int> f() {}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.expect
new file mode 100644
index 0000000..c630e6a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.expect
@@ -0,0 +1,22 @@
+beginCompilationUnit(int)
+ beginMetadataStar(int)
+ endMetadataStar(0)
+ beginTopLevelMember(int)
+ beginTopLevelMethod(, null)
+ handleIdentifier(int, typeReference)
+ beginTypeArguments(<)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(>)
+ handleType(int, null)
+ endTypeArguments(1, <, >)
+ handleType(int, null)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ endBlockFunctionBody(0, {, })
+ endTopLevelMethod(int, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.intertwined.expect
new file mode 100644
index 0000000..86f90d9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.intertwined.expect
@@ -0,0 +1,39 @@
+parseUnit(int)
+ skipErrorTokens(int)
+ listener: beginCompilationUnit(int)
+ syntheticPreviousToken(int)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(int)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(int)
+ parseTopLevelMethod(, null, , Instance of 'SimpleTypeWith1Argument', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleIdentifier(int, typeReference)
+ listener: beginTypeArguments(<)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(>)
+ listener: handleType(int, null)
+ listener: endTypeArguments(1, <, >)
+ listener: handleType(int, null)
+ ensureIdentifier(>, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(0, {, })
+ listener: endTopLevelMethod(int, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(int)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.parser.expect
new file mode 100644
index 0000000..4131ad4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.parser.expect
@@ -0,0 +1,3 @@
+int<int> f() {}
+
+int[StringToken]<[BeginToken]int[StringToken]>[SimpleToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.scanner.expect
new file mode 100644
index 0000000..4131ad4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_03.dart.scanner.expect
@@ -0,0 +1,3 @@
+int<int> f() {}
+
+int[StringToken]<[BeginToken]int[StringToken]>[SimpleToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart
new file mode 100644
index 0000000..1a373f5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart
@@ -0,0 +1 @@
+Foo<int> f() {}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.expect
new file mode 100644
index 0000000..bb5654f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.expect
@@ -0,0 +1,22 @@
+beginCompilationUnit(Foo)
+ beginMetadataStar(Foo)
+ endMetadataStar(0)
+ beginTopLevelMember(Foo)
+ beginTopLevelMethod(, null)
+ handleIdentifier(Foo, typeReference)
+ beginTypeArguments(<)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(>)
+ handleType(int, null)
+ endTypeArguments(1, <, >)
+ handleType(Foo, null)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ endBlockFunctionBody(0, {, })
+ endTopLevelMethod(Foo, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.intertwined.expect
new file mode 100644
index 0000000..502ba49
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.intertwined.expect
@@ -0,0 +1,39 @@
+parseUnit(Foo)
+ skipErrorTokens(Foo)
+ listener: beginCompilationUnit(Foo)
+ syntheticPreviousToken(Foo)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(Foo)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(Foo)
+ parseTopLevelMethod(, null, , Instance of 'SimpleTypeWith1Argument', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleIdentifier(Foo, typeReference)
+ listener: beginTypeArguments(<)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(>)
+ listener: handleType(int, null)
+ listener: endTypeArguments(1, <, >)
+ listener: handleType(Foo, null)
+ ensureIdentifier(>, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(0, {, })
+ listener: endTopLevelMethod(Foo, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(Foo)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.parser.expect
new file mode 100644
index 0000000..59a90cf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.parser.expect
@@ -0,0 +1,3 @@
+Foo<int> f() {}
+
+Foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.scanner.expect
new file mode 100644
index 0000000..59a90cf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39958_04.dart.scanner.expect
@@ -0,0 +1,3 @@
+Foo<int> f() {}
+
+Foo[StringToken]<[BeginToken]int[StringToken]>[SimpleToken] f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index c3addc7..5f473d7 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -2923,6 +2923,11 @@
calls.add('handleVoidKeyword $token');
}
+ @override
+ void handleVoidKeywordWithTypeArguments(Token token) {
+ calls.add('handleVoidKeywordWithTypeArguments $token');
+ }
+
noSuchMethod(Invocation invocation) {
throw '${invocation.memberName} should not be called.';
}
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index ce31947..61b94ee 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -23,7 +23,7 @@
show CompilerOptions, DiagnosticMessage;
import 'package:front_end/src/api_prototype/experimental_flags.dart'
- show ExperimentalFlag;
+ show ExperimentalFlag, defaultExperimentalFlags;
import 'package:front_end/src/api_prototype/standard_file_system.dart'
show StandardFileSystem;
@@ -148,21 +148,25 @@
final Expectation runtimeError = ExpectationSet.Default["RuntimeError"];
const String experimentalFlagOptions = '--enable-experiment=';
+const String overwriteCurrentSdkVersion = '--overwrite-current-sdk-version=';
class TestOptions {
- final Map<ExperimentalFlag, bool> experimentalFlags;
+ final Map<ExperimentalFlag, bool> _experimentalFlags;
final bool forceLateLowering;
final bool forceNnbdChecks;
final bool forceNoExplicitGetterCalls;
final bool nnbdAgnosticMode;
final String target;
+ final String overwriteCurrentSdkVersion;
- TestOptions(this.experimentalFlags,
+ TestOptions(this._experimentalFlags,
{this.forceLateLowering: false,
this.forceNnbdChecks: false,
this.forceNoExplicitGetterCalls: false,
this.nnbdAgnosticMode: false,
- this.target: "vm"})
+ this.target: "vm",
+ // can be null
+ this.overwriteCurrentSdkVersion})
: assert(forceLateLowering != null),
assert(forceNnbdChecks != null),
assert(forceNoExplicitGetterCalls != null),
@@ -171,7 +175,8 @@
Map<ExperimentalFlag, bool> computeExperimentalFlags(
Map<ExperimentalFlag, bool> forcedExperimentalFlags) {
- Map<ExperimentalFlag, bool> flags = new Map.from(experimentalFlags);
+ Map<ExperimentalFlag, bool> flags = new Map.from(defaultExperimentalFlags);
+ flags.addAll(_experimentalFlags);
flags.addAll(forcedExperimentalFlags);
return flags;
}
@@ -305,11 +310,15 @@
new File.fromUri(directory.uri.resolve('test.options'));
if (optionsFile.existsSync()) {
List<String> experimentalFlagsArguments = [];
+ String overwriteCurrentSdkVersionArgument = null;
for (String line in optionsFile.readAsStringSync().split('\n')) {
line = line.trim();
if (line.startsWith(experimentalFlagOptions)) {
experimentalFlagsArguments =
line.substring(experimentalFlagOptions.length).split('\n');
+ } else if (line.startsWith(overwriteCurrentSdkVersion)) {
+ overwriteCurrentSdkVersionArgument =
+ line.substring(overwriteCurrentSdkVersion.length);
} else if (line.startsWith(Flags.forceLateLowering)) {
forceLateLowering = true;
} else if (line.startsWith(Flags.forceNnbdChecks)) {
@@ -338,7 +347,8 @@
forceNnbdChecks: forceNnbdChecks,
forceNoExplicitGetterCalls: forceNoExplicitGetterCalls,
nnbdAgnosticMode: nnbdAgnosticMode,
- target: target);
+ target: target,
+ overwriteCurrentSdkVersion: overwriteCurrentSdkVersionArgument);
} else {
testOptions = _computeTestOptionsForDirectory(directory.parent);
}
@@ -366,22 +376,26 @@
Uri sdk = Uri.base.resolve("sdk/");
Uri packages = Uri.base.resolve(".packages");
TestOptions testOptions = computeTestOptions(description);
- ProcessedOptions options = new ProcessedOptions(
- options: new CompilerOptions()
- ..onDiagnostic = (DiagnosticMessage message) {
- throw message.plainTextFormatted.join("\n");
- }
- ..sdkRoot = sdk
- ..packagesFileUri = packages
- ..environmentDefines = {}
- ..experimentalFlags =
- testOptions.computeExperimentalFlags(experimentalFlags)
- ..nnbdMode = weak
- ? NnbdMode.Weak
- : (testOptions.nnbdAgnosticMode
- ? NnbdMode.Agnostic
- : NnbdMode.Strong)
- ..librariesSpecificationUri = librariesSpecificationUri);
+ CompilerOptions compilerOptions = new CompilerOptions()
+ ..onDiagnostic = (DiagnosticMessage message) {
+ throw message.plainTextFormatted.join("\n");
+ }
+ ..sdkRoot = sdk
+ ..packagesFileUri = packages
+ ..environmentDefines = {}
+ ..experimentalFlags =
+ testOptions.computeExperimentalFlags(experimentalFlags)
+ ..nnbdMode = weak
+ ? NnbdMode.Weak
+ : (testOptions.nnbdAgnosticMode
+ ? NnbdMode.Agnostic
+ : NnbdMode.Strong)
+ ..librariesSpecificationUri = librariesSpecificationUri;
+ if (testOptions.overwriteCurrentSdkVersion != null) {
+ compilerOptions.currentSdkVersion =
+ testOptions.overwriteCurrentSdkVersion;
+ }
+ ProcessedOptions options = new ProcessedOptions(options: compilerOptions);
uriTranslator = await options.getUriTranslator();
_uriTranslators[librariesSpecificationUri] = uriTranslator;
}
@@ -535,6 +549,8 @@
Future<Result<int>> run(ComponentResult result, FastaContext context) async {
TestOptions testOptions = context.computeTestOptions(result.description);
+ Map<ExperimentalFlag, bool> experimentalFlags =
+ testOptions.computeExperimentalFlags(context.experimentalFlags);
switch (testOptions.target) {
case "vm":
if (context.platformUri == null) {
@@ -544,6 +560,12 @@
StdioProcess process;
try {
var args = <String>[];
+ if (experimentalFlags[ExperimentalFlag.nonNullable]) {
+ args.add("--enable-experiment=non-nullable");
+ if (!context.weak) {
+ args.add("--null-safety");
+ }
+ }
args.add(generated.path);
process = await StdioProcess.run(context.vm.toFilePath(), args);
print(process.output);
@@ -590,20 +612,23 @@
List<Uri> inputs = <Uri>[description.uri];
ProcessedOptions createProcessedOptions(NnbdMode nnbdMode) {
- return new ProcessedOptions(
- options: new CompilerOptions()
- ..onDiagnostic = (DiagnosticMessage message) {
- if (errors.isNotEmpty) {
- errors.write("\n\n");
- }
- errors.writeAll(message.plainTextFormatted, "\n");
- }
- ..environmentDefines = {}
- ..experimentalFlags = experimentalFlags
- ..performNnbdChecks = testOptions.forceNnbdChecks
- ..nnbdMode = nnbdMode
- ..librariesSpecificationUri = librariesSpecificationUri,
- inputs: inputs);
+ CompilerOptions compilerOptions = new CompilerOptions()
+ ..onDiagnostic = (DiagnosticMessage message) {
+ if (errors.isNotEmpty) {
+ errors.write("\n\n");
+ }
+ errors.writeAll(message.plainTextFormatted, "\n");
+ }
+ ..environmentDefines = {}
+ ..experimentalFlags = experimentalFlags
+ ..performNnbdChecks = testOptions.forceNnbdChecks
+ ..nnbdMode = nnbdMode
+ ..librariesSpecificationUri = librariesSpecificationUri;
+ if (testOptions.overwriteCurrentSdkVersion != null) {
+ compilerOptions.currentSdkVersion =
+ testOptions.overwriteCurrentSdkVersion;
+ }
+ return new ProcessedOptions(options: compilerOptions, inputs: inputs);
}
// Disable colors to ensure that expectation files are the same across
diff --git a/pkg/front_end/test/hot_reload_e2e_test.dart b/pkg/front_end/test/hot_reload_e2e_test.dart
index cda1f76..d58ec7f 100644
--- a/pkg/front_end/test/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/hot_reload_e2e_test.dart
@@ -19,8 +19,7 @@
import 'package:kernel/ast.dart' show Component;
-import 'package:kernel/binary/limited_ast_to_binary.dart'
- show LimitedBinaryPrinter;
+import 'package:kernel/binary/ast_to_binary.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions;
@@ -321,8 +320,8 @@
var sink = new File.fromUri(outputUri).openWrite();
// TODO(sigmund): the incremental generator should always filter these
// libraries instead.
- new LimitedBinaryPrinter(
- sink, (library) => library.importUri.scheme != 'dart', false)
+ new BinaryPrinter(sink,
+ libraryFilter: (library) => library.importUri.scheme != 'dart')
.writeComponentFile(component);
await sink.close();
}
diff --git a/pkg/front_end/test/id_tests/inheritance_test.dart b/pkg/front_end/test/id_tests/inheritance_test.dart
index fa0b755..33de8fd 100644
--- a/pkg/front_end/test/id_tests/inheritance_test.dart
+++ b/pkg/front_end/test/id_tests/inheritance_test.dart
@@ -191,21 +191,18 @@
ClassHierarchyNode classHierarchyNode =
_classHierarchyBuilder.getNodeFromClass(node);
Set<String> supertypes = <String>{};
- void addDartType(DartType type) {
- if (type is InterfaceType) {
- if (type.classNode.isAnonymousMixin) return;
- Supertype supertype =
- new Supertype(type.classNode, type.typeArguments);
- supertypes.add(supertypeToText(
- supertype, TypeRepresentation.analyzerNonNullableByDefault));
- }
+ void addSupertype(Supertype supertype) {
+ if (supertype.classNode.isAnonymousMixin) return;
+ supertypes.add(supertypeToText(
+ supertype, TypeRepresentation.analyzerNonNullableByDefault));
}
- addDartType(_coreTypes.thisInterfaceType(
+ addSupertype(new Supertype(
classHierarchyNode.classBuilder.cls,
- classHierarchyNode.classBuilder.cls.enclosingLibrary.nonNullable));
- classHierarchyNode.superclasses.forEach(addDartType);
- classHierarchyNode.interfaces.forEach(addDartType);
+ getAsTypeArguments(classHierarchyNode.classBuilder.cls.typeParameters,
+ classHierarchyNode.classBuilder.library.library)));
+ classHierarchyNode.superclasses.forEach(addSupertype);
+ classHierarchyNode.interfaces.forEach(addSupertype);
List<String> sorted = supertypes.toList()..sort();
return sorted.join(',');
}
diff --git a/pkg/front_end/test/issue_34856_test.dart b/pkg/front_end/test/issue_34856_test.dart
index 15f424c..7e78eb1 100644
--- a/pkg/front_end/test/issue_34856_test.dart
+++ b/pkg/front_end/test/issue_34856_test.dart
@@ -85,7 +85,7 @@
options = new CompilerOptions()
..fileSystem = fs
- ..linkedDependencies = <Uri>[base.resolve("lib.dart.dill")]
+ ..additionalDills = <Uri>[base.resolve("lib.dart.dill")]
..sdkSummary = platformDill;
List<Uri> inputs = <Uri>[base.resolve("repro.dart")];
diff --git a/pkg/front_end/test/kernel_generator_test.dart b/pkg/front_end/test/kernel_generator_test.dart
index 8103c8c..27fe114 100644
--- a/pkg/front_end/test/kernel_generator_test.dart
+++ b/pkg/front_end/test/kernel_generator_test.dart
@@ -138,7 +138,7 @@
sources['a.dill'] = serializeComponent(unitA);
var unitBC = await compileUnit(['b.dart', 'c.dart'], sources,
- inputSummaries: ['a.dill']);
+ additionalDills: ['a.dill']);
// Pretend that the compiled code is a summary
sources['bc.dill'] = serializeComponent(unitBC);
@@ -155,11 +155,11 @@
}
var unitD1 = await compileUnit(['d.dart'], sources,
- inputSummaries: ['a.dill', 'bc.dill']);
+ additionalDills: ['a.dill', 'bc.dill']);
checkDCallsC(unitD1);
var unitD2 = await compileUnit(['d.dart'], sources,
- inputSummaries: ['bc.dill', 'a.dill']);
+ additionalDills: ['bc.dill', 'a.dill']);
checkDCallsC(unitD2);
});
diff --git a/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart b/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart
index 36d0799..171e212 100644
--- a/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart
+++ b/pkg/front_end/test/language_versioning/language_versioning_up_to_date_test.dart
@@ -3,8 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:io' show Platform, Process, ProcessResult;
+
import 'package:front_end/src/api_prototype/compiler_options.dart';
-import 'package:kernel/ast.dart' as kernel show Library;
+
+import 'package:kernel/default_language_version.dart' as kernel
+ show defaultLanguageVersionMajor, defaultLanguageVersionMinor;
import '../utils/io_utils.dart';
@@ -34,12 +37,12 @@
int major = int.tryParse(dotSeparatedParts[0]);
int minor = int.tryParse(dotSeparatedParts[1]);
- if (kernel.Library.defaultLanguageVersionMajor != major ||
- kernel.Library.defaultLanguageVersionMinor != minor) {
+ if (kernel.defaultLanguageVersionMajor != major ||
+ kernel.defaultLanguageVersionMinor != minor) {
throw "Kernel defaults "
- "${kernel.Library.defaultLanguageVersionMajor}"
+ "${kernel.defaultLanguageVersionMajor}"
"."
- "${kernel.Library.defaultLanguageVersionMinor}"
+ "${kernel.defaultLanguageVersionMinor}"
" does not match output from make_version.py ($major.$minor)";
} else {
print("Kernel version matches.");
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index b3f5376..7845720 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -1603,6 +1603,10 @@
doPrint('handleVoidKeyword(' '$token)');
}
+ void handleVoidKeywordWithTypeArguments(Token token) {
+ doPrint('handleVoidKeywordWithTypeArguments(' '$token)');
+ }
+
void beginYieldStatement(Token token) {
doPrint('beginYieldStatement(' '$token)');
indent++;
diff --git a/pkg/front_end/test/patching/data/opt_in/origin.dart b/pkg/front_end/test/patching/data/opt_in/origin.dart
index 87b2f28..1ccedea 100644
--- a/pkg/front_end/test/patching/data/opt_in/origin.dart
+++ b/pkg/front_end/test/patching/data/opt_in/origin.dart
@@ -4,6 +4,6 @@
/*cfe:nnbd.library: nnbd=true*/
-// @dart=2.8
+// @dart=2.9999
external int method(int? i);
diff --git a/pkg/front_end/test/patching/data/opt_in/patch.dart b/pkg/front_end/test/patching/data/opt_in/patch.dart
index 43884ea..298cd4a 100644
--- a/pkg/front_end/test/patching/data/opt_in/patch.dart
+++ b/pkg/front_end/test/patching/data/opt_in/patch.dart
@@ -2,7 +2,7 @@
// 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.
-// @dart=2.8
+// @dart=2.9999
// ignore: import_internal_library
import 'dart:_internal';
diff --git a/pkg/front_end/test/patching/data/opt_in_patch/patch.dart b/pkg/front_end/test/patching/data/opt_in_patch/patch.dart
index 8b8d368..9ee2b59 100644
--- a/pkg/front_end/test/patching/data/opt_in_patch/patch.dart
+++ b/pkg/front_end/test/patching/data/opt_in_patch/patch.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
/*cfe:nnbd.error: message=The language version override has to be the same in the library and its patch(es).*/
-// @dart=2.8
+// @dart=2.9999
// ignore: import_internal_library
import 'dart:_internal';
diff --git a/pkg/front_end/test/patching/data/opt_out_patch/origin.dart b/pkg/front_end/test/patching/data/opt_out_patch/origin.dart
index 6234d1a..e90fe24 100644
--- a/pkg/front_end/test/patching/data/opt_out_patch/origin.dart
+++ b/pkg/front_end/test/patching/data/opt_out_patch/origin.dart
@@ -4,6 +4,6 @@
/*cfe:nnbd.library: nnbd=true*/
-// @dart=2.8
+// @dart=2.9999
external int method();
diff --git a/pkg/front_end/test/patching/patching_test.dart b/pkg/front_end/test/patching/patching_test.dart
index 5e9b0a4..753ef203 100644
--- a/pkg/front_end/test/patching/patching_test.dart
+++ b/pkg/front_end/test/patching/patching_test.dart
@@ -8,6 +8,7 @@
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
show DataInterpreter, runTests;
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
+import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart';
import 'package:front_end/src/fasta/builder/builder.dart';
import 'package:front_end/src/fasta/builder/class_builder.dart';
@@ -25,9 +26,10 @@
createUriForFileName: createUriForFileName,
onFailure: onFailure,
runTest: runTestFor(const PatchingDataComputer(), [
- new TestConfig(cfeMarker, 'cfe with libraries specification',
+ new TestConfigWithLanguageVersion(
+ cfeMarker, 'cfe with libraries specification',
librariesSpecificationUri: createUriForFileName('libraries.json')),
- new TestConfig(cfeWithNnbdMarker,
+ new TestConfigWithLanguageVersion(cfeWithNnbdMarker,
'cfe with libraries specification and non-nullable',
librariesSpecificationUri: createUriForFileName('libraries.json'),
experimentalFlags: {ExperimentalFlag.nonNullable: true})
@@ -42,6 +44,20 @@
});
}
+class TestConfigWithLanguageVersion extends TestConfig {
+ TestConfigWithLanguageVersion(String marker, String name,
+ {Uri librariesSpecificationUri,
+ Map<ExperimentalFlag, bool> experimentalFlags = const {}})
+ : super(marker, name,
+ librariesSpecificationUri: librariesSpecificationUri,
+ experimentalFlags: experimentalFlags);
+
+ @override
+ void customizeCompilerOptions(CompilerOptions options) {
+ options.currentSdkVersion = "2.9999";
+ }
+}
+
class PatchingDataComputer extends DataComputer<Features> {
const PatchingDataComputer();
diff --git a/pkg/front_end/test/simple_stats.dart b/pkg/front_end/test/simple_stats.dart
index c8ef59e..062d59d 100644
--- a/pkg/front_end/test/simple_stats.dart
+++ b/pkg/front_end/test/simple_stats.dart
@@ -23,9 +23,10 @@
if (confidence < diffMean.abs()) {
double percentDiff = diffMean * 100 / bMean;
double percentDiffConfidence = confidence * 100 / bMean;
- return new TTestResult(true, percentDiff, percentDiffConfidence);
+ return new TTestResult(
+ true, percentDiff, percentDiffConfidence, diffMean, confidence);
} else {
- return new TTestResult(false, 0, 0);
+ return new TTestResult(false, 0, 0, 0, 0);
}
}
@@ -94,15 +95,30 @@
final bool significant;
final double percentDiff;
final double percentDiffConfidence;
+ final double diff;
+ final double confidence;
- TTestResult(this.significant, this.percentDiff, this.percentDiffConfidence);
+ TTestResult(this.significant, this.percentDiff, this.percentDiffConfidence,
+ this.diff, this.confidence);
String toString() {
if (significant) {
+ double leastConfidentChange;
+ if (diff < 0) {
+ leastConfidentChange = diff + confidence;
+ } else {
+ leastConfidentChange = diff - confidence;
+ }
return "TTestResult[significant: "
- "$percentDiff% +/- $percentDiffConfidence%]";
+ "${_format(percentDiff)}% +/- ${_format(percentDiffConfidence)}% "
+ "(${_format(diff)} +/- ${_format(confidence)}) "
+ "(at least ${_format(leastConfidentChange)})]";
} else {
return "TTestResult[not significant]";
}
}
+
+ String _format(double d) {
+ return d.toStringAsFixed(2);
+ }
}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 1553958..1552922 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -151,6 +151,7 @@
ck
cl
claim
+claimed
clarification
clashes
class's
@@ -282,6 +283,7 @@
digest
digests
dijkstra's
+dills
directed
directions
dirtify
@@ -875,6 +877,7 @@
rs
runnable
s
+saw
say
sb
sc
@@ -1122,6 +1125,7 @@
unwraps
unzip
upcast
+update2018
ur
uri's
url
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 8e62978..68fea26 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -136,6 +136,7 @@
angle
annotatable
annotated
+annotating
annotation
annotations
annotator
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 7f38ea6..89ce2e9 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -98,6 +98,7 @@
complement
completers
confidence
+confident
confirm
consecutive
considering
@@ -115,6 +116,7 @@
daemon
dartanalyzer
dartfile
+dash
dashes
day
db
@@ -184,6 +186,7 @@
explain
extern
fac
+faking
falling
favors
fetched
@@ -379,6 +382,7 @@
retains
rev
risky
+runtimes
say
scans
screen
diff --git a/pkg/front_end/test/summary_generator_test.dart b/pkg/front_end/test/summary_generator_test.dart
index bd4775e..486295d 100644
--- a/pkg/front_end/test/summary_generator_test.dart
+++ b/pkg/front_end/test/summary_generator_test.dart
@@ -40,7 +40,7 @@
sourcesWithA['a.dill'] = summaryA;
var summaryBC = await summarize(['b.dart', 'c.dart'], sourcesWithA,
- inputSummaries: ['a.dill']);
+ additionalDills: ['a.dill']);
var sourcesWithABC = new Map<String, dynamic>.from(sourcesWithA);
sourcesWithABC['bc.dill'] = summaryBC;
@@ -48,7 +48,7 @@
// Note: a is loaded first, bc.dill have a.dart as an external reference so
// we want to ensure loading them here will not create a problem.
var summaryD = await summarize(['d.dart'], sourcesWithABC,
- inputSummaries: ['a.dill', 'bc.dill']);
+ additionalDills: ['a.dill', 'bc.dill']);
checkDSummary(summaryD);
});
@@ -59,7 +59,7 @@
sourcesWithA['a.dill'] = summaryA;
var summaryBC = await summarize(['b.dart', 'c.dart'], sourcesWithA,
- inputSummaries: ['a.dill']);
+ additionalDills: ['a.dill']);
var sourcesWithABC = new Map<String, dynamic>.from(sourcesWithA);
sourcesWithABC['bc.dill'] = summaryBC;
@@ -69,7 +69,7 @@
// because we share a CanonicalName root to resolve names across multiple
// dill files and because of how the kernel loader merges definitions.
var summaryD = await summarize(['d.dart'], sourcesWithABC,
- inputSummaries: ['bc.dill', 'a.dill']);
+ additionalDills: ['bc.dill', 'a.dill']);
checkDSummary(summaryD);
});
@@ -84,7 +84,7 @@
var sourcesWithA = new Map<String, dynamic>.from(allSources);
sourcesWithA['a.dill'] = summaryA;
var summaryB = await summarize(['b.dart'], sourcesWithA,
- inputSummaries: ['a.dill'], truncate: true);
+ additionalDills: ['a.dill'], truncate: true);
component = loadComponentFromBytes(summaryB);
expect(component.libraries.length, 1);
expect(
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart b/pkg/front_end/testcases/extensions/issue40816.dart
new file mode 100644
index 0000000..d521d29
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40816.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2019, 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.
+
+class A {}
+
+class B {}
+
+extension on A {
+ void foo(A a, B b) {}
+}
+
+void main() {
+ dynamic a = A();
+ dynamic b = B();
+ A().foo(a, b);
+}
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.outline.expect b/pkg/front_end/testcases/extensions/issue40816.dart.outline.expect
new file mode 100644
index 0000000..934efa0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.outline.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A*
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B*
+ ;
+}
+extension _extension#0 on self::A* {
+ method foo = self::_extension#0|foo;
+ tearoff foo = self::_extension#0|get#foo;
+}
+static method _extension#0|foo(final self::A* #this, self::A* a, self::B* b) → void
+ ;
+static method _extension#0|get#foo(final self::A* #this) → (self::A*, self::B*) →* void
+ return (self::A* a, self::B* b) → void => self::_extension#0|foo(#this, a, b);
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.strong.expect b/pkg/front_end/testcases/extensions/issue40816.dart.strong.expect
new file mode 100644
index 0000000..b69ff84
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.strong.expect
@@ -0,0 +1,26 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A*
+ : super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B*
+ : super core::Object::•()
+ ;
+}
+extension _extension#0 on self::A* {
+ method foo = self::_extension#0|foo;
+ tearoff foo = self::_extension#0|get#foo;
+}
+static method _extension#0|foo(final self::A* #this, self::A* a, self::B* b) → void {}
+static method _extension#0|get#foo(final self::A* #this) → (self::A*, self::B*) →* void
+ return (self::A* a, self::B* b) → void => self::_extension#0|foo(#this, a, b);
+static method main() → void {
+ dynamic a = new self::A::•();
+ dynamic b = new self::B::•();
+ self::_extension#0|foo(new self::A::•(), a as{TypeError,ForDynamic} self::A*, b as{TypeError,ForDynamic} self::B*);
+}
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue40816.dart.strong.transformed.expect
new file mode 100644
index 0000000..b69ff84
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A*
+ : super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B*
+ : super core::Object::•()
+ ;
+}
+extension _extension#0 on self::A* {
+ method foo = self::_extension#0|foo;
+ tearoff foo = self::_extension#0|get#foo;
+}
+static method _extension#0|foo(final self::A* #this, self::A* a, self::B* b) → void {}
+static method _extension#0|get#foo(final self::A* #this) → (self::A*, self::B*) →* void
+ return (self::A* a, self::B* b) → void => self::_extension#0|foo(#this, a, b);
+static method main() → void {
+ dynamic a = new self::A::•();
+ dynamic b = new self::B::•();
+ self::_extension#0|foo(new self::A::•(), a as{TypeError,ForDynamic} self::A*, b as{TypeError,ForDynamic} self::B*);
+}
diff --git a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
index 2fe75da..2d6ae21 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
@@ -27,9 +27,9 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- self::Node* :async_temporary_0;
- self::Node* :async_temporary_1;
- self::Node* :async_temporary_2;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -42,11 +42,11 @@
[yield] let dynamic #t6 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("8", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = _in::unsafeCast<self::Node*>(:result);
[yield] let dynamic #t7 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("9", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
- [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("4", <self::Node*>[new self::Node::•("5", <self::Node*>[:async_temporary_1, :async_temporary_0, _in::unsafeCast<self::Node*>(:result)])])), :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("4", <self::Node*>[new self::Node::•("5", <self::Node*>[_in::unsafeCast<self::Node*>(:async_temporary_1), _in::unsafeCast<self::Node*>(:async_temporary_0), _in::unsafeCast<self::Node*>(:result)])])), :async_op_then, :async_op_error, :async_op) in null;
[yield] let dynamic #t9 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("3", <self::Node*>[_in::unsafeCast<self::Node*>(:result)])), :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = _in::unsafeCast<self::Node*>(:result);
[yield] let dynamic #t10 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("10", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
- self::Node* node = new self::Node::•("1", <self::Node*>[:async_temporary_2, :async_temporary_0, _in::unsafeCast<self::Node*>(:result)]);
+ self::Node* node = new self::Node::•("1", <self::Node*>[_in::unsafeCast<self::Node*>(:async_temporary_2), _in::unsafeCast<self::Node*>(:async_temporary_0), _in::unsafeCast<self::Node*>(:result)]);
core::String* actual = node.{self::Node::toSimpleString}() as{TypeError,ForDynamic} core::String*;
core::print(actual);
if(!actual.{core::String::==}(expected)) {
diff --git a/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
index 3840565..8a2da7f 100644
--- a/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
@@ -55,39 +55,39 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
- core::int* :async_temporary_5;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
+ dynamic :async_temporary_5;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
:async_temporary_0 = self::C::staticField;
[yield] let dynamic #t1 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = self::C::staticField = 1;
[yield] let dynamic #t2 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* f = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* f = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, f);
:async_temporary_2 = self::C::staticGetter;
[yield] let dynamic #t3 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_3 = self::C::staticSetter = 1;
[yield] let dynamic #t4 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_4 = self::C::staticFoo(2);
[yield] let dynamic #t5 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(3, d);
:async_temporary_5 = self::C::staticField.{core::num::+}(self::C::staticGetter).{core::num::+}(self::C::staticSetter = 1).{core::num::+}(self::C::staticFoo(1));
[yield] let dynamic #t6 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_5.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_5).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -111,34 +111,34 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
:async_temporary_0 = self::globalVariable;
[yield] let dynamic #t7 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = self::topLevelGetter;
[yield] let dynamic #t8 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_2 = self::topLevelSetter = 1;
[yield] let dynamic #t9 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_3 = self::topLevelFoo(1);
[yield] let dynamic #t10 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, d);
:async_temporary_4 = self::globalVariable.{core::num::+}(self::topLevelGetter).{core::num::+}(self::topLevelSetter = 1).{core::num::+}(self::topLevelFoo(1));
[yield] let dynamic #t11 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -162,11 +162,11 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
@@ -174,23 +174,23 @@
self::C* inst = new self::C::•();
:async_temporary_0 = inst.{self::C::field};
[yield] let dynamic #t12 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = inst.{self::C::getter};
[yield] let dynamic #t13 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_2 = inst.{self::C::setter} = 1;
[yield] let dynamic #t14 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_3 = inst.{self::C::foo}(1);
[yield] let dynamic #t15 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, d);
:async_temporary_4 = inst.{self::C::field}.{core::num::+}(inst.{self::C::getter}).{core::num::+}(inst.{self::C::setter} = 1).{core::num::+}(inst.{self::C::foo}(1));
[yield] let dynamic #t16 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -214,35 +214,35 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::String* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::List<core::int*>* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
:async_temporary_0 = self::globalVariable;
[yield] let dynamic #t17 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- :async_temporary_0 = "${:async_temporary_0} ${:result} ";
+ :async_temporary_0 = "${_in::unsafeCast<core::int*>(:async_temporary_0)} ${:result} ";
[yield] let dynamic #t18 = asy::_awaitHelper("someString", :async_op_then, :async_op_error, :async_op) in null;
- core::String* a = :async_temporary_0.{core::String::+}(_in::unsafeCast<core::String*>(:result));
+ core::String* a = _in::unsafeCast<core::String*>(:async_temporary_0).{core::String::+}(_in::unsafeCast<core::String*>(:result));
self::expect("1 1 someString", a);
self::C* c = new self::C::•();
:async_temporary_1 = c.{self::C::field};
[yield] let dynamic #t19 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
core::int* cnt = 2;
core::List<core::int*>* b = <core::int*>[1, 2, 3];
:async_temporary_3 = b;
:async_temporary_2 = cnt;
[yield] let dynamic #t20 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- :async_temporary_3.{core::List::[]=}(:async_temporary_2, :result as{TypeError,ForDynamic} core::int*);
+ _in::unsafeCast<core::List<core::int*>*>(:async_temporary_3).{core::List::[]=}(_in::unsafeCast<core::int*>(:async_temporary_2), :result as{TypeError,ForDynamic} core::int*);
self::expect(1, b.{core::List::[]}(cnt));
:async_temporary_4 = b.{core::List::[]}(0);
[yield] let dynamic #t21 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -416,8 +416,8 @@
dynamic :saved_try_context_var3;
dynamic :exception0;
dynamic :stack_trace0;
- core::List<dynamic>* :async_temporary_0;
- core::List<dynamic>* :async_temporary_1;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L7:
@@ -631,7 +631,7 @@
}
:async_temporary_0 = <dynamic>[42];
[yield] let dynamic #t55 = asy::_awaitHelper(testStream1.call().{asy::Stream::toList}(), :async_op_then, :async_op_error, :async_op) in null;
- self::expectList(:async_temporary_0, _in::unsafeCast<core::List<core::int*>*>(:result));
+ self::expectList(_in::unsafeCast<core::List<dynamic>*>(:async_temporary_0), _in::unsafeCast<core::List<core::int*>*>(:result));
function testStream2() → asy::Stream<core::int*>* /* originally async* */ {
asy::_AsyncStarStreamController<core::int*>* :controller;
dynamic :controller_stream;
@@ -670,7 +670,7 @@
}
:async_temporary_1 = <dynamic>[42];
[yield] let dynamic #t57 = asy::_awaitHelper(testStream2.call().{asy::Stream::toList}(), :async_op_then, :async_op_error, :async_op) in null;
- self::expectList(:async_temporary_1, _in::unsafeCast<core::List<core::int*>*>(:result));
+ self::expectList(_in::unsafeCast<core::List<dynamic>*>(:async_temporary_1), _in::unsafeCast<core::List<core::int*>*>(:result));
}
}
}
diff --git a/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
index afe0a4f..52fd146 100644
--- a/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
@@ -17,10 +17,10 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
core::List<core::int*>* :async_temporary_2;
- core::int* :async_temporary_3;
+ dynamic :async_temporary_3;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -30,12 +30,12 @@
:async_temporary_1 = x.{core::num::+}(1);
:async_temporary_0 = x.{core::num::+}(2);
[yield] let dynamic #t1 = asy::_awaitHelper(null, :async_op_then, :async_op_error, :async_op) in null;
- :async_temporary_2 = <core::int*>[:async_temporary_1, :async_temporary_0, _in::unsafeCast<core::Null?>(:result)];
+ :async_temporary_2 = <core::int*>[_in::unsafeCast<core::int*>(:async_temporary_1), _in::unsafeCast<core::int*>(:async_temporary_0), _in::unsafeCast<core::Null?>(:result)];
}
else {
:async_temporary_2 = null;
}
- :return_value = self::bar(:async_temporary_3, :async_temporary_2);
+ :return_value = self::bar(_in::unsafeCast<core::int*>(:async_temporary_3), :async_temporary_2);
break #L1;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart
new file mode 100644
index 0000000..c056d2b
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart
@@ -0,0 +1,4 @@
+dynamic<int> f() {}
+main() {
+ f();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.outline.expect b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.outline.expect
new file mode 100644
index 0000000..bf2c639
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.outline.expect
@@ -0,0 +1,14 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/type_parameters_on_dynamic.dart:1:1: Error: Expected 0 type arguments.
+// dynamic<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.strong.expect b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.strong.expect
new file mode 100644
index 0000000..5e20cb1
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.strong.expect
@@ -0,0 +1,14 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/type_parameters_on_dynamic.dart:1:1: Error: Expected 0 type arguments.
+// dynamic<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type {}
+static method main() → dynamic {
+ self::f();
+}
diff --git a/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.strong.transformed.expect b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.strong.transformed.expect
new file mode 100644
index 0000000..5e20cb1
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/type_parameters_on_dynamic.dart:1:1: Error: Expected 0 type arguments.
+// dynamic<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → invalid-type {}
+static method main() → dynamic {
+ self::f();
+}
diff --git a/pkg/front_end/testcases/general/type_parameters_on_void.dart b/pkg/front_end/testcases/general/type_parameters_on_void.dart
new file mode 100644
index 0000000..ad72c99
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_void.dart
@@ -0,0 +1,5 @@
+void<int> f() {}
+
+main() {
+ f();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/type_parameters_on_void.dart.outline.expect b/pkg/front_end/testcases/general/type_parameters_on_void.dart.outline.expect
new file mode 100644
index 0000000..841412c
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_void.dart.outline.expect
@@ -0,0 +1,15 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/type_parameters_on_void.dart:1:5: Error: Type 'void' can't have type arguments.
+// Try removing the type arguments.
+// void<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/type_parameters_on_void.dart.strong.expect b/pkg/front_end/testcases/general/type_parameters_on_void.dart.strong.expect
new file mode 100644
index 0000000..0f39d1c
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_void.dart.strong.expect
@@ -0,0 +1,15 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/type_parameters_on_void.dart:1:5: Error: Type 'void' can't have type arguments.
+// Try removing the type arguments.
+// void<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → void {}
+static method main() → dynamic {
+ self::f();
+}
diff --git a/pkg/front_end/testcases/general/type_parameters_on_void.dart.strong.transformed.expect b/pkg/front_end/testcases/general/type_parameters_on_void.dart.strong.transformed.expect
new file mode 100644
index 0000000..0f39d1c
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_void.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/type_parameters_on_void.dart:1:5: Error: Type 'void' can't have type arguments.
+// Try removing the type arguments.
+// void<int> f() {}
+// ^
+//
+import self as self;
+
+static method f() → void {}
+static method main() → dynamic {
+ self::f();
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.strong.transformed.expect
index 2fe75da..2d6ae21 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.strong.transformed.expect
@@ -27,9 +27,9 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- self::Node* :async_temporary_0;
- self::Node* :async_temporary_1;
- self::Node* :async_temporary_2;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -42,11 +42,11 @@
[yield] let dynamic #t6 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("8", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = _in::unsafeCast<self::Node*>(:result);
[yield] let dynamic #t7 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("9", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
- [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("4", <self::Node*>[new self::Node::•("5", <self::Node*>[:async_temporary_1, :async_temporary_0, _in::unsafeCast<self::Node*>(:result)])])), :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("4", <self::Node*>[new self::Node::•("5", <self::Node*>[_in::unsafeCast<self::Node*>(:async_temporary_1), _in::unsafeCast<self::Node*>(:async_temporary_0), _in::unsafeCast<self::Node*>(:result)])])), :async_op_then, :async_op_error, :async_op) in null;
[yield] let dynamic #t9 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("3", <self::Node*>[_in::unsafeCast<self::Node*>(:result)])), :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = _in::unsafeCast<self::Node*>(:result);
[yield] let dynamic #t10 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("10", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
- self::Node* node = new self::Node::•("1", <self::Node*>[:async_temporary_2, :async_temporary_0, _in::unsafeCast<self::Node*>(:result)]);
+ self::Node* node = new self::Node::•("1", <self::Node*>[_in::unsafeCast<self::Node*>(:async_temporary_2), _in::unsafeCast<self::Node*>(:async_temporary_0), _in::unsafeCast<self::Node*>(:result)]);
core::String* actual = node.{self::Node::toSimpleString}() as{TypeError,ForDynamic} core::String*;
core::print(actual);
if(!actual.{core::String::==}(expected)) {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
index 2fe75da..2d6ae21 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
@@ -27,9 +27,9 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- self::Node* :async_temporary_0;
- self::Node* :async_temporary_1;
- self::Node* :async_temporary_2;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -42,11 +42,11 @@
[yield] let dynamic #t6 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("8", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = _in::unsafeCast<self::Node*>(:result);
[yield] let dynamic #t7 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("9", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
- [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("4", <self::Node*>[new self::Node::•("5", <self::Node*>[:async_temporary_1, :async_temporary_0, _in::unsafeCast<self::Node*>(:result)])])), :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("4", <self::Node*>[new self::Node::•("5", <self::Node*>[_in::unsafeCast<self::Node*>(:async_temporary_1), _in::unsafeCast<self::Node*>(:async_temporary_0), _in::unsafeCast<self::Node*>(:result)])])), :async_op_then, :async_op_error, :async_op) in null;
[yield] let dynamic #t9 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("3", <self::Node*>[_in::unsafeCast<self::Node*>(:result)])), :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = _in::unsafeCast<self::Node*>(:result);
[yield] let dynamic #t10 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("10", <self::Node*>[])), :async_op_then, :async_op_error, :async_op) in null;
- self::Node* node = new self::Node::•("1", <self::Node*>[:async_temporary_2, :async_temporary_0, _in::unsafeCast<self::Node*>(:result)]);
+ self::Node* node = new self::Node::•("1", <self::Node*>[_in::unsafeCast<self::Node*>(:async_temporary_2), _in::unsafeCast<self::Node*>(:async_temporary_0), _in::unsafeCast<self::Node*>(:result)]);
core::String* actual = node.{self::Node::toSimpleString}() as{TypeError,ForDynamic} core::String*;
core::print(actual);
if(!actual.{core::String::==}(expected)) {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.strong.transformed.expect
index 3840565..8a2da7f 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.strong.transformed.expect
@@ -55,39 +55,39 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
- core::int* :async_temporary_5;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
+ dynamic :async_temporary_5;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
:async_temporary_0 = self::C::staticField;
[yield] let dynamic #t1 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = self::C::staticField = 1;
[yield] let dynamic #t2 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* f = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* f = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, f);
:async_temporary_2 = self::C::staticGetter;
[yield] let dynamic #t3 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_3 = self::C::staticSetter = 1;
[yield] let dynamic #t4 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_4 = self::C::staticFoo(2);
[yield] let dynamic #t5 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(3, d);
:async_temporary_5 = self::C::staticField.{core::num::+}(self::C::staticGetter).{core::num::+}(self::C::staticSetter = 1).{core::num::+}(self::C::staticFoo(1));
[yield] let dynamic #t6 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_5.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_5).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -111,34 +111,34 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
:async_temporary_0 = self::globalVariable;
[yield] let dynamic #t7 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = self::topLevelGetter;
[yield] let dynamic #t8 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_2 = self::topLevelSetter = 1;
[yield] let dynamic #t9 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_3 = self::topLevelFoo(1);
[yield] let dynamic #t10 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, d);
:async_temporary_4 = self::globalVariable.{core::num::+}(self::topLevelGetter).{core::num::+}(self::topLevelSetter = 1).{core::num::+}(self::topLevelFoo(1));
[yield] let dynamic #t11 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -162,11 +162,11 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
@@ -174,23 +174,23 @@
self::C* inst = new self::C::•();
:async_temporary_0 = inst.{self::C::field};
[yield] let dynamic #t12 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = inst.{self::C::getter};
[yield] let dynamic #t13 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_2 = inst.{self::C::setter} = 1;
[yield] let dynamic #t14 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_3 = inst.{self::C::foo}(1);
[yield] let dynamic #t15 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, d);
:async_temporary_4 = inst.{self::C::field}.{core::num::+}(inst.{self::C::getter}).{core::num::+}(inst.{self::C::setter} = 1).{core::num::+}(inst.{self::C::foo}(1));
[yield] let dynamic #t16 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -214,35 +214,35 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::String* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::List<core::int*>* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
:async_temporary_0 = self::globalVariable;
[yield] let dynamic #t17 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- :async_temporary_0 = "${:async_temporary_0} ${:result} ";
+ :async_temporary_0 = "${_in::unsafeCast<core::int*>(:async_temporary_0)} ${:result} ";
[yield] let dynamic #t18 = asy::_awaitHelper("someString", :async_op_then, :async_op_error, :async_op) in null;
- core::String* a = :async_temporary_0.{core::String::+}(_in::unsafeCast<core::String*>(:result));
+ core::String* a = _in::unsafeCast<core::String*>(:async_temporary_0).{core::String::+}(_in::unsafeCast<core::String*>(:result));
self::expect("1 1 someString", a);
self::C* c = new self::C::•();
:async_temporary_1 = c.{self::C::field};
[yield] let dynamic #t19 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
core::int* cnt = 2;
core::List<core::int*>* b = <core::int*>[1, 2, 3];
:async_temporary_3 = b;
:async_temporary_2 = cnt;
[yield] let dynamic #t20 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- :async_temporary_3.{core::List::[]=}(:async_temporary_2, :result as{TypeError,ForDynamic} core::int*);
+ _in::unsafeCast<core::List<core::int*>*>(:async_temporary_3).{core::List::[]=}(_in::unsafeCast<core::int*>(:async_temporary_2), :result as{TypeError,ForDynamic} core::int*);
self::expect(1, b.{core::List::[]}(cnt));
:async_temporary_4 = b.{core::List::[]}(0);
[yield] let dynamic #t21 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -416,8 +416,8 @@
dynamic :saved_try_context_var3;
dynamic :exception0;
dynamic :stack_trace0;
- core::List<dynamic>* :async_temporary_0;
- core::List<dynamic>* :async_temporary_1;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L7:
@@ -631,7 +631,7 @@
}
:async_temporary_0 = <dynamic>[42];
[yield] let dynamic #t55 = asy::_awaitHelper(testStream1.call().{asy::Stream::toList}(), :async_op_then, :async_op_error, :async_op) in null;
- self::expectList(:async_temporary_0, _in::unsafeCast<core::List<core::int*>*>(:result));
+ self::expectList(_in::unsafeCast<core::List<dynamic>*>(:async_temporary_0), _in::unsafeCast<core::List<core::int*>*>(:result));
function testStream2() → asy::Stream<core::int*>* /* originally async* */ {
asy::_AsyncStarStreamController<core::int*>* :controller;
dynamic :controller_stream;
@@ -670,7 +670,7 @@
}
:async_temporary_1 = <dynamic>[42];
[yield] let dynamic #t57 = asy::_awaitHelper(testStream2.call().{asy::Stream::toList}(), :async_op_then, :async_op_error, :async_op) in null;
- self::expectList(:async_temporary_1, _in::unsafeCast<core::List<core::int*>*>(:result));
+ self::expectList(_in::unsafeCast<core::List<dynamic>*>(:async_temporary_1), _in::unsafeCast<core::List<core::int*>*>(:result));
}
}
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
index 3840565..8a2da7f 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
@@ -55,39 +55,39 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
- core::int* :async_temporary_5;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
+ dynamic :async_temporary_5;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
:async_temporary_0 = self::C::staticField;
[yield] let dynamic #t1 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = self::C::staticField = 1;
[yield] let dynamic #t2 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* f = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* f = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, f);
:async_temporary_2 = self::C::staticGetter;
[yield] let dynamic #t3 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_3 = self::C::staticSetter = 1;
[yield] let dynamic #t4 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_4 = self::C::staticFoo(2);
[yield] let dynamic #t5 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(3, d);
:async_temporary_5 = self::C::staticField.{core::num::+}(self::C::staticGetter).{core::num::+}(self::C::staticSetter = 1).{core::num::+}(self::C::staticFoo(1));
[yield] let dynamic #t6 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_5.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_5).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -111,34 +111,34 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
:async_temporary_0 = self::globalVariable;
[yield] let dynamic #t7 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = self::topLevelGetter;
[yield] let dynamic #t8 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_2 = self::topLevelSetter = 1;
[yield] let dynamic #t9 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_3 = self::topLevelFoo(1);
[yield] let dynamic #t10 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, d);
:async_temporary_4 = self::globalVariable.{core::num::+}(self::topLevelGetter).{core::num::+}(self::topLevelSetter = 1).{core::num::+}(self::topLevelFoo(1));
[yield] let dynamic #t11 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -162,11 +162,11 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::int* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::int* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
@@ -174,23 +174,23 @@
self::C* inst = new self::C::•();
:async_temporary_0 = inst.{self::C::field};
[yield] let dynamic #t12 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* a = :async_temporary_0.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* a = _in::unsafeCast<core::int*>(:async_temporary_0).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, a);
:async_temporary_1 = inst.{self::C::getter};
[yield] let dynamic #t13 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* b = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* b = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, b);
:async_temporary_2 = inst.{self::C::setter} = 1;
[yield] let dynamic #t14 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* c = :async_temporary_2.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* c = _in::unsafeCast<core::int*>(:async_temporary_2).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, c);
:async_temporary_3 = inst.{self::C::foo}(1);
[yield] let dynamic #t15 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_3.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_3).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, d);
:async_temporary_4 = inst.{self::C::field}.{core::num::+}(inst.{self::C::getter}).{core::num::+}(inst.{self::C::setter} = 1).{core::num::+}(inst.{self::C::foo}(1));
[yield] let dynamic #t16 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(5, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -214,35 +214,35 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- core::String* :async_temporary_0;
- core::int* :async_temporary_1;
- core::int* :async_temporary_2;
- core::List<core::int*>* :async_temporary_3;
- core::int* :async_temporary_4;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
+ dynamic :async_temporary_3;
+ dynamic :async_temporary_4;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
:async_temporary_0 = self::globalVariable;
[yield] let dynamic #t17 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- :async_temporary_0 = "${:async_temporary_0} ${:result} ";
+ :async_temporary_0 = "${_in::unsafeCast<core::int*>(:async_temporary_0)} ${:result} ";
[yield] let dynamic #t18 = asy::_awaitHelper("someString", :async_op_then, :async_op_error, :async_op) in null;
- core::String* a = :async_temporary_0.{core::String::+}(_in::unsafeCast<core::String*>(:result));
+ core::String* a = _in::unsafeCast<core::String*>(:async_temporary_0).{core::String::+}(_in::unsafeCast<core::String*>(:result));
self::expect("1 1 someString", a);
self::C* c = new self::C::•();
:async_temporary_1 = c.{self::C::field};
[yield] let dynamic #t19 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* d = :async_temporary_1.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* d = _in::unsafeCast<core::int*>(:async_temporary_1).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
core::int* cnt = 2;
core::List<core::int*>* b = <core::int*>[1, 2, 3];
:async_temporary_3 = b;
:async_temporary_2 = cnt;
[yield] let dynamic #t20 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- :async_temporary_3.{core::List::[]=}(:async_temporary_2, :result as{TypeError,ForDynamic} core::int*);
+ _in::unsafeCast<core::List<core::int*>*>(:async_temporary_3).{core::List::[]=}(_in::unsafeCast<core::int*>(:async_temporary_2), :result as{TypeError,ForDynamic} core::int*);
self::expect(1, b.{core::List::[]}(cnt));
:async_temporary_4 = b.{core::List::[]}(0);
[yield] let dynamic #t21 = asy::_awaitHelper(self::dummy(), :async_op_then, :async_op_error, :async_op) in null;
- core::num* e = :async_temporary_4.{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
+ core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num*);
self::expect(2, e);
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -416,8 +416,8 @@
dynamic :saved_try_context_var3;
dynamic :exception0;
dynamic :stack_trace0;
- core::List<dynamic>* :async_temporary_0;
- core::List<dynamic>* :async_temporary_1;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L7:
@@ -631,7 +631,7 @@
}
:async_temporary_0 = <dynamic>[42];
[yield] let dynamic #t55 = asy::_awaitHelper(testStream1.call().{asy::Stream::toList}(), :async_op_then, :async_op_error, :async_op) in null;
- self::expectList(:async_temporary_0, _in::unsafeCast<core::List<core::int*>*>(:result));
+ self::expectList(_in::unsafeCast<core::List<dynamic>*>(:async_temporary_0), _in::unsafeCast<core::List<core::int*>*>(:result));
function testStream2() → asy::Stream<core::int*>* /* originally async* */ {
asy::_AsyncStarStreamController<core::int*>* :controller;
dynamic :controller_stream;
@@ -670,7 +670,7 @@
}
:async_temporary_1 = <dynamic>[42];
[yield] let dynamic #t57 = asy::_awaitHelper(testStream2.call().{asy::Stream::toList}(), :async_op_then, :async_op_error, :async_op) in null;
- self::expectList(:async_temporary_1, _in::unsafeCast<core::List<core::int*>*>(:result));
+ self::expectList(_in::unsafeCast<core::List<dynamic>*>(:async_temporary_1), _in::unsafeCast<core::List<core::int*>*>(:result));
}
}
}
diff --git a/pkg/front_end/testcases/late_lowering/later.dart b/pkg/front_end/testcases/late_lowering/later.dart
index 61d02ae..810ed2f 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart
+++ b/pkg/front_end/testcases/late_lowering/later.dart
@@ -2,7 +2,7 @@
// 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.
-// @dart=2.8
+// @dart=2.9999
// This test checks for compile-time errors and their absence for some use cases
// of late fields and variables.
diff --git a/pkg/front_end/testcases/late_lowering/test.options b/pkg/front_end/testcases/late_lowering/test.options
index 0b0b221..63755f4 100644
--- a/pkg/front_end/testcases/late_lowering/test.options
+++ b/pkg/front_end/testcases/late_lowering/test.options
@@ -1,3 +1,4 @@
--enable-experiment=non-nullable
--force-late-lowering
--force-nnbd-checks
+--overwrite-current-sdk-version=2.9999
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.outline.expect
index 3874625..765b560 100644
--- a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.outline.expect
@@ -12,7 +12,7 @@
// Problems in library:
//
// pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart:21:52: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// class LegacyClass4c implements GenericInterface<num?> {}
// ^
// pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.strong.expect
index 734a657..24eb602 100644
--- a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.strong.expect
@@ -12,7 +12,7 @@
// Problems in library:
//
// pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart:21:52: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// class LegacyClass4c implements GenericInterface<num?> {}
// ^
// pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.weak.expect
index 734a657..24eb602 100644
--- a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.weak.expect
@@ -12,7 +12,7 @@
// Problems in library:
//
// pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart:21:52: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// class LegacyClass4c implements GenericInterface<num?> {}
// ^
// pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart
new file mode 100644
index 0000000..3d43a76
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2019, 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.
+
+typedef F = void Function()?;
+
+void foo(void Function() x) {
+ bar(x);
+ bar(null);
+
+ baz(x);
+ baz(null);
+}
+
+void bar(F x) {}
+void baz(F? x) {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.outline.expect
new file mode 100644
index 0000000..3429c36
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.outline.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+typedef F = () →? void;
+static method foo(() → void x) → void
+ ;
+static method bar(() →? void x) → void
+ ;
+static method baz(() →? void x) → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.expect
new file mode 100644
index 0000000..425f791
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+typedef F = () →? void;
+static method foo(() → void x) → void {
+ self::bar(x);
+ self::bar(null);
+ self::baz(x);
+ self::baz(null);
+}
+static method bar(() →? void x) → void {}
+static method baz(() →? void x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.transformed.expect
new file mode 100644
index 0000000..425f791
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+typedef F = () →? void;
+static method foo(() → void x) → void {
+ self::bar(x);
+ self::bar(null);
+ self::baz(x);
+ self::baz(null);
+}
+static method bar(() →? void x) → void {}
+static method baz(() →? void x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.expect
new file mode 100644
index 0000000..425f791
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+typedef F = () →? void;
+static method foo(() → void x) → void {
+ self::bar(x);
+ self::bar(null);
+ self::baz(x);
+ self::baz(null);
+}
+static method bar(() →? void x) → void {}
+static method baz(() →? void x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.transformed.expect
new file mode 100644
index 0000000..425f791
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.weak.transformed.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+typedef F = () →? void;
+static method foo(() → void x) → void {
+ self::bar(x);
+ self::bar(null);
+ self::baz(x);
+ self::baz(null);
+}
+static method bar(() →? void x) → void {}
+static method baz(() →? void x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.outline.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.outline.expect
index cfcc66f..7361e96 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.outline.expect
@@ -30,7 +30,7 @@
// Problems in library:
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:18:25: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// class B extends A<String?> {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -38,7 +38,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:20:28: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// typedef F = void Function()?;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -46,7 +46,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:22:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = [];
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -54,7 +54,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:23:7: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -62,7 +62,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:28:21: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// void method(void f()?, {int a}) {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -70,7 +70,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:24:10: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.strong.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.strong.expect
index 2fce215..66a160f 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.strong.expect
@@ -35,7 +35,7 @@
// Problems in library:
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:18:25: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// class B extends A<String?> {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -43,7 +43,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:20:28: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// typedef F = void Function()?;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -51,7 +51,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:22:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = [];
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -59,7 +59,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:23:7: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -67,7 +67,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:28:21: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// void method(void f()?, {int a}) {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -75,7 +75,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:24:10: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -83,7 +83,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:32:14: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -91,7 +91,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:33:9: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -99,7 +99,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:34:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.strong.transformed.expect
index 2fce215..66a160f 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.strong.transformed.expect
@@ -35,7 +35,7 @@
// Problems in library:
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:18:25: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// class B extends A<String?> {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -43,7 +43,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:20:28: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// typedef F = void Function()?;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -51,7 +51,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:22:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = [];
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -59,7 +59,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:23:7: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -67,7 +67,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:28:21: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// void method(void f()?, {int a}) {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -75,7 +75,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:24:10: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -83,7 +83,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:32:14: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -91,7 +91,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:33:9: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -99,7 +99,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:34:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.weak.expect
index 2fce215..66a160f 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.weak.expect
@@ -35,7 +35,7 @@
// Problems in library:
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:18:25: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// class B extends A<String?> {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -43,7 +43,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:20:28: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// typedef F = void Function()?;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -51,7 +51,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:22:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = [];
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -59,7 +59,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:23:7: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -67,7 +67,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:28:21: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// void method(void f()?, {int a}) {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -75,7 +75,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:24:10: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -83,7 +83,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:32:14: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -91,7 +91,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:33:9: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -99,7 +99,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:34:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.weak.transformed.expect
index 2fce215..66a160f 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
// Problems in library:
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:18:25: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// class B extends A<String?> {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -43,7 +43,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:20:28: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// typedef F = void Function()?;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -51,7 +51,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:22:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = [];
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -59,7 +59,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:23:7: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -67,7 +67,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:28:21: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// void method(void f()?, {int a}) {}
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -75,7 +75,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:24:10: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -83,7 +83,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:32:14: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// List<String?> l = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -91,7 +91,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:33:9: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// String? s = null;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
@@ -99,7 +99,7 @@
// ^^^^^^^^^^^^
//
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:34:12: Error: Null safety features are disabled for this library.
-// Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.8`.
+// Try removing the `@dart=` annotation or setting the language version higher.
// var t = s!;
// ^
// pkg/front_end/testcases/nnbd/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 3cee311..95377bb 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -57,6 +57,7 @@
extensions/issue38755: TextSerializationFailure
extensions/issue38915: TextSerializationFailure
extensions/issue39938/issue39938: TextSerializationFailure
+extensions/issue40816: TextSerializationFailure
extensions/missing_toplevel: TextSerializationFailure
extensions/nested_on_types: TextSerializationFailure
extensions/null_aware: TextSerializationFailure
@@ -342,6 +343,8 @@
general/type_literal_as_metadata: TextSerializationFailure
general/type_of_null: TextSerializationFailure
general/type_parameter_type_named_int: TextSerializationFailure
+general/type_parameters_on_dynamic: TextSerializationFailure
+general/type_parameters_on_void: TextSerializationFailure
general/type_variable_as_super: TextSerializationFailure # Was: RuntimeError
general/type_variable_bound_access: TypeCheckError
general/type_variable_prefix: TextSerializationFailure # Was: RuntimeError
@@ -1299,6 +1302,7 @@
nnbd/nullable_null: TextSerializationFailure
nnbd/nullable_param: TextSerializationFailure
nnbd/nullable_receiver: TextSerializationFailure
+nnbd/nullable_rhs_of_typedef: TextSerializationFailure
nnbd/opt_out: TextSerializationFailure
nnbd/override_checks: TextSerializationFailure
nnbd/platform_definite_assignment/main: TextSerializationFailure
diff --git a/pkg/front_end/tool/_fasta/bulk_compile.dart b/pkg/front_end/tool/_fasta/bulk_compile.dart
deleted file mode 100644
index c50da92..0000000
--- a/pkg/front_end/tool/_fasta/bulk_compile.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2017, 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.
-
-import 'dart:async' show Future;
-
-import 'dart:convert' show utf8;
-
-import 'package:front_end/src/api_prototype/compiler_options.dart'
- show CompilerOptions;
-
-import 'package:front_end/src/api_prototype/file_system.dart'
- show FileSystem, FileSystemEntity, FileSystemException;
-
-import 'package:front_end/src/api_prototype/standard_file_system.dart'
- show StandardFileSystem;
-
-import 'package:front_end/src/base/processed_options.dart'
- show ProcessedOptions;
-
-import 'package:front_end/src/compute_platform_binaries_location.dart'
- show computePlatformBinariesLocation;
-
-import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
-
-import 'package:front_end/src/kernel_generator_impl.dart'
- show InternalCompilerResult, generateKernelInternal;
-
-const String customScheme = "org-dartlang-bulkcompile";
-
-final Uri mainUri = new Uri(scheme: customScheme, host: "", path: "/main.dart");
-
-class BulkCompiler {
- final ProcessedOptions options;
-
- BulkCompiler(CompilerOptions options)
- : options = new ProcessedOptions(
- options: options
- ..packagesFileUri ??= Uri.base.resolve(".packages")
- ..linkedDependencies = <Uri>[
- computePlatformBinariesLocation(forceBuildDir: true)
- .resolve("vm_platform_strong.dill")
- ]
- ..fileSystem = (new FileBackedMemoryFileSystem()
- ..entities[mainUri.path] =
- (new MemoryFileSystemEntity(mainUri)..bytes = <int>[])),
- inputs: <Uri>[mainUri]);
-
- Future<Null> compile(String source) {
- defineSource(mainUri.path, source);
- return CompilerContext.runWithOptions(options,
- (CompilerContext context) async {
- (await context.options.loadSdkSummary(null))?.computeCanonicalNames();
- InternalCompilerResult result = await generateKernelInternal();
- result?.component?.unbindCanonicalNames();
- return null;
- });
- }
-
- void defineSource(String path, String source) {
- if (!path.startsWith("/")) {
- throw new ArgumentError("'path' should start with a slash ('/').");
- }
- Uri uri = new Uri(scheme: customScheme, host: "", path: path);
- MemoryFileSystemEntity entity = options.fileSystem.entityForUri(uri);
- entity.bytes = utf8.encode(source);
- }
-}
-
-class FileBackedMemoryFileSystem implements FileSystem {
- final Map<String, MemoryFileSystemEntity> entities =
- <String, MemoryFileSystemEntity>{};
-
- FileSystemEntity entityForUri(Uri uri) {
- if (uri.scheme == customScheme) {
- MemoryFileSystemEntity entity = entities[uri.path];
- if (entity == null) {
- entity = new MemoryFileSystemEntity(uri);
- entities[uri.path] = entity;
- }
- return entity;
- } else {
- return StandardFileSystem.instance.entityForUri(uri);
- }
- }
-}
-
-class MemoryFileSystemEntity implements FileSystemEntity {
- final Uri uri;
-
- List<int> bytes;
-
- MemoryFileSystemEntity(this.uri);
-
- Future<List<int>> readAsBytes() {
- return bytes == null
- ? new Future.error(new FileSystemException(uri, "Not found"))
- : new Future.value(bytes);
- }
-
- Future<String> readAsString() {
- throw "unsupported operation";
- }
-
- Future<bool> exists() => new Future.value(bytes != null);
-}
diff --git a/pkg/front_end/tool/_fasta/bulk_compile_test.dart b/pkg/front_end/tool/_fasta/bulk_compile_test.dart
deleted file mode 100644
index 29b98c9..0000000
--- a/pkg/front_end/tool/_fasta/bulk_compile_test.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017, 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.
-
-import 'dart:isolate' show ReceivePort;
-
-import 'package:front_end/src/api_prototype/compiler_options.dart'
- show CompilerOptions;
-
-import 'bulk_compile.dart' show BulkCompiler;
-
-testCompiler() async {
- BulkCompiler compiler = new BulkCompiler(new CompilerOptions()
- ..debugDump = true
- ..verbose = true);
- await compiler.compile("main() { print('Hello, World!'); }");
- await compiler.compile(
- // This example is a regression test of lazy loading of FunctionNode
- // which would break when this is preceded by hello-world.
- "main() { [].map(); }");
- await compiler.compile("main() { print('Hello, Brave New World!'); }");
- await compiler.compile("import 'package';");
-}
-
-main() {
- var port = new ReceivePort();
- testCompiler().whenComplete(port.close);
-}
diff --git a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
index 2b2442e..9d8b634 100644
--- a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
+++ b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
@@ -2,11 +2,7 @@
// 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.
-import 'dart:async';
-
-import 'dart:io';
-
-import 'dart:isolate';
+import 'dart:io' show File, Platform;
import 'package:_fe_analyzer_shared/src/scanner/characters.dart'
show $A, $MINUS, $a, $z;
@@ -15,23 +11,75 @@
import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
-main(List<String> arguments) async {
- var port = new ReceivePort();
- await new File.fromUri(await computeGeneratedFile())
- .writeAsString(await generateMessagesFile(), flush: true);
- port.close();
+main(List<String> arguments) {
+ new File.fromUri(computeCfeGeneratedFile())
+ .writeAsStringSync(generateCfeFile(), flush: true);
+ new File.fromUri(computeKernelGeneratedFile())
+ .writeAsStringSync(generateKernelFile(), flush: true);
}
-Future<Uri> computeGeneratedFile() {
- return Isolate.resolvePackageUri(
- Uri.parse('package:front_end/src/api_prototype/experimental_flags.dart'));
+Uri computeCfeGeneratedFile() {
+ return Platform.script
+ .resolve("../../lib/src/api_prototype/experimental_flags.dart");
}
-Future<String> generateMessagesFile() async {
- Uri messagesFile =
- Platform.script.resolve("../../../../tools/experimental_features.yaml");
+Uri computeKernelGeneratedFile() {
+ return Platform.script
+ .resolve("../../../kernel/lib/default_language_version.dart");
+}
+
+Uri computeYamlFile() {
+ return Platform.script
+ .resolve("../../../../tools/experimental_features.yaml");
+}
+
+String generateKernelFile() {
+ Uri yamlFile = computeYamlFile();
Map<dynamic, dynamic> yaml =
- loadYaml(await new File.fromUri(messagesFile).readAsStringSync());
+ loadYaml(new File.fromUri(yamlFile).readAsStringSync());
+
+ int currentVersionMajor;
+ int currentVersionMinor;
+ {
+ String currentVersion = getAsVersionNumberString(yaml['current-version']);
+ List<String> split = currentVersion.split(".");
+ currentVersionMajor = int.parse(split[0]);
+ currentVersionMinor = int.parse(split[1]);
+ }
+
+ StringBuffer sb = new StringBuffer();
+
+ sb.write('''
+// Copyright (c) 2020, 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.
+
+// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
+//
+// Instead modify 'tools/experimental_features.yaml' and run
+// 'pkg/front_end/tool/fasta generate-experimental-flags' to update.
+
+ int defaultLanguageVersionMajor = $currentVersionMajor;
+ int defaultLanguageVersionMinor = $currentVersionMinor;
+''');
+
+ return new DartFormatter().format("$sb");
+}
+
+String generateCfeFile() {
+ Uri yamlFile = computeYamlFile();
+ Map<dynamic, dynamic> yaml =
+ loadYaml(new File.fromUri(yamlFile).readAsStringSync());
+
+ int currentVersionMajor;
+ int currentVersionMinor;
+ {
+ String currentVersion = getAsVersionNumberString(yaml['current-version']);
+ List<String> split = currentVersion.split(".");
+ currentVersionMajor = int.parse(split[0]);
+ currentVersionMinor = int.parse(split[1]);
+ }
+
StringBuffer sb = new StringBuffer();
sb.write('''
@@ -53,16 +101,41 @@
enum ExperimentalFlag {
''');
- for (var key in keys) {
+ for (String key in keys) {
sb.writeln(' ${keyToIdentifier(key)},');
}
sb.write('''
}
+''');
+
+ for (String key in keys) {
+ int major;
+ int minor;
+ String enabledIn =
+ getAsVersionNumberString((features[key] as YamlMap)['enabledIn']);
+ if (enabledIn == null) {
+ major = currentVersionMajor;
+ minor = currentVersionMinor;
+ } else {
+ List<String> split = enabledIn.split(".");
+ major = int.parse(split[0]);
+ minor = int.parse(split[1]);
+ }
+ sb.writeln(' const int enable'
+ '${keyToIdentifier(key, upperCaseFirst: true)}'
+ 'MajorVersion = $major;');
+ sb.writeln(' const int enable'
+ '${keyToIdentifier(key, upperCaseFirst: true)}'
+ 'MinorVersion = $minor;');
+ }
+
+ sb.write('''
+
ExperimentalFlag parseExperimentalFlag(String flag) {
switch (flag) {
''');
- for (var key in keys) {
+ for (String key in keys) {
sb.writeln(' case "$key":');
sb.writeln(' return ExperimentalFlag.${keyToIdentifier(key)};');
}
@@ -72,8 +145,8 @@
const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
''');
- for (var key in keys) {
- var expired = (features[key] as YamlMap)['expired'];
+ for (String key in keys) {
+ bool expired = (features[key] as YamlMap)['expired'];
bool shipped = (features[key] as YamlMap)['enabledIn'] != null;
sb.writeln(' ExperimentalFlag.${keyToIdentifier(key)}: ${shipped},');
if (shipped) {
@@ -87,7 +160,7 @@
const Map<ExperimentalFlag, bool> expiredExperimentalFlags = {
''');
- for (var key in keys) {
+ for (String key in keys) {
bool expired = (features[key] as YamlMap)['expired'] == true;
sb.writeln(' ExperimentalFlag.${keyToIdentifier(key)}: ${expired},');
}
@@ -96,10 +169,11 @@
return new DartFormatter().format("$sb");
}
-keyToIdentifier(String key) {
- var identifier = StringBuffer();
+keyToIdentifier(String key, {bool upperCaseFirst = false}) {
+ StringBuffer identifier = StringBuffer();
+ bool first = true;
for (int index = 0; index < key.length; ++index) {
- var code = key.codeUnitAt(index);
+ int code = key.codeUnitAt(index);
if (code == $MINUS) {
++index;
code = key.codeUnitAt(index);
@@ -107,7 +181,18 @@
code = code - $a + $A;
}
}
+ if (first && upperCaseFirst && $a <= code && code <= $z) {
+ code = code - $a + $A;
+ }
+ first = false;
identifier.writeCharCode(code);
}
return identifier.toString();
}
+
+String getAsVersionNumberString(dynamic value) {
+ if (value == null) return null;
+ if (value is String) return value;
+ if (value is double) return "$value";
+ throw "Unexpected value: $value (${value.runtimeType})";
+}
diff --git a/pkg/front_end/tool/_fasta/generate_experimental_flags_test.dart b/pkg/front_end/tool/_fasta/generate_experimental_flags_test.dart
index ad1ac6e..1249933 100644
--- a/pkg/front_end/tool/_fasta/generate_experimental_flags_test.dart
+++ b/pkg/front_end/tool/_fasta/generate_experimental_flags_test.dart
@@ -2,22 +2,35 @@
// 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.
-import "dart:io" show File;
-
-import "package:async_helper/async_helper.dart" show asyncTest;
-
-import "package:expect/expect.dart" show Expect;
+import "dart:io" show File, exitCode;
import "generate_experimental_flags.dart"
- show computeGeneratedFile, generateMessagesFile;
+ show
+ computeCfeGeneratedFile,
+ computeKernelGeneratedFile,
+ generateCfeFile,
+ generateKernelFile;
main() {
- asyncTest(() async {
- Uri generatedFile = await computeGeneratedFile();
- String generated = await generateMessagesFile();
- String actual = (await new File.fromUri(generatedFile).readAsString())
+ {
+ Uri generatedFile = computeCfeGeneratedFile();
+ String generated = generateCfeFile();
+ String actual = (new File.fromUri(generatedFile).readAsStringSync())
.replaceAll('\r\n', '\n');
- Expect.stringEquals(generated, actual, """
+ check(generated, actual, generatedFile);
+ }
+ {
+ Uri generatedFile = computeKernelGeneratedFile();
+ String generated = generateKernelFile();
+ String actual = (new File.fromUri(generatedFile).readAsStringSync())
+ .replaceAll('\r\n', '\n');
+ check(generated, actual, generatedFile);
+ }
+}
+
+void check(String generated, String actual, Uri generatedFile) {
+ if (generated != actual) {
+ print("""
------------------------
The generated file
@@ -28,5 +41,6 @@
------------------------
""");
- });
+ exitCode = 1;
+ }
}
diff --git a/pkg/front_end/tool/stat_on_dash_v.dart b/pkg/front_end/tool/stat_on_dash_v.dart
new file mode 100644
index 0000000..ead3e7b
--- /dev/null
+++ b/pkg/front_end/tool/stat_on_dash_v.dart
@@ -0,0 +1,225 @@
+import "dart:io";
+
+import "../test/simple_stats.dart";
+
+void usage([String extraMessage]) {
+ print("Usage:");
+ print("On Linux via bash you can do something like");
+ print("dart pkg/front_end/tool/stat_on_dash_v.dart \ "
+ " now_run_{1..10}.data then_run_{1..10}.data");
+ if (extraMessage != null) {
+ print("");
+ print("Notice:");
+ print(extraMessage);
+ }
+ exit(1);
+}
+
+main(List<String> args) {
+ if (args.length < 4) {
+ usage("Requires more input.");
+ }
+ // Maps from "part" (or "category" or whatever) =>
+ // (map from file group => list of runtimes)
+ Map<String, Map<String, List<int>>> data = {};
+ Set<String> allGroups = {};
+ for (String file in args) {
+ File f = new File(file);
+ if (!f.existsSync()) usage("$file doesn't exist.");
+ String groupId = replaceNumbers(file);
+ allGroups.add(groupId);
+ String fileContent = f.readAsStringSync();
+ List<String> fileLines = fileContent.split("\n");
+ Set<String> partsSeen = {};
+ for (String line in fileLines) {
+ if (!isTimePrependedLine(line)) continue;
+ String trimmedLine = line.substring(16).trim();
+ String part = replaceNumbers(trimmedLine);
+ if (!partsSeen.add(part)) {
+ int seen = 2;
+ while (true) {
+ String newPartName = "$part ($seen)";
+ if (partsSeen.add(newPartName)) {
+ part = newPartName;
+ break;
+ }
+ seen++;
+ }
+ }
+ int microSeconds = findMs(trimmedLine, inMs: true);
+ Map<String, List<int>> groupToTime = data[part] ??= {};
+ List<int> times = groupToTime[groupId] ??= [];
+ times.add(microSeconds);
+ }
+ }
+
+ if (allGroups.length < 2) {
+ assert(allGroups.length == 1);
+ usage("Found only 1 group. At least two are required.");
+ }
+
+ Map<String, double> combinedChange = {};
+
+ bool printedAnything = false;
+ for (String part in data.keys) {
+ Map<String, List<int>> partData = data[part];
+ List<int> prevRuntimes;
+ String prevGroup;
+ bool printed = false;
+ for (String group in allGroups) {
+ List<int> runtimes = partData[group];
+ if (runtimes == null) {
+ // Fake it to be a small list of 0s.
+ runtimes = new List<int>.filled(5, 0);
+ if (!printed) {
+ printed = true;
+ print("$part:");
+ }
+ print("Notice: faking data for $group");
+ }
+ if (prevRuntimes != null) {
+ TTestResult result = SimpleTTestStat.ttest(runtimes, prevRuntimes);
+ if (result.significant) {
+ if (!printed) {
+ printed = true;
+ print("$part:");
+ }
+ print("$prevGroup => $group: $result");
+ print("$group: $runtimes");
+ print("$prevGroup: $prevRuntimes");
+ combinedChange["$prevGroup => $group"] ??= 0;
+ double leastConfidentChange;
+ if (result.diff < 0) {
+ leastConfidentChange = result.diff + result.confidence;
+ } else {
+ leastConfidentChange = result.diff - result.confidence;
+ }
+
+ combinedChange["$prevGroup => $group"] += leastConfidentChange;
+ }
+ }
+ prevRuntimes = runtimes;
+ prevGroup = group;
+ }
+ if (printed) {
+ print("---");
+ printedAnything = true;
+ }
+ }
+ if (printedAnything) {
+ for (String part in combinedChange.keys) {
+ print("Combined least change for $part: "
+ "${combinedChange[part].toStringAsFixed(2)} ms.");
+ }
+ } else {
+ print("Nothing significant found.");
+ }
+}
+
+/// Returns ms or µs or throws if ms not found.
+int findMs(String s, {bool inMs: true}) {
+ // Find " in " followed by numbers possibly followed by (a dot and more
+ // numbers) followed by "ms"; e.g. " in 42.3ms"
+
+ // This is O(n^2) but it doesn't matter.
+ for (int i = 0; i < s.length; i++) {
+ int j = 0;
+ if (s.codeUnitAt(i + j++) != $SPACE) continue;
+ if (s.codeUnitAt(i + j++) != $i) continue;
+ if (s.codeUnitAt(i + j++) != $n) continue;
+ if (s.codeUnitAt(i + j++) != $SPACE) continue;
+ int numberStartsAt = i + j;
+ if (!isNumber(s.codeUnitAt(i + j++))) continue;
+ while (isNumber(s.codeUnitAt(i + j))) {
+ j++;
+ }
+ // We've seen " is 0+" => we should now either have "ms" or a dot,
+ // more numbers followed by "ms".
+ if (s.codeUnitAt(i + j) == $m) {
+ j++;
+ if (s.codeUnitAt(i + j++) != $s) continue;
+ // Seen " is 0+ms" => We're done.
+ int ms = int.parse(s.substring(numberStartsAt, i + j - 2));
+ if (inMs) return ms;
+ return ms * 1000;
+ } else if (s.codeUnitAt(i + j) == $PERIOD) {
+ int dotAt = i + j;
+ j++;
+ if (!isNumber(s.codeUnitAt(i + j++))) continue;
+ while (isNumber(s.codeUnitAt(i + j))) {
+ j++;
+ }
+ if (s.codeUnitAt(i + j++) != $m) continue;
+ if (s.codeUnitAt(i + j++) != $s) continue;
+ // Seen " is 0+.0+ms" => We're done.
+ // int.parse(s.substring(numberStartsAt, i + j - 2));
+ int ms = int.parse(s.substring(numberStartsAt, dotAt));
+ if (inMs) return ms;
+ int fraction = int.parse(s.substring(dotAt + 1, i + j - 2));
+ while (fraction < 100) {
+ fraction *= 10;
+ }
+ while (fraction >= 1000) {
+ fraction ~/= 10;
+ }
+ return ms * 1000 + fraction;
+ } else {
+ continue;
+ }
+ }
+ usage("Didn't find any ms data in line '$s'.");
+ throw "usage should exit";
+}
+
+const int $SPACE = 32;
+const int $PERIOD = 46;
+const int $0 = 48;
+const int $9 = 57;
+const int $COLON = 58;
+const int $_ = 95;
+const int $i = 105;
+const int $m = 109;
+const int $n = 110;
+const int $s = 115;
+
+/// Check that format is like '0:00:00.000000: '.
+bool isTimePrependedLine(String s) {
+ if (s.length < 15) return false;
+ int index = 0;
+ if (!isNumber(s.codeUnitAt(index++))) return false;
+ if (s.codeUnitAt(index++) != $COLON) return false;
+ if (!isNumber(s.codeUnitAt(index++))) return false;
+ if (!isNumber(s.codeUnitAt(index++))) return false;
+ if (s.codeUnitAt(index++) != $COLON) return false;
+ if (!isNumber(s.codeUnitAt(index++))) return false;
+ if (!isNumber(s.codeUnitAt(index++))) return false;
+ if (s.codeUnitAt(index++) != $PERIOD) return false;
+ for (int i = 0; i < 6; i++) {
+ if (!isNumber(s.codeUnitAt(index++))) return false;
+ }
+ if (s.codeUnitAt(index++) != $COLON) return false;
+ return true;
+}
+
+bool isNumber(int codeUnit) {
+ return codeUnit >= $0 && codeUnit <= $9;
+}
+
+String replaceNumbers(String s) {
+ StringBuffer sb = new StringBuffer();
+ bool lastWasNumber = false;
+ for (int i = 0; i < s.length; i++) {
+ int codeUnit = s.codeUnitAt(i);
+ if (isNumber(codeUnit)) {
+ if (!lastWasNumber) {
+ // Ignore number; replace with '_'.
+ sb.writeCharCode($_);
+ lastWasNumber = true;
+ }
+ } else {
+ sb.writeCharCode(codeUnit);
+ lastWasNumber = false;
+ }
+ }
+ return sb.toString();
+}
diff --git a/pkg/frontend_server/bin/frontend_server_starter.dart b/pkg/frontend_server/bin/frontend_server_starter.dart
index fedda20..2113752 100644
--- a/pkg/frontend_server/bin/frontend_server_starter.dart
+++ b/pkg/frontend_server/bin/frontend_server_starter.dart
@@ -6,7 +6,7 @@
import '../lib/frontend_server.dart';
Future<Null> main(List<String> args) async {
- final int exitCode = await starter(args);
+ exitCode = await starter(args);
if (exitCode != 0) {
exit(exitCode);
}
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 80d72c3..add6b9a 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -19,13 +19,12 @@
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions, parseExperimentalFlags;
import 'package:front_end/src/api_unstable/vm.dart';
-import 'package:kernel/ast.dart';
+import 'package:kernel/ast.dart' show Library, Procedure, LibraryDependency;
import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/binary/limited_ast_to_binary.dart';
import 'package:kernel/kernel.dart'
show Component, loadComponentSourceFromBytes;
import 'package:kernel/target/targets.dart' show targets, TargetFlags;
-import 'package:package_resolver/package_resolver.dart';
+import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as path;
import 'package:usage/uuid/uuid.dart';
@@ -161,7 +160,9 @@
help: 'Name of the subdirectory of //data for output files')
..addOption('far-manifest', help: 'Path to output Fuchsia package manifest')
..addOption('libraries-spec',
- help: 'A path or uri to the libraries specification JSON file');
+ help: 'A path or uri to the libraries specification JSON file')
+ ..addFlag('debugger-module-names',
+ help: 'Use debugger-friendly modules names', defaultsTo: false);
String usage = '''
Usage: server [options] [input.dart]
@@ -298,8 +299,7 @@
class BinaryPrinterFactory {
/// Creates new [BinaryPrinter] to write to [targetSink].
BinaryPrinter newBinaryPrinter(Sink<List<int>> targetSink) {
- return LimitedBinaryPrinter(targetSink, (_) => true /* predicate */,
- false /* excludeUriToSource */);
+ return BinaryPrinter(targetSink);
}
}
@@ -308,7 +308,8 @@
{this.printerFactory,
this.transformer,
this.unsafePackageSerialization,
- this.incrementalSerialization: true}) {
+ this.incrementalSerialization: true,
+ this.useDebuggerModuleNames: false}) {
_outputStream ??= stdout;
printerFactory ??= new BinaryPrinterFactory();
}
@@ -317,6 +318,7 @@
BinaryPrinterFactory printerFactory;
bool unsafePackageSerialization;
bool incrementalSerialization;
+ bool useDebuggerModuleNames;
CompilerOptions _compilerOptions;
BytecodeOptions _bytecodeOptions;
@@ -457,7 +459,7 @@
final String importDill = options['import-dill'];
if (importDill != null) {
- compilerOptions.inputSummaries = <Uri>[
+ compilerOptions.additionalDills = <Uri>[
Uri.base.resolveUri(Uri.file(importDill))
];
}
@@ -494,11 +496,12 @@
incrementalSerializer = _generator.incrementalSerializer;
_component = component;
+ _component.computeCanonicalNames();
} else {
if (options['link-platform']) {
// TODO(aam): Remove linkedDependencies once platform is directly embedded
// into VM snapshot and http://dartbug.com/30111 is fixed.
- compilerOptions.linkedDependencies = <Uri>[
+ compilerOptions.additionalDills = <Uri>[
sdkRoot.resolve(platformKernelDill)
];
}
@@ -589,8 +592,8 @@
/// Write a JavaScript bundle containg the provided component.
Future<void> writeJavascriptBundle(KernelCompilationResults results,
String filename, String fileSystemScheme) async {
- var packageResolver = await PackageResolver.loadConfig(
- _compilerOptions.packagesFileUri ?? '.packages');
+ var packageConfig = await loadPackageConfigUri(
+ _compilerOptions.packagesFileUri ?? File('.packages').absolute.uri);
final Component component = results.component;
// Compute strongly connected components.
final strongComponents = StrongComponents(component,
@@ -605,7 +608,8 @@
sourceFile.parent.createSync(recursive: true);
}
_bundler = JavaScriptBundler(
- component, strongComponents, fileSystemScheme, packageResolver);
+ component, strongComponents, fileSystemScheme, packageConfig,
+ useDebuggerModuleNames: useDebuggerModuleNames);
final sourceFileSink = sourceFile.openWrite();
final manifestFileSink = manifestFile.openWrite();
final sourceMapsFileSink = sourceMapsFile.openWrite();
@@ -670,10 +674,9 @@
final IOSink sink = file.openWrite();
final Set<Library> loadedLibraries = results.loadedLibraries;
final BinaryPrinter printer = filterExternal
- ? LimitedBinaryPrinter(
- sink,
- (lib) => !loadedLibraries.contains(lib),
- true /* excludeUriToSource */)
+ ? BinaryPrinter(sink,
+ libraryFilter: (lib) => !loadedLibraries.contains(lib),
+ includeSources: false)
: printerFactory.newBinaryPrinter(sink);
sortComponent(component);
@@ -686,8 +689,9 @@
final IOSink sink = File(filename).openWrite();
final Set<Library> loadedLibraries = results.loadedLibraries;
final BinaryPrinter printer = filterExternal
- ? LimitedBinaryPrinter(sink, (lib) => !loadedLibraries.contains(lib),
- true /* excludeUriToSource */)
+ ? BinaryPrinter(sink,
+ libraryFilter: (lib) => !loadedLibraries.contains(lib),
+ includeSources: false)
: printerFactory.newBinaryPrinter(sink);
sortComponent(component);
@@ -814,10 +818,9 @@
}
final byteSink = ByteSink();
- final BinaryPrinter printer = LimitedBinaryPrinter(
- byteSink,
- (lib) => packageFor(lib, result.loadedLibraries) == package,
- false /* excludeUriToSource */);
+ final BinaryPrinter printer = BinaryPrinter(byteSink,
+ libraryFilter: (lib) =>
+ packageFor(lib, result.loadedLibraries) == package);
printer.writeComponentFile(partComponent);
final bytes = byteSink.builder.takeBytes();
@@ -907,6 +910,11 @@
if (_bundler != null) {
var kernel2jsCompiler = _bundler.compilers[moduleName];
+ if (kernel2jsCompiler == null) {
+ throw Exception('Cannot find kernel2js compiler for $moduleName. '
+ 'Compilers are avaiable for modules: '
+ '\n\t${_bundler.compilers.keys.toString()}');
+ }
assert(kernel2jsCompiler != null);
var evaluator = new ExpressionCompiler(
@@ -917,7 +925,7 @@
var procedure = await evaluator.compileExpressionToJs(libraryUri, line,
column, jsModules, jsFrameValues, moduleName, expression);
- var result = procedure ?? errors[0];
+ var result = errors.length > 0 ? errors[0] : procedure;
// TODO(annagrin): kernelBinaryFilename is too specific
// rename to _outputFileName?
@@ -1120,15 +1128,15 @@
/// Listens for the compilation commands on [input] stream.
/// This supports "interactive" recompilation mode of execution.
-void listenAndCompile(CompilerInterface compiler, Stream<List<int>> input,
- ArgResults options, Completer<int> completer,
+StreamSubscription<String> listenAndCompile(CompilerInterface compiler,
+ Stream<List<int>> input, ArgResults options, Completer<int> completer,
{IncrementalCompiler generator}) {
_State state = _State.READY_FOR_INSTRUCTION;
_CompileExpressionRequest compileExpressionRequest;
_CompileExpressionToJsRequest compileExpressionToJsRequest;
String boundaryKey;
String recompileEntryPoint;
- input
+ return input
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((String string) async {
@@ -1198,7 +1206,9 @@
} else if (string == 'reset') {
compiler.resetIncrementalCompiler();
} else if (string == 'quit') {
- completer.complete(0);
+ if (!completer.isCompleted) {
+ completer.complete(0);
+ }
}
break;
case _State.RECOMPILE_LIST:
@@ -1365,7 +1375,8 @@
compiler ??= FrontendCompiler(output,
printerFactory: binaryPrinterFactory,
unsafePackageSerialization: options["unsafe-package-serialization"],
- incrementalSerialization: options["incremental-serialization"]);
+ incrementalSerialization: options["incremental-serialization"],
+ useDebuggerModuleNames: options['debugger-module-names']);
if (options.rest.isNotEmpty) {
return await compiler.compile(options.rest[0], options,
@@ -1375,7 +1386,8 @@
}
Completer<int> completer = Completer<int>();
- listenAndCompile(compiler, input ?? stdin, options, completer,
+ var subscription = listenAndCompile(
+ compiler, input ?? stdin, options, completer,
generator: generator);
- return completer.future;
+ return completer.future..then((value) => subscription.cancel());
}
diff --git a/pkg/frontend_server/lib/src/expression_compiler.dart b/pkg/frontend_server/lib/src/expression_compiler.dart
index 6f81341..2902fc5 100644
--- a/pkg/frontend_server/lib/src/expression_compiler.dart
+++ b/pkg/frontend_server/lib/src/expression_compiler.dart
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:async';
+import 'dart:io';
import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
show DiagnosticMessage, DiagnosticMessageHandler;
@@ -232,7 +233,10 @@
void _log(String message) {
if (verbose) {
- print(message);
+ // writing to stdout breaks communication to
+ // frontend server, which is done on stdin/stdout,
+ // so we use stderr here instead
+ stderr.writeln(message);
}
}
@@ -250,14 +254,14 @@
///
/// Returns expression compiled to JavaScript or null on error.
/// Errors are reported using onDiagnostic function
- /// [moduleName] is of the form '/packages/hello_world_main.dart'
+ /// [moduleName] is of the form 'packages/hello_world_main.dart'
/// [jsFrameValues] is a map from js variable name to its primitive value
/// or another variable name, for example
/// { 'x': '1', 'y': 'y', 'o': 'null' }
/// [jsModules] is a map from variable name to the module name, where
/// variable name is the name originally used in JavaScript to contain the
/// module object, for example:
- /// { 'dart':'dart_sdk', 'main': '/packages/hello_world_main.dart' }
+ /// { 'dart':'dart_sdk', 'main': 'packages/hello_world_main.dart' }
Future<String> compileExpressionToJs(
String libraryUri,
int line,
@@ -270,8 +274,6 @@
_log('ExpressionCompiler: compiling: $expression in $moduleName');
- var moduleVariable = moduleName.split('/').last;
-
var dartScope = await _findScopeAt(Uri.parse(libraryUri), line, column);
if (dartScope == null) {
_log('ExpressionCompiler: scope not found at $libraryUri:$line:$column');
@@ -299,8 +301,8 @@
// 3. compile dart expression to JS
- var jsExpression = await _compileExpression(
- dartScope, jsModules, moduleVariable, expression);
+ var jsExpression =
+ await _compileExpression(dartScope, jsModules, moduleName, expression);
if (jsExpression == null) {
_log('ExpressionCompiler: failed to compile $expression, $jsExpression');
@@ -370,10 +372,13 @@
Future<Library> _getLibrary(Uri libraryUri) async {
return await _compiler.context.runInContext((_) async {
var builder = _compiler.userCode.loader.builders[libraryUri];
- var library =
- _compiler.userCode.loader.read(libraryUri, -1, accessor: builder);
+ if (builder != null) {
+ var library =
+ _compiler.userCode.loader.read(libraryUri, -1, accessor: builder);
- return library.library;
+ return library.library;
+ }
+ return null;
});
}
@@ -381,12 +386,12 @@
/// example:
/// let dart = require('dart_sdk').dart;
js_ast.Statement _createRequireModuleStatement(
- String moduleName, String moduleVariable) {
+ String moduleName, String moduleVariable, String fieldName) {
var variableName = moduleVariable.replaceFirst('.dart', '');
var rhs = js_ast.PropertyAccess.field(
js_ast.Call(js_ast.Identifier('require'),
[js_ast.LiteralExpression('\'$moduleName\'')]),
- '$variableName');
+ '$fieldName');
return rhs.toVariableDeclaration(js_ast.Identifier('$variableName'));
}
@@ -416,16 +421,18 @@
/// [scope] current dart scope information
/// [modules] map from module variable names to module names in JavaScript
/// code. For example,
- /// { 'dart':'dart_sdk', 'main': '/packages/hello_world_main.dart' }
+ /// { 'dart':'dart_sdk', 'main': 'packages/hello_world_main.dart' }
/// [currentModule] current js module name.
/// For example, in library package:hello_world/main.dart:
- /// '/packages/hello_world/main.dart'
+ /// 'packages/hello_world/main.dart'
/// [expression] expression to compile in given [scope].
Future<String> _compileExpression(
DartScope scope,
Map<String, String> modules,
String currentModule,
String expression) async {
+ var currentModuleVariable = currentModule.split('/').last;
+
// 1. Compile expression to kernel AST
var procedure = await _compiler.compileExpression(
@@ -437,6 +444,10 @@
scope.cls?.name,
scope.procedure.isStatic);
+ // TODO(annagrin): The condition below seems to be always false.
+ // Errors are still correctly reported in the frontent_server,
+ // but we end up doing unnesessary work below.
+ // Add communication of error state from compiler here.
if (_compiler.context.errors.length > 0) {
return null;
}
@@ -468,18 +479,46 @@
var body = js_ast.Block([
// require dart, core, self and other modules
...modules.keys.map((String variable) {
- return _createRequireModuleStatement(modules[variable], variable);
+ var module = modules[variable];
+ _log('ExpressionCompiler: '
+ 'module: $module, '
+ 'variable: $variable, '
+ 'currentModule: $currentModule');
+
+ return _createRequireModuleStatement(
+ module,
+ // Inside a module, the library variable compiler creates is the
+ // file name without extension (currentModuleVariable).
+ //
+ // Inside a non-package module, the statement we need to produce
+ // to reload the library is
+ // 'main = require('web/main.dart').web__main'
+ //
+ // This is the only special case where currentModuleVariable
+ // ('main') is different from variable and field ('web_name')
+ //
+ // In all other cases, the variable, currentModuleVariable and
+ // the field are the same:
+ // 'library = require('packages/_test/library.dart').library'
+ //
+ // TODO(annagrin): save metadata decribing the variables and fields
+ // to use during compilation and use this information here to make
+ // expression compilation resilient to name convention changes
+ // See [issue 891](https://github.com/dart-lang/webdev/issues/891)
+ module == currentModule ? currentModuleVariable : variable,
+ variable);
}),
// re-create private field accessors
...scope.privateFields
- .map((String v) => _createPrivateField(v, currentModule)),
- ...privateFields.map((String v) => _createPrivateField(v, currentModule)),
+ .map((String v) => _createPrivateField(v, currentModuleVariable)),
+ ...privateFields
+ .map((String v) => _createPrivateField(v, currentModuleVariable)),
// statements generated by the FE
...jsFun.body.statements
]);
var jsFunModified = js_ast.Fun(jsFun.params, body);
- _log('ExpressionCompiler: JS AST: ${jsFunModified.toString()}');
+ _log('ExpressionCompiler: JS AST: $jsFunModified');
// 4. print JS ast to string for evaluation
diff --git a/pkg/frontend_server/lib/src/javascript_bundle.dart b/pkg/frontend_server/lib/src/javascript_bundle.dart
index 84f0118..cedccc6 100644
--- a/pkg/frontend_server/lib/src/javascript_bundle.dart
+++ b/pkg/frontend_server/lib/src/javascript_bundle.dart
@@ -10,7 +10,7 @@
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:path/path.dart' as p;
-import 'package:package_resolver/package_resolver.dart';
+import 'package:package_config/package_config.dart';
import 'strong_components.dart';
/// Produce a special bundle format for compiled JavaScript.
@@ -24,11 +24,13 @@
/// only the updated libraries.
class JavaScriptBundler {
JavaScriptBundler(this._originalComponent, this._strongComponents,
- this._fileSystemScheme, this._packageResolver)
+ this._fileSystemScheme, this._packageConfig,
+ {this.useDebuggerModuleNames = false})
: compilers = <String, ProgramCompiler>{} {
_summaries = <Component>[];
_summaryUris = <Uri>[];
_moduleImportForSummary = <Uri, String>{};
+ _moduleImportNameForSummary = <Uri, String>{};
_uriToComponent = <Uri, Component>{};
for (Uri uri in _strongComponents.modules.keys) {
final List<Library> libraries = _strongComponents.modules[uri].toList();
@@ -39,7 +41,13 @@
);
_summaries.add(summaryComponent);
_summaryUris.add(uri);
- _moduleImportForSummary[uri] = '${urlForComponentUri(uri)}.lib.js';
+
+ var baseName = urlForComponentUri(uri);
+ _moduleImportForSummary[uri] = '$baseName.lib.js';
+ if (useDebuggerModuleNames) {
+ _moduleImportNameForSummary[uri] = makeDebuggerModuleName(baseName);
+ }
+
_uriToComponent[uri] = summaryComponent;
}
}
@@ -47,12 +55,14 @@
final StrongComponents _strongComponents;
final Component _originalComponent;
final String _fileSystemScheme;
- final PackageResolver _packageResolver;
+ final PackageConfig _packageConfig;
+ final bool useDebuggerModuleNames;
final Map<String, ProgramCompiler> compilers;
List<Component> _summaries;
List<Uri> _summaryUris;
Map<Uri, String> _moduleImportForSummary;
+ Map<Uri, String> _moduleImportNameForSummary;
Map<Uri, Component> _uriToComponent;
/// Compile each component into a single JavaScript module.
@@ -72,7 +82,10 @@
final summaryToModule = Map<Component, String>.identity();
for (var i = 0; i < _summaries.length; i++) {
var summary = _summaries[i];
- var moduleImport = _moduleImportForSummary[_summaryUris[i]];
+ var moduleImport = useDebuggerModuleNames
+ // debugger loads modules by modules names, not paths
+ ? _moduleImportNameForSummary[_summaryUris[i]]
+ : _moduleImportForSummary[_summaryUris[i]];
for (var l in summary.libraries) {
assert(!importToSummary.containsKey(l));
importToSummary[l] = summary;
@@ -95,10 +108,15 @@
final summaryComponent = _uriToComponent[moduleUri];
// module name to use in trackLibraries
- // use full path for tracking if module uri is not a package uri
- final String moduleName = moduleUri.scheme == 'package'
- ? '/packages/${moduleUri.path}'
- : moduleUri.path;
+ // use full path for tracking if module uri is not a package uri.
+ String moduleName = urlForComponentUri(moduleUri);
+ if (useDebuggerModuleNames) {
+ // Skip the leading '/' as module names are used to require
+ // modules using module paths mape in RequireJS, which treats
+ // names with leading '/' or '.js' extensions specially
+ // and tries to load them without mapping.
+ moduleName = makeDebuggerModuleName(moduleName);
+ }
var compiler = ProgramCompiler(
_originalComponent,
@@ -127,7 +145,7 @@
// make relative paths in the source map we get the absolute uri for
// the module and make them relative to that.
sourceMapBase =
- p.dirname((await _packageResolver.resolveUri(moduleUri)).path);
+ p.dirname((await _packageConfig.resolve(moduleUri)).path);
}
final code = jsProgramToCode(
jsModule,
@@ -160,3 +178,7 @@
String urlForComponentUri(Uri componentUri) => componentUri.scheme == 'package'
? '/packages/${componentUri.path}'
: componentUri.path;
+
+String makeDebuggerModuleName(String name) {
+ return name.startsWith('/') ? name.substring(1) : name;
+}
diff --git a/pkg/frontend_server/pubspec.yaml b/pkg/frontend_server/pubspec.yaml
index 0436be0..c14c3b8 100644
--- a/pkg/frontend_server/pubspec.yaml
+++ b/pkg/frontend_server/pubspec.yaml
@@ -13,7 +13,7 @@
front_end: ^0.1.6
kernel: ^0.3.6
args: ^1.4.4
- package_resolver: ^1.0.0
+ package_config: ^1.9.0
dev_dependencies:
test: any
diff --git a/pkg/frontend_server/test/frontend_server_test.dart b/pkg/frontend_server/test/frontend_server_test.dart
index 267a812..8e521f4 100644
--- a/pkg/frontend_server/test/frontend_server_test.dart
+++ b/pkg/frontend_server/test/frontend_server_test.dart
@@ -548,7 +548,7 @@
];
var library = 'package:hello/foo.dart';
- var module = '/packages/hello/foo.dart';
+ var module = 'packages/hello/foo.dart';
final StreamController<List<int>> streamController =
StreamController<List<int>>();
@@ -1470,7 +1470,7 @@
..writeAsStringSync("hello:${tempDir.uri}\n");
var library = 'package:hello/foo.dart';
- var module = '/packages/hello/foo.dart';
+ var module = 'packages/hello/foo.dart';
var dillFile = File('${tempDir.path}/foo.dart.dill');
var sourceFile = File('${dillFile.path}.sources');
@@ -1486,6 +1486,7 @@
'--output-dill=${dillFile.path}',
'--target=dartdevc',
'--packages=${tempDir.path}/.packages',
+ '--debugger-module-names'
];
final StreamController<List<int>> streamController =
@@ -1577,7 +1578,7 @@
..writeAsStringSync("hello:${tempDir.uri}\n");
var library = 'package:hello/foo.dart';
- var module = '/packages/hello/foo.dart';
+ var module = 'packages/hello/foo.dart';
var dillFile = File('${tempDir.path}/foo.dart.dill');
var sourceFile = File('${dillFile.path}.sources');
@@ -1593,6 +1594,7 @@
'--output-dill=${dillFile.path}',
'--target=dartdevc',
'--packages=${tempDir.path}/.packages',
+ '--debugger-module-names'
];
final StreamController<List<int>> streamController =
diff --git a/pkg/frontend_server/test/src/expression_compiler_test.dart b/pkg/frontend_server/test/src/expression_compiler_test.dart
index fd4cb68..4528537 100644
--- a/pkg/frontend_server/test/src/expression_compiler_test.dart
+++ b/pkg/frontend_server/test/src/expression_compiler_test.dart
@@ -137,7 +137,8 @@
// create expression compiler
var evaluator = new ExpressionCompiler(
compiler, kernel2jsCompiler, component,
- verbose: false, onDiagnostic: setup.options.onDiagnostic);
+ verbose: setup.options.verbose,
+ onDiagnostic: setup.options.onDiagnostic);
// collect all module names and paths
Map<Uri, Module> moduleInfo = _collectModules(component);
@@ -164,9 +165,6 @@
return TestCompilationResult(jsExpression, false);
}
- // use to generate expected test results
- //print("\njsExpression: ${jsExpression}");
-
return TestCompilationResult(jsExpression, true);
}
diff --git a/pkg/frontend_server/test/src/javascript_bundle_test.dart b/pkg/frontend_server/test/src/javascript_bundle_test.dart
index e410461..c24aa9e 100644
--- a/pkg/frontend_server/test/src/javascript_bundle_test.dart
+++ b/pkg/frontend_server/test/src/javascript_bundle_test.dart
@@ -10,7 +10,7 @@
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
-import 'package:package_resolver/package_resolver.dart';
+import 'package:package_config/package_config.dart';
import 'package:test/test.dart';
/// Additional indexed types required by the dev_compiler's NativeTypeSet.
@@ -73,7 +73,16 @@
]),
];
- final packageResolver = PackageResolver.config({'a': Uri.file('/pkg/a')});
+ final packageConfig = PackageConfig.parseJson({
+ 'configVersion': 2,
+ 'packages': [
+ {
+ 'name': 'a',
+ 'rootUri': 'file:///pkg/a',
+ 'packagesUri': '',
+ }
+ ],
+ }, Uri.base);
final multiRootScheme = 'org-dartlang-app';
test('compiles JavaScript code', () async {
@@ -90,7 +99,7 @@
StrongComponents(testComponent, {}, Uri.file('/c.dart'));
strongComponents.computeModules();
final javaScriptBundler = JavaScriptBundler(
- testComponent, strongComponents, multiRootScheme, packageResolver);
+ testComponent, strongComponents, multiRootScheme, packageConfig);
final manifestSink = _MemorySink();
final codeSink = _MemorySink();
final sourcemapSink = _MemorySink();
@@ -116,7 +125,7 @@
test('converts package: uris into /packages/ uris', () async {
var importUri = Uri.parse('package:a/a.dart');
- var fileUri = await packageResolver.resolveUri(importUri);
+ var fileUri = await packageConfig.resolve(importUri);
final library = Library(
importUri,
fileUri: fileUri,
@@ -130,7 +139,7 @@
final strongComponents = StrongComponents(testComponent, {}, fileUri);
strongComponents.computeModules();
final javaScriptBundler = JavaScriptBundler(
- testComponent, strongComponents, multiRootScheme, packageResolver);
+ testComponent, strongComponents, multiRootScheme, packageConfig);
final manifestSink = _MemorySink();
final codeSink = _MemorySink();
final sourcemapSink = _MemorySink();
@@ -170,7 +179,7 @@
final strongComponents = StrongComponents(testComponent, {}, fileUri);
strongComponents.computeModules();
final javaScriptBundler = JavaScriptBundler(
- testComponent, strongComponents, multiRootScheme, packageResolver);
+ testComponent, strongComponents, multiRootScheme, packageConfig);
final manifestSink = _MemorySink();
final codeSink = _MemorySink();
final sourcemapSink = _MemorySink();
@@ -219,7 +228,7 @@
StrongComponents(testComponent, {}, Uri.file('/a.dart'));
strongComponents.computeModules();
final javaScriptBundler = JavaScriptBundler(
- testComponent, strongComponents, multiRootScheme, packageResolver);
+ testComponent, strongComponents, multiRootScheme, packageConfig);
final manifestSink = _MemorySink();
final codeSink = _MemorySink();
final sourcemapSink = _MemorySink();
diff --git a/pkg/kernel/bin/split.dart b/pkg/kernel/bin/split.dart
index d3abed4..e3c99e8 100755
--- a/pkg/kernel/bin/split.dart
+++ b/pkg/kernel/bin/split.dart
@@ -8,7 +8,6 @@
import 'package:kernel/ast.dart';
import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/binary/limited_ast_to_binary.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/src/tool/command_line_util.dart';
@@ -45,7 +44,7 @@
IOSink sink = output.openWrite();
try {
BinaryPrinter printer =
- new LimitedBinaryPrinter(sink, (lib) => lib == wantedLibrary, false);
+ new BinaryPrinter(sink, libraryFilter: (lib) => lib == wantedLibrary);
printer.writeComponentFile(component);
} finally {
await sink.close();
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index aa2408c..92e1b4c 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -73,6 +73,8 @@
import 'canonical_name.dart' show CanonicalName;
export 'canonical_name.dart' show CanonicalName;
+import 'default_language_version.dart';
+
import 'transformations/flags.dart';
import 'text/ast_to_text.dart';
import 'core_types.dart';
@@ -329,10 +331,6 @@
/// The URI of the source file this library was loaded from.
Uri fileUri;
- // TODO(jensj): Do we have a better option than this?
- static int defaultLanguageVersionMajor = 2;
- static int defaultLanguageVersionMinor = 8;
-
int _languageVersionMajor;
int _languageVersionMinor;
int get languageVersionMajor =>
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 190429c..dbdee4d 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -37,8 +37,9 @@
final BytesSink _constantsBytesSink;
BufferedSink _constantsSink;
BufferedSink _sink;
- bool includeSources;
- bool includeOffsets;
+ final bool includeSources;
+ final bool includeOffsets;
+ final LibraryFilter libraryFilter;
List<int> libraryOffsets;
List<int> classOffsets;
@@ -52,7 +53,6 @@
List<CanonicalName> _canonicalNameList;
Set<CanonicalName> _knownCanonicalNameNonRootTops = new Set<CanonicalName>();
- Set<CanonicalName> _reindexedCanonicalNames = new Set<CanonicalName>();
Library _currentLibrary;
@@ -61,7 +61,8 @@
/// The BinaryPrinter will use its own buffer, so the [sink] does not need
/// one.
BinaryPrinter(Sink<List<int>> sink,
- {StringIndexer stringIndexer,
+ {this.libraryFilter,
+ StringIndexer stringIndexer,
this.includeSources = true,
this.includeOffsets = true})
: _mainSink = new BufferedSink(sink),
@@ -504,9 +505,10 @@
_canonicalNameList = <CanonicalName>[];
for (int i = 0; i < component.libraries.length; ++i) {
Library library = component.libraries[i];
- if (!shouldWriteLibraryCanonicalNames(library)) continue;
- _indexLinkTableInternal(library.canonicalName);
- _knownCanonicalNameNonRootTops.add(library.canonicalName);
+ if (libraryFilter == null || libraryFilter(library)) {
+ _indexLinkTableInternal(library.canonicalName);
+ _knownCanonicalNameNonRootTops.add(library.canonicalName);
+ }
}
}
@@ -523,15 +525,14 @@
/// Compute canonical names for the whole component or parts of it.
void computeCanonicalNames(Component component) {
- component.computeCanonicalNames();
+ for (int i = 0; i < component.libraries.length; ++i) {
+ Library library = component.libraries[i];
+ if (libraryFilter == null || libraryFilter(library)) {
+ component.computeCanonicalNamesForLibrary(library);
+ }
+ }
}
- /// Return `true` if all canonical names of the [library] should be written
- /// into the link table. If some libraries of the component are skipped,
- /// then all the additional names referenced by the libraries that are written
- /// by [writeLibraries] are automatically added.
- bool shouldWriteLibraryCanonicalNames(Library library) => true;
-
void writeCanonicalNameEntry(CanonicalName node) {
CanonicalName parent = node.parent;
if (parent.isRoot) {
@@ -565,7 +566,16 @@
_writeMetadataSection(component);
writeStringTable(stringIndexer);
writeConstantTable(_constantIndexer);
- writeComponentIndex(component, component.libraries);
+ List<Library> libraries = component.libraries;
+ if (libraryFilter != null) {
+ List<Library> librariesNew = new List<Library>();
+ for (int i = 0; i < libraries.length; i++) {
+ Library library = libraries[i];
+ if (libraryFilter(library)) librariesNew.add(library);
+ }
+ libraries = librariesNew;
+ }
+ writeComponentIndex(component, libraries);
_flush();
});
@@ -703,7 +713,10 @@
/// Write all of some of the libraries of the [component].
void writeLibraries(Component component) {
for (int i = 0; i < component.libraries.length; ++i) {
- writeLibraryNode(component.libraries[i]);
+ Library library = component.libraries[i];
+ if (libraryFilter == null || libraryFilter(library)) {
+ writeLibraryNode(library);
+ }
}
}
@@ -862,35 +875,16 @@
void checkCanonicalName(CanonicalName node) {
if (_knownCanonicalNameNonRootTops.contains(node.nonRootTop)) return;
if (node == null || node.isRoot) return;
- bool indexCheckContains;
- {
- if (node.index < 0) {
- indexCheckContains = false;
- } else if (node.index >= _canonicalNameList.length) {
- indexCheckContains = false;
- } else {
- CanonicalName claim = _canonicalNameList[node.index];
- if (node != claim) {
- indexCheckContains = false;
- } else {
- indexCheckContains = true;
- }
+ if (node.index >= 0 && node.index < _canonicalNameList.length) {
+ CanonicalName claim = _canonicalNameList[node.index];
+ if (node == claim) {
+ // Already has the claimed index.
+ return;
}
}
-
- bool setContains = _reindexedCanonicalNames.contains(node);
- if (setContains != indexCheckContains) {
- throw "Unexpected difference between set and index";
- }
-
- if (_reindexedCanonicalNames.contains(node)) {
- return;
- }
-
checkCanonicalName(node.parent);
node.index = _canonicalNameList.length;
_canonicalNameList.add(node);
- _reindexedCanonicalNames.add(node);
}
void writeNullAllowedCanonicalNameReference(CanonicalName name) {
diff --git a/pkg/kernel/lib/binary/limited_ast_to_binary.dart b/pkg/kernel/lib/binary/limited_ast_to_binary.dart
deleted file mode 100644
index 6f5208e..0000000
--- a/pkg/kernel/lib/binary/limited_ast_to_binary.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2017, 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.
-
-import 'package:kernel/ast.dart';
-import 'package:kernel/binary/ast_to_binary.dart';
-
-/// Writes libraries that satisfy the [predicate].
-///
-/// Only the referenced subset of canonical names is indexed and written,
-/// so we don't waste time indexing all libraries of a component, when only
-/// a tiny subset is used.
-class LimitedBinaryPrinter extends BinaryPrinter {
- final LibraryFilter predicate;
-
- LimitedBinaryPrinter(
- Sink<List<int>> sink, this.predicate, bool excludeUriToSource,
- {bool includeOffsets = true})
- : super(sink,
- includeSources: !excludeUriToSource,
- includeOffsets: includeOffsets);
-
- @override
- void computeCanonicalNames(Component component) {
- for (var library in component.libraries) {
- if (predicate(library)) {
- component.root
- .getChildFromUri(library.importUri)
- .bindTo(library.reference);
- library.computeCanonicalNames();
- }
- }
- }
-
- @override
- bool shouldWriteLibraryCanonicalNames(Library library) {
- return predicate(library);
- }
-
- void writeLibraries(Component component) {
- for (int i = 0; i < component.libraries.length; ++i) {
- Library library = component.libraries[i];
- if (predicate(library)) writeLibraryNode(library);
- }
- }
-
- @override
- void writeNode(Node node) {
- if (node is Library) {
- throw "Internal error: writeNode should not see a Library.";
- }
- super.writeNode(node);
- }
-
- @override
- void writeComponentIndex(Component component, List<Library> libraries) {
- var librariesToWrite = libraries.where(predicate).toList();
- super.writeComponentIndex(component, librariesToWrite);
- }
-}
diff --git a/pkg/kernel/lib/default_language_version.dart b/pkg/kernel/lib/default_language_version.dart
new file mode 100644
index 0000000..73670a5
--- /dev/null
+++ b/pkg/kernel/lib/default_language_version.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, 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.
+
+// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
+//
+// Instead modify 'tools/experimental_features.yaml' and run
+// 'pkg/front_end/tool/fasta generate-experimental-flags' to update.
+
+int defaultLanguageVersionMajor = 2;
+int defaultLanguageVersionMinor = 8;
diff --git a/pkg/kernel/lib/src/norm.dart b/pkg/kernel/lib/src/norm.dart
index 5c161a9..c434b90 100644
--- a/pkg/kernel/lib/src/norm.dart
+++ b/pkg/kernel/lib/src/norm.dart
@@ -13,6 +13,7 @@
return type.accept(new _Norm(coreTypes)) ?? type;
}
+/// Returns normalization of [supertype].
Supertype normSupertype(CoreTypes coreTypes, Supertype supertype) {
if (supertype.typeArguments.isEmpty) return supertype;
_Norm normVisitor = new _Norm(coreTypes);
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 0b9e21b..8c6a691 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -22,6 +22,32 @@
this.forceLateLoweringForTesting = false,
this.forceNoExplicitGetterCallsForTesting = false,
this.enableNullSafety = false});
+
+ bool operator ==(other) {
+ if (other is! TargetFlags) return false;
+ TargetFlags o = other;
+ if (trackWidgetCreation != o.trackWidgetCreation) return false;
+ if (forceLateLoweringForTesting != o.forceLateLoweringForTesting) {
+ return false;
+ }
+ if (forceNoExplicitGetterCallsForTesting !=
+ o.forceNoExplicitGetterCallsForTesting) {
+ return false;
+ }
+ if (enableNullSafety != o.enableNullSafety) return false;
+ return true;
+ }
+
+ int get hashCode {
+ int hash = 485786;
+ hash = 0x3fffffff & (hash * 31 + (hash ^ trackWidgetCreation.hashCode));
+ hash = 0x3fffffff &
+ (hash * 31 + (hash ^ forceLateLoweringForTesting.hashCode));
+ hash = 0x3fffffff &
+ (hash * 31 + (hash ^ forceNoExplicitGetterCallsForTesting.hashCode));
+ hash = 0x3fffffff & (hash * 31 + (hash ^ enableNullSafety.hashCode));
+ return hash;
+ }
}
typedef Target _TargetBuilder(TargetFlags flags);
@@ -87,6 +113,7 @@
/// A target provides backend-specific options for generating kernel IR.
abstract class Target {
+ TargetFlags get flags;
String get name;
/// A list of URIs of required libraries, not including dart:core.
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
index 88188f5..9d5b372 100644
--- a/pkg/kernel/lib/transformations/async.dart
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -116,17 +116,22 @@
}
// Name an expression by emitting an assignment to a temporary variable.
- VariableGet name(Expression expr) {
+ Expression name(Expression expr) {
+ // Allocate as dynamic as temps might be reused with different types.
VariableDeclaration temp =
- allocateTemporary(nameIndex, expr.getStaticType(_staticTypeContext));
- statements.add(new ExpressionStatement(new VariableSet(temp, expr)));
- return new VariableGet(temp);
+ allocateTemporary(nameIndex, const DynamicType());
+ statements.add(ExpressionStatement(VariableSet(temp, expr)));
+ // Type annotate the get via an unsafe cast since all temps are allocated
+ // as dynamic.
+ DartType type = expr.getStaticType(_staticTypeContext);
+ return StaticInvocation(continuationRewriter.helper.unsafeCast,
+ Arguments(<Expression>[VariableGet(temp)], types: <DartType>[type]));
}
- VariableDeclaration allocateTemporary(int index, DartType type) {
+ VariableDeclaration allocateTemporary(int index,
+ [DartType type = const DynamicType()]) {
for (var i = variables.length; i <= index; i++) {
- variables
- .add(new VariableDeclaration(":async_temporary_${i}", type: type));
+ variables.add(VariableDeclaration(":async_temporary_${i}", type: type));
}
return variables[index];
}
@@ -159,11 +164,12 @@
// Getting a final or const variable is not an effect so it can be evaluated
// after an await to its right.
TreeNode visitVariableGet(VariableGet expr) {
+ Expression result = expr;
if (seenAwait && !expr.variable.isFinal && !expr.variable.isConst) {
- expr = name(expr);
+ result = name(expr);
++nameIndex;
}
- return expr;
+ return result;
}
// Transform an expression given an action to transform the children. For
diff --git a/pkg/nnbd_migration/bin/steamroll_ecosystem.dart b/pkg/nnbd_migration/bin/steamroll_ecosystem.dart
index 35a443d..341eca2 100644
--- a/pkg/nnbd_migration/bin/steamroll_ecosystem.dart
+++ b/pkg/nnbd_migration/bin/steamroll_ecosystem.dart
@@ -4,12 +4,13 @@
import 'dart:io';
+import 'package:args/args.dart';
+
/// This binary can generate and update an integrated workspace for upgrading
/// individual packages and their dependencies simultaneously.
import 'package:nnbd_migration/src/fantasyland/fantasy_workspace.dart';
import 'package:path/path.dart' as path;
-import 'package:args/args.dart';
final parser = ArgParser()
..addMultiOption('extra-packages', abbr: 'e', splitCommas: true)
@@ -25,18 +26,15 @@
defaultsTo: false,
negatable: true,
help:
- 'Use dartfix to force-update all dependencies (lib/ directory only).')
+ 'Use dart migrate to force-update all dependencies (lib/ directory only).')
..addFlag('force-migrate-package',
defaultsTo: false,
negatable: true,
- help: 'Use dartfix to force-update the base package (from root).')
+ help: 'Use dart migrate to force-update the base package (from root).')
..addFlag('force-migrate-extras',
defaultsTo: false,
negatable: true,
- help: 'Use dartfix to force-update extra packages (from root).')
- ..addOption('sdk',
- help:
- 'Use the given path to a NNBD-compliant sdk. Required for any --force options.')
+ help: 'Use dart migrate to force-update extra packages (from root).')
..addOption('analyze-results',
defaultsTo: 'full',
allowed: ['full', 'none', 'all'],
@@ -106,15 +104,11 @@
(s) => s.name != packageName && !extraPackages.contains(s.name)));
}
- if (results['sdk'] as String == null) {
- _showHelp('error: --sdk required with force-migrate options');
- exit(1);
- }
- if (!await workspace.forceMigratePackages(upgradedSubPackages,
- upgradedSubPackagesLibOnly, results['sdk'] as String, [
+ if (!await workspace
+ .forceMigratePackages(upgradedSubPackages, upgradedSubPackagesLibOnly, [
Platform.resolvedExecutable,
path.normalize(path.join(Platform.script.toFilePath(), '..', '..', '..',
- 'dartfix', 'bin', 'dartfix.dart'))
+ 'dartdev', 'bin', 'dartdev.dart'))
])) {
stderr.writeln('//// Everything already upgraded.');
}
@@ -137,8 +131,7 @@
if (results['analyze-results'] == 'all') {
subPackagesLibOnly = upgradedSubPackagesLibOnly;
}
- await workspace.analyzePackages(
- subPackages, subPackagesLibOnly, results['sdk'] as String, [
+ await workspace.analyzePackages(subPackages, subPackagesLibOnly, [
Platform.resolvedExecutable,
path.normalize(path.join(Platform.script.toFilePath(), '..', '..', '..',
'analyzer_cli', 'bin', 'analyzer.dart'))
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 594be67..820e4bf 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -8,6 +8,42 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:nnbd_migration/src/edit_plan.dart';
+/// Data structure used by the nullability migration engine to refer to a
+/// specific location in source code.
+class CodeReference {
+ final String path;
+
+ final int line;
+
+ final int column;
+
+ /// Name of the enclosing function, or `null` if not known.
+ String function;
+
+ CodeReference(this.path, this.line, this.column, this.function);
+
+ CodeReference.fromJson(dynamic json)
+ : path = json['path'] as String,
+ line = json['line'] as int,
+ column = json['col'] as int,
+ function = json['function'] as String;
+
+ Map<String, Object> toJson() {
+ return {
+ 'path': path,
+ 'line': line,
+ 'col': column,
+ if (function != null) 'function': function
+ };
+ }
+
+ @override
+ String toString() {
+ var pathAsUri = Uri.file(path);
+ return 'unknown ($pathAsUri:$line:$column)';
+ }
+}
+
/// Information exposed to the migration client about the set of nullability
/// nodes decorating a type in the program being migrated.
abstract class DecoratedTypeInfo {
@@ -267,6 +303,14 @@
/// The edges that caused this node to have the nullability that it has.
Iterable<EdgeInfo> get upstreamEdges;
+
+ PropagationStepInfo get whyNullable;
+}
+
+abstract class PropagationStepInfo {
+ CodeReference get codeReference;
+
+ PropagationStepInfo get principalCause;
}
/// Information exposed to the migration client about a node in the nullability
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index b7efcd9..bd2113c 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -63,7 +63,7 @@
'Changed a null-aware access into an ordinary access, because the target cannot be null',
kind: NullabilityFixKind.removeNullAwareness);
- /// A message used by dartfix to indicate a fix has been applied.
+ /// A message used to indicate a fix has been applied.
final String appliedMessage;
/// The kind of fix described.
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 9b55b96..48517ac 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -1593,6 +1593,9 @@
assert(_flowAnalysis != null);
}
try {
+ if (declaredElement is PromotableElement) {
+ _flowAnalysis.declare(declaredElement, initializer != null);
+ }
if (initializer == null) {
// For top level variables and static fields, we have to generate an
// implicit assignment of `null`. For instance fields, this is done
@@ -1606,9 +1609,6 @@
type.node, ImplicitNullInitializerOrigin(source, node));
}
} else {
- if (declaredElement is PromotableElement) {
- _flowAnalysis.initialize(declaredElement);
- }
var destinationType = getOrComputeElementType(declaredElement);
_handleAssignment(initializer, destinationType: destinationType);
}
@@ -1652,7 +1652,7 @@
void _addParametersToFlowAnalysis(FormalParameterList parameters) {
if (parameters != null) {
for (var parameter in parameters.parameters) {
- _flowAnalysis.initialize(parameter.declaredElement);
+ _flowAnalysis.declare(parameter.declaredElement, true);
}
}
}
@@ -1703,7 +1703,7 @@
_assignedVariables);
if (parameters != null) {
for (var parameter in parameters.parameters) {
- _flowAnalysis.initialize(parameter.declaredElement);
+ _flowAnalysis.declare(parameter.declaredElement, true);
}
}
}
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index e22e48b..f5ada49 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -6,7 +6,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:nnbd_migration/instrumentation.dart';
-import 'package:nnbd_migration/src/nullability_node.dart';
/// Edge origin resulting from a type in already-migrated code.
///
@@ -107,11 +106,32 @@
.thisOrAncestorOfType<CompilationUnit>()
.lineInfo
.getLocation(node.offset);
- return CodeReference(
- source.fullName, location.lineNumber, location.columnNumber);
+ return CodeReference(source.fullName, location.lineNumber,
+ location.columnNumber, _computeEnclosingName(node));
}
return null;
}
+
+ static String _computeEnclosingName(AstNode node) {
+ List<String> parts = [];
+ while (node != null) {
+ var nodeName = _computeNodeDeclarationName(node);
+ if (nodeName != null) {
+ parts.add(nodeName);
+ }
+ node = node.parent;
+ }
+ if (parts.isEmpty) return null;
+ return parts.reversed.join('.');
+ }
+
+ static String _computeNodeDeclarationName(AstNode node) {
+ if (node is Declaration) {
+ return node.declaredElement?.name;
+ } else {
+ return null;
+ }
+ }
}
/// An edge origin used for edges that originated because of a reference to an
diff --git a/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace.dart b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace.dart
index e9aa2ae..87a39e7 100644
--- a/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace.dart
+++ b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace.dart
@@ -28,7 +28,6 @@
Future<void> analyzePackages(
Iterable<FantasySubPackage> subPackages,
Iterable<FantasySubPackage> subPackagesLibOnly,
- String sdkPath,
List<String> dartanalyzerExec);
/// Force-migrate these packages.
@@ -36,11 +35,8 @@
/// All [subPackages] must be part of this workspace. Returned future
/// completes when all [subPackages] have been migrated. Completes with
/// `true` if packages needed to be migrated, `false` if skipped.
- Future<bool> forceMigratePackages(
- Iterable<FantasySubPackage> subPackages,
- Iterable<FantasySubPackage> subPackagesLibOnly,
- String sdkPath,
- List<String> dartfixExec);
+ Future<bool> forceMigratePackages(Iterable<FantasySubPackage> subPackages,
+ Iterable<FantasySubPackage> subPackagesLibOnly, List<String> dartdevExec);
/// Rewrite the package_config.json and/or .packages for this package.
Future<void> rewritePackageConfigWith(FantasySubPackage subPackage);
diff --git a/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace_impl.dart b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace_impl.dart
index a760781..4888a3f 100644
--- a/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace_impl.dart
+++ b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace_impl.dart
@@ -13,9 +13,11 @@
import 'package:nnbd_migration/src/fantasyland/fantasy_workspace.dart';
import 'package:nnbd_migration/src/utilities/multi_future_tracker.dart';
import 'package:nnbd_migration/src/utilities/subprocess_launcher.dart';
+import 'package:path/path.dart' as path;
class FantasyWorkspaceError extends Error {
final String message;
+
FantasyWorkspaceError(this.message);
@override
@@ -35,7 +37,7 @@
Future<FantasyRepo> Function(FantasyRepoSettings, String, bool,
{FantasyRepoDependencies fantasyRepoDependencies})
buildGitRepoFrom,
- List<String> dartfixExec})
+ List<String> dartdevExec})
: resourceProvider =
resourceProvider ?? PhysicalResourceProvider.INSTANCE,
launcher = launcher ?? SubprocessLauncher('fantasy-workspace'),
@@ -67,16 +69,19 @@
Map<FantasySubPackageSettings, FantasySubPackage> subPackages = {};
File _packagesFile;
+
File get packagesFile => _packagesFile ??= _external.resourceProvider.getFile(
_external.resourceProvider.pathContext
.join(workspaceRootPath, '.packages'));
File _packageConfigJson;
+
File get packageConfigJson => _packageConfigJson ??=
_external.resourceProvider.getFile(_external.resourceProvider.pathContext
.join(workspaceRootPath, '.dart_tool', 'package_config.json'));
File _migratedPackagesFile;
+
// TODO(jcollins-g): Remove this hack once a good way of determining whether
// a package is already migrated is available. (and our front-end implements it)
File get migratedPackagesFile => _migratedPackagesFile ??=
@@ -84,6 +89,7 @@
.join(workspaceRootPath, '.steamroller_already_migrated'));
Set<String> _migratedPackagePaths;
+
Set<String> get migratedPackagePaths =>
_migratedPackagePaths ??= migratedPackagesFile.exists
? migratedPackagesFile.readAsStringSync().split('\n').toSet()
@@ -128,15 +134,14 @@
Future<bool> forceMigratePackages(
Iterable<FantasySubPackage> subPackages,
Iterable<FantasySubPackage> subPackagesLibOnly,
- String sdkPath,
- List<String> dartfixExec) async {
- String dartfix_bin = dartfixExec.first;
- List<String> args = dartfixExec.sublist(1);
+ List<String> dartdevExec) async {
+ String dartdevBin = dartdevExec.first;
+ List<String> args = dartdevExec.sublist(1);
args.addAll(
- ['upgrade', 'sdk', '--no-preview', '--force', '--sdk=$sdkPath']);
+ ['migrate', '--no-web-preview', '--apply-changes', '--ignore-errors']);
bool migrationNecessary = false;
// TODO(jcollins-g): consider using the package graph to break up and
- // parallelize dartfix runs
+ // parallelize dartdev migrate runs
for (FantasySubPackage subPackage in subPackages) {
if (!migratedPackagePaths.contains(subPackage.packageRoot.path)) {
args.add(subPackage.packageRoot.path);
@@ -151,7 +156,7 @@
}
if (migrationNecessary) {
await _external.launcher
- .runStreamed(dartfix_bin, args, instance: 'dartfix');
+ .runStreamed(dartdevBin, args, instance: 'dartdev');
}
// Update the file once we're sure it has completed successfully.
packagesMigrated(subPackages);
@@ -163,8 +168,9 @@
Future<void> analyzePackages(
Iterable<FantasySubPackage> subPackages,
Iterable<FantasySubPackage> subPackagesLibOnly,
- String sdkPath,
List<String> dartanalyzerExec) async {
+ var sdkPath = path.dirname(path.dirname(Platform.resolvedExecutable));
+
var analyzers = <Future>[];
String dartanalyzer_bin = dartanalyzerExec.first;
List<String> baseArgs = dartanalyzerExec.sublist(1);
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index 524691d..fe9bab5 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -10,33 +10,6 @@
import 'edge_origin.dart';
-/// Data structure used by the nullability migration engine to refer to a
-/// specific location in source code.
-class CodeReference {
- final String path;
-
- final int line;
-
- final int column;
-
- CodeReference(this.path, this.line, this.column);
-
- CodeReference.fromJson(dynamic json)
- : path = json['path'] as String,
- line = json['line'] as int,
- column = json['col'] as int;
-
- Map<String, Object> toJson() {
- return {'path': path, 'line': line, 'col': column};
- }
-
- @override
- String toString() {
- var pathAsUri = Uri.file(path);
- return 'unknown ($pathAsUri:$line:$column)';
- }
-}
-
/// Base class for steps that occur as part of downstream propagation, where the
/// nullability of a node is changed to a new state.
abstract class DownstreamPropagationStep extends PropagationStep {
@@ -992,6 +965,8 @@
NonNullIntent _nonNullIntent;
+ DownstreamPropagationStep _whyNullable;
+
NullabilityNodeMutable.fromJson(
dynamic json, NullabilityGraphDeserializer deserializer)
: _nullability = json['nullability'] == null
@@ -1021,9 +996,13 @@
NonNullIntent get nonNullIntent => _nonNullIntent;
@override
+ PropagationStepInfo get whyNullable => _whyNullable;
+
+ @override
void resetState() {
_nullability = Nullability.nonNullable;
_nonNullIntent = NonNullIntent.none;
+ _whyNullable = null;
}
@override
@@ -1052,7 +1031,7 @@
}
/// Class representing a step taken by the nullability propagation algorithm.
-abstract class PropagationStep {
+abstract class PropagationStep implements PropagationStepInfo {
PropagationStep();
factory PropagationStep.fromJson(
@@ -1278,6 +1257,9 @@
isNullable ? NonNullIntent.none : NonNullIntent.direct;
@override
+ PropagationStepInfo get whyNullable => null;
+
+ @override
String get _jsonKind => 'immutable';
@override
@@ -1534,6 +1516,7 @@
node._nullability = newState;
_postmortemFileWriter?.addPropagationStep(step);
if (!oldState.isNullable) {
+ node._whyNullable = step;
// Was not previously nullable, so we need to propagate.
for (var edge in node._downstreamEdges) {
_pendingDownstreamSteps
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index b40cac4..9296346 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/src/dart/error/hint_codes.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeSystemImpl;
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/edge_builder.dart';
@@ -2655,6 +2656,36 @@
assertNoUpstreamNullability(decoratedTypeAnnotation('double').node);
}
+ Future<void> test_edgeOrigin_call_from_function() async {
+ await analyze('''
+void f(int i) {}
+void g(int j) {
+ f(j);
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int i').node,
+ hard: true,
+ codeReference:
+ matchCodeRef(offset: findNode.simple('j);').offset, function: 'g'));
+ }
+
+ Future<void> test_edgeOrigin_call_from_method() async {
+ await analyze('''
+class C {
+ void f(int i) {}
+ void g(int j) {
+ f(j);
+ }
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int i').node,
+ hard: true,
+ codeReference: matchCodeRef(
+ offset: findNode.simple('j);').offset, function: 'C.g'));
+ }
+
Future<void> test_export_metadata() async {
await analyze('''
@deprecated
diff --git a/pkg/nnbd_migration/test/fantasyland/fantasy_workspace_test.dart b/pkg/nnbd_migration/test/fantasyland/fantasy_workspace_test.dart
index e60f7c5..ff3ae24 100644
--- a/pkg/nnbd_migration/test/fantasyland/fantasy_workspace_test.dart
+++ b/pkg/nnbd_migration/test/fantasyland/fantasy_workspace_test.dart
@@ -2,9 +2,12 @@
// 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.
+import 'dart:io';
+
import 'package:mockito/mockito.dart';
import 'package:nnbd_migration/src/fantasyland/fantasy_workspace.dart';
import 'package:nnbd_migration/src/fantasyland/fantasy_workspace_impl.dart';
+import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -33,19 +36,20 @@
workspaceDependencies: workspaceDependencies);
await testWorkspace.analyzePackages(
testWorkspace.subPackages.values.where((p) => p.name == 'test_package'),
- // We are forcing extra_package_1 to be treated as migrated with 'lib_only'
- // for the purpose of testing. This would not be the case in normal
- // steamroll_ecosystem.dart runs.
+ // We are forcing extra_package_1 to be treated as migrated with
+ // 'lib_only' for the purpose of testing. This would not be the case in
+ // normal steamroll_ecosystem.dart runs.
testWorkspace.subPackages.values
.where((p) => p.name == 'extra_package_1'),
- convertPath('/path/to/a/sdk'),
['dart', 'really_the_analyzer.dart']);
+
+ var sdkPath = path.dirname(path.dirname(Platform.resolvedExecutable));
verify(mockLauncher.runStreamed(
'dart',
[
'really_the_analyzer.dart',
'--enable-experiment=non-nullable',
- '--dart-sdk=${convertPath("/path/to/a/sdk")}',
+ '--dart-sdk=$sdkPath',
'.'
],
workingDirectory: convertPath('/fantasyland/_repo/test_package'),
@@ -56,7 +60,7 @@
[
'really_the_analyzer.dart',
'--enable-experiment=non-nullable',
- '--dart-sdk=${convertPath("/path/to/a/sdk")}',
+ '--dart-sdk=$sdkPath',
'lib'
],
workingDirectory: convertPath('/fantasyland/_repo/extra_package_1'),
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index f4f53ac..34716eb 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -12,6 +12,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:meta/meta.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/conditional_discard.dart';
import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
@@ -197,7 +198,10 @@
/// aren't already. In practice this means that the caller can pass in either
// /// a [NodeMatcher] or a [NullabilityNode].
NullabilityEdge assertEdge(Object source, Object destination,
- {@required bool hard, bool checkable = true, Object guards = isEmpty}) {
+ {@required bool hard,
+ bool checkable = true,
+ Object guards = isEmpty,
+ Object codeReference}) {
var edges = getEdges(source, destination);
if (edges.length == 0) {
fail('Expected edge $source -> $destination, found none');
@@ -208,6 +212,9 @@
expect(edge.isHard, hard);
expect(edge.isCheckable, checkable);
expect(edge.guards, guards);
+ if (codeReference != null) {
+ expect(edge.codeReference, codeReference);
+ }
return edge;
}
}
@@ -402,6 +409,17 @@
return variables.conditionalDiscard(findNode.collectionElement(text));
}
+ /// Returns a [Matcher] that matches a [CodeReference] pointing to the given
+ /// file [offset], with the given [function] name.
+ TypeMatcher<CodeReference> matchCodeRef(
+ {@required int offset, @required String function}) {
+ var location = testUnit.lineInfo.getLocation(offset);
+ return TypeMatcher<CodeReference>()
+ .having((cr) => cr.line, 'line', location.lineNumber)
+ .having((cr) => cr.column, 'column', location.columnNumber)
+ .having((cr) => cr.function, 'function', function);
+ }
+
NullabilityNode possiblyOptionalParameter(String text) {
return variables.possiblyOptionalParameter(findNode.defaultParameter(text));
}
diff --git a/pkg/nnbd_migration/test/nullability_node_test.dart b/pkg/nnbd_migration/test/nullability_node_test.dart
index 639b5a9..e674000 100644
--- a/pkg/nnbd_migration/test/nullability_node_test.dart
+++ b/pkg/nnbd_migration/test/nullability_node_test.dart
@@ -2,6 +2,7 @@
// 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.
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/edge_origin.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:test/test.dart';
diff --git a/pkg/nnbd_migration/tool/trial_migration.sh b/pkg/nnbd_migration/tool/trial_migration.sh
index a2e048f..4db1c2b 100755
--- a/pkg/nnbd_migration/tool/trial_migration.sh
+++ b/pkg/nnbd_migration/tool/trial_migration.sh
@@ -7,12 +7,12 @@
TRIAL_MIGRATION=`dirname "$0"`/trial_migration.dart
-# Priority One, Group One
+# Priority One, Group One, as defined at go/dart-null-safety-migration-order.
p1g1 () {
for n in charcode collection logging path pedantic term_glyph typed_data ; do
echo "-g https://dart.googlesource.com/${n}.git"
done
- # Some packages do not have googlesource mirrors, use github directly.
+ # Some packages do not have googlesource mirrors; use GitHub directly.
echo "-g https://github.com/google/vector_math.dart.git"
# SDK-only packages.
echo "-p meta"
diff --git a/pkg/nnbd_migration/tool/trial_migration_p2.sh b/pkg/nnbd_migration/tool/trial_migration_p2.sh
new file mode 100755
index 0000000..63fee78
--- /dev/null
+++ b/pkg/nnbd_migration/tool/trial_migration_p2.sh
@@ -0,0 +1,148 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2020, 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.
+#
+
+TRIAL_MIGRATION=`dirname "$0"`/trial_migration.dart
+
+# Priority Two, Group One, as defined at go/dart-null-safety-migration-order.
+p2g1 () {
+ echo "-g https://github.com/google/ansicolor-dart.git"
+ echo "-g https://dart.googlesource.com/args.git"
+ echo "-p dart_internal"
+ echo "-g https://dart.googlesource.com/fixnum.git"
+ echo "-g https://github.com/google/inject.dart.git"
+ echo "-p js"
+ echo "-g https://github.com/a14n/dart-js-wrapping.git"
+ echo "-g https://dart.googlesource.com/mime.git"
+ echo "-g https://github.com/xxgreg/mustache.git"
+ echo "-g https://github.com/leonsenft/path_to_regexp.git"
+ echo "-g https://github.com/petitparser/dart-petitparser.git"
+ echo "-g https://github.com/google/platform.dart.git"
+ echo "-g https://github.com/dart-lang/stream_transform.git"
+ echo "-g https://github.com/dart-lang/sync_http.git"
+ echo "-g https://github.com/srawlins/timezone.git"
+}
+
+# Priority Two, Group Two, as defined at go/dart-null-safety-migration-order.
+p2g2 () {
+ echo "-g https://github.com/google/ansicolor-dart.git"
+ echo "-g https://dart.googlesource.com/cli_util.git"
+ echo "-g https://github.com/dart-lang/clock.git"
+ echo "-g https://github.com/kevmoo/completion.dart.git"
+ echo "-g https://dart.googlesource.com/convert.git"
+ echo "-g https://github.com/a14n/dart-google-maps.git"
+ echo "-g https://github.com/dart-lang/http_server.git"
+ echo "-g https://dart.googlesource.com/intl.git"
+ echo "-p kernel"
+ echo "-g https://dart.googlesource.com/package_config.git"
+ # TODO(srawlins): Add protobuf, from monorepo
+ # https://github.com/dart-lang/protobuf.
+ echo "-g https://dart.googlesource.com/pub_semver.git"
+ echo "-g https://github.com/google/quiver-dart.git"
+}
+
+# Priority Two, Group Three, as defined at go/dart-null-safety-migration-order.
+p2g3 () {
+ # TODO(srawlins): Add android_intent, from monorepo
+ # https://github.com/flutter/plugins/tree/master/packages/android_intent.
+ # SDK-only packages.
+ echo "-g https://dart.googlesource.com/bazel_worker.git"
+ echo "-g https://github.com/google/built_collection.dart.git"
+ # TODO(srawlins): Add charts_common, from monorepo
+ # https://github.com/google/charts/tree/master/charts_common.
+ echo "-g https://github.com/jathak/cli_repl.git"
+ echo "-g https://dart.googlesource.com/crypto.git"
+ echo "-g https://dart.googlesource.com/csslib.git"
+ echo "-g https://github.com/google/file.dart.git"
+ # TODO(srawlins): Add front_end, which currently crashes.
+ echo "-g https://github.com/reyerstudio/google-maps-markerclusterer.git"
+ # TODO(srawlins): Add google_sign_in, from monorepo
+ # https://github.com/flutter/plugins/tree/master/packages/google_sign_in.
+ echo "-g https://dart.googlesource.com/http_multi_server.git"
+ echo "-g https://github.com/dart-lang/observable.git"
+ # TODO(srawlins): Add package_info, from monorepo
+ # https://github.com/flutter/plugins/tree/master/packages/package_info.
+ echo "-g https://dart.googlesource.com/pool.git"
+ # TODO(srawlins): Add protoc_plugin, from monorepo
+ # https://github.com/dart-lang/protobuf.
+ echo "-g https://github.com/google/quiver-log.git"
+ # TODO(srawlins): Add shared_preferences, from monorepo
+ # https://github.com/flutter/plugins/tree/master/packages/shared_preferences.
+ echo "-g https://dart.googlesource.com/source_maps.git"
+ echo "-g https://dart.googlesource.com/string_scanner.git"
+ echo "-g https://github.com/renggli/dart-xml.git"
+}
+
+# Priority Two, Group Four, as defined at go/dart-null-safety-migration-order.
+p2g4 () {
+ echo "-g https://github.com/brendan-duncan/archive.git"
+ # TODO(srawlins): Add built_value, from monorepo
+ # https://github.com/google/built_value.dart
+ # Not including charted; concern is internal copy; not old published copy.
+ echo "-g https://dart.googlesource.com/glob.git"
+ echo "-g https://dart.googlesource.com/html.git"
+ echo "-g https://dart.googlesource.com/http_parser.git"
+ echo "-g https://dart.googlesource.com/json_rpc_2.git"
+ # Not including observe; concern is internal copy; not old published copy.
+ echo "-g https://github.com/google/process.dart.git"
+ # Not including scissors; concern is internal copy; not old published copy.
+}
+
+# Priority Two, Group Five, as defined at go/dart-null-safety-migration-order.
+p2g5 () {
+ echo "-p analyzer"
+ # Not including angular_forms; concern is internal copy; not old published copy.
+ # Not including angular_router; concern is internal copy; not old published copy.
+ # Not including angular_test; concern is internal copy; not old published copy.
+ echo "-g https://github.com/dart-lang/code_builder.git"
+ echo "-g https://dart.googlesource.com/http.git"
+ echo "-g https://github.com/brendan-duncan/image.git"
+ echo "-g https://dart.googlesource.com/shelf.git"
+}
+
+# Priority Two, Group Six, as defined at go/dart-null-safety-migration-order.
+p2g6 () {
+ echo "-p analyzer_plugin"
+ # TODO(srawlins): Add build, from monorepo
+ # https://github.com/dart-lang/build/tree/master/build.
+ echo "-g https://github.com/dart-lang/coverage.git"
+ echo "-g https://dart.googlesource.com/dart_style.git"
+ # TODO(srawlins): Add flutter_test.
+ echo "-g https://github.com/dart-lang/googleapis_auth.git"
+ echo "-g https://github.com/dart-lang/intl_translation.git"
+ echo "-g https://dart.googlesource.com/mockito.git"
+ echo "-g https://dart.googlesource.com/package_resolver.git"
+ # Not including pageloader ("2"); concern is internal copy; not old published copy.
+ echo "-g https://dart.googlesource.com/shelf_static.git"
+ echo "-g https://dart.googlesource.com/shelf_web_socket.git"
+}
+
+# Priority Two, Group Seven, as defined at go/dart-null-safety-migration-order.
+p2g7 () {
+ echo "-g https://github.com/dart-lang/grpc-dart.git"
+ echo "-g https://github.com/google/pageloader.git" # This is pageloader3.
+ echo "-g https://github.com/sass/dart-sass.git"
+ echo "-g https://dart.googlesource.com/shelf_packages_handler.git"
+ echo "-g https://github.com/dart-lang/source_gen.git"
+ echo "-g https://dart.googlesource.com/source_map_stack_trace.git"
+}
+
+# Priority Two, Group Eight, as defined at go/dart-null-safety-migration-order.
+p2g8 () {
+ # Not including angular_compiler; concern is internal copy; not old published copy.
+ # TODO(srawlins): Add built_value_generator, from monorepo
+ # https://github.com/google/built_value.dart.
+ # TODO(srawlins): Add flutter_tools, from monorepo
+ # https://github.com/flutter/flutter.
+ # TODO(srawlins): Locate and add rpc_client.
+ echo ""
+}
+
+# The current "official" set of parameters for the trial_migration script.
+set -x
+dart --enable-asserts ${TRIAL_MIGRATION} \
+ $(p2g1) $(p2g2) $(p2g3) $(p2g4) $(p2g5) $(p2g6) $(p2g7) $(p2g8) \
+ "$@"
diff --git a/pkg/telemetry/lib/crash_reporting.dart b/pkg/telemetry/lib/crash_reporting.dart
index 6e44d8e..808c4ac 100644
--- a/pkg/telemetry/lib/crash_reporting.dart
+++ b/pkg/telemetry/lib/crash_reporting.dart
@@ -66,6 +66,7 @@
Future sendReport(
dynamic error,
StackTrace stackTrace, {
+ List<CrashReportAttachment> attachments = const [],
String comment,
}) async {
if (!shouldSend()) {
@@ -129,6 +130,15 @@
_stackTraceFileField, chain.terse.toString(),
filename: _stackTraceFilename));
+ for (var attachment in attachments) {
+ req.files.add(
+ new http.MultipartFile.fromString(
+ attachment._field,
+ attachment._value,
+ ),
+ );
+ }
+
final http.StreamedResponse resp = await _httpClient.send(req);
if (resp.statusCode != 200) {
@@ -152,6 +162,18 @@
}
}
+/// The additional attachment to be added to a crash report.
+class CrashReportAttachment {
+ final String _field;
+ final String _value;
+
+ CrashReportAttachment.string({
+ @required String field,
+ @required String value,
+ }) : _field = field,
+ _value = value;
+}
+
/// A typedef to allow crash reporting to query as to whether it should send a
/// crash report.
typedef bool EnablementCallback();
diff --git a/pkg/telemetry/test/crash_reporting_test.dart b/pkg/telemetry/test/crash_reporting_test.dart
index 9d48324..be93424 100644
--- a/pkg/telemetry/test/crash_reporting_test.dart
+++ b/pkg/telemetry/test/crash_reporting_test.dart
@@ -72,6 +72,27 @@
expect(body, contains('additional message'));
});
+ test('has attachments', () async {
+ CrashReportSender sender = new CrashReportSender(
+ analytics.trackingId, shouldSend,
+ httpClient: mockClient);
+
+ await sender.sendReport(
+ 'test-error',
+ StackTrace.current,
+ attachments: [
+ CrashReportAttachment.string(field: 'attachment-1', value: 'aaa'),
+ CrashReportAttachment.string(field: 'attachment-2', value: 'bbb'),
+ ],
+ );
+
+ String body = utf8.decode(request.bodyBytes);
+ expect(body, contains('attachment-1'));
+ expect(body, contains('aaa'));
+ expect(body, contains('attachment-2'));
+ expect(body, contains('bbb'));
+ });
+
test('has ptime', () async {
CrashReportSender sender = new CrashReportSender(
analytics.trackingId, shouldSend,
diff --git a/pkg/test_runner/bin/http_server.dart b/pkg/test_runner/bin/http_server.dart
index 881dd35..b034e72 100644
--- a/pkg/test_runner/bin/http_server.dart
+++ b/pkg/test_runner/bin/http_server.dart
@@ -20,7 +20,6 @@
parser.addFlag('help',
abbr: 'h', negatable: false, help: 'Print this usage information.');
parser.addOption('build-directory', help: 'The build directory to use.');
- parser.addOption('package-root', help: 'The package root to use.');
parser.addOption('packages', help: 'The package spec file to use.');
parser.addOption('network',
help: 'The network interface to use.', defaultsTo: '0.0.0.0');
@@ -38,7 +37,6 @@
args['csp'] as bool,
Runtime.find(args['runtime'] as String),
null,
- args['package-root'] as String,
args['packages'] as String);
var port = int.parse(args['port'] as String);
var crossOriginPort = int.parse(args['crossOriginPort'] as String);
diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart
index 63fc701..b5cf4ea 100644
--- a/pkg/test_runner/lib/src/configuration.dart
+++ b/pkg/test_runner/lib/src/configuration.dart
@@ -63,7 +63,6 @@
this.keepGeneratedFiles,
this.sharedOptions,
String packages,
- this.packageRoot,
this.suiteDirectory,
this.outputDirectory,
this.reproducingArguments,
@@ -170,15 +169,12 @@
String get packages {
// If the .packages file path wasn't given, find it.
- if (packageRoot == null && _packages == null) {
- _packages = Repository.uri.resolve('.packages').toFilePath();
- }
+ _packages ??= Repository.uri.resolve('.packages').toFilePath();
return _packages;
}
final String outputDirectory;
- final String packageRoot;
final String suiteDirectory;
String get babel => configuration.babel;
String get builderTag => configuration.builderTag;
@@ -431,8 +427,7 @@
/// server for cross-domain tests can be found by calling
/// `getCrossOriginPortNumber()`.
Future startServers() {
- _servers = TestingServers(
- buildDirectory, isCsp, runtime, null, packageRoot, packages);
+ _servers = TestingServers(buildDirectory, isCsp, runtime, null, packages);
var future = servers.startServers(localIP,
port: testServerPort, crossOriginPort: testServerCrossOriginPort);
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index eae5f49..757e362 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -747,7 +747,6 @@
localIP: data["local_ip"] as String,
sharedOptions: sharedOptions,
packages: data["packages"] as String,
- packageRoot: data["package_root"] as String,
suiteDirectory: data["suite_dir"] as String,
outputDirectory: data["output_directory"] as String,
reproducingArguments:
diff --git a/pkg/test_runner/lib/src/test_file.dart b/pkg/test_runner/lib/src/test_file.dart
index 11c1d4bf..74bb378 100644
--- a/pkg/test_runner/lib/src/test_file.dart
+++ b/pkg/test_runner/lib/src/test_file.dart
@@ -18,7 +18,6 @@
final _vmOptionsRegExp = RegExp(r"// VMOptions=(.*)");
final _environmentRegExp = RegExp(r"// Environment=(.*)");
-final _packageRootRegExp = RegExp(r"// PackageRoot=(.*)");
final _packagesRegExp = RegExp(r"// Packages=(.*)");
final _experimentRegExp = RegExp(r"^--enable-experiment=([a-z,-]+)$");
@@ -180,7 +179,6 @@
dart2jsOptions: [],
ddcOptions: [],
dartOptions: [],
- packageRoot: null,
packages: null,
hasSyntaxError: false,
hasCompileError: false,
@@ -259,34 +257,17 @@
}
// Packages.
- String packageRoot;
String packages;
- matches = _packageRootRegExp.allMatches(contents);
- for (var match in matches) {
- if (packageRoot != null || packages != null) {
- throw Exception('More than one "// Package... line in test $filePath');
- }
- packageRoot = match[1];
- if (packageRoot != 'none') {
- // PackageRoot=none means that no packages or package-root option
- // should be given. Any other value overrides package-root and
- // removes any packages option. Don't use with // Packages=.
- packageRoot = Uri.file(filePath)
- .resolveUri(Uri.directory(packageRoot))
- .toFilePath();
- }
- }
matches = _packagesRegExp.allMatches(contents);
for (var match in matches) {
- if (packages != null || packageRoot != null) {
+ if (packages != null) {
throw Exception('More than one "// Package..." line in test $filePath');
}
packages = match[1];
if (packages != 'none') {
- // Packages=none means that no packages or package-root option
- // should be given. Any other value overrides packages and removes
- // any package-root option. Don't use with // PackageRoot=.
+ // Packages=none means that no packages option should be given. Any
+ // other value overrides packages.
packages =
Uri.file(filePath).resolveUri(Uri.file(packages)).toFilePath();
}
@@ -338,7 +319,6 @@
}
return TestFile._(suiteDirectory, Path(filePath), errorExpectations,
- packageRoot: packageRoot,
packages: packages,
environment: environment,
isMultitest: isMultitest,
@@ -367,8 +347,7 @@
this.hasRuntimeError,
this.hasStaticWarning,
this.hasCrash})
- : packageRoot = null,
- packages = null,
+ : packages = null,
environment = null,
isMultitest = false,
isMultiHtmlTest = false,
@@ -385,8 +364,7 @@
super(null, null, []);
TestFile._(Path suiteDirectory, Path path, List<StaticError> expectedErrors,
- {this.packageRoot,
- this.packages,
+ {this.packages,
this.environment,
this.isMultitest,
this.isMultiHtmlTest,
@@ -413,7 +391,6 @@
String get multitestKey => "";
- final String packageRoot;
final String packages;
final Map<String, String> environment;
@@ -465,7 +442,6 @@
hasSyntaxError: hasSyntaxError ?? false);
String toString() => """TestFile(
- packageRoot: $packageRoot
packages: $packages
environment: $environment
isMultitest: $isMultitest
@@ -514,7 +490,6 @@
Path get originPath => _origin.path;
- String get packageRoot => _origin.packageRoot;
String get packages => _origin.packages;
List<Feature> get requirements => _origin.requirements;
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index 317a917..45c8d41 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -782,8 +782,7 @@
_createUrlPathFromFile(Path('$compilationTempDir/$nameNoExt.js'));
content = dart2jsHtml(testFile.path.toNativePath(), scriptPath);
} else {
- var packageRoot =
- packagesArgument(configuration.packageRoot, configuration.packages);
+ var packageRoot = packagesArgument(configuration.packages);
packageRoot =
packageRoot == null ? nameNoExt : packageRoot.split("=").last;
var nameFromModuleRoot =
@@ -860,7 +859,7 @@
List<String> _commonArgumentsFromFile(TestFile testFile) {
var args = configuration.standardOptions.toList();
- var packages = packagesArgument(testFile.packageRoot, testFile.packages);
+ var packages = packagesArgument(testFile.packages);
if (packages != null) {
args.add(packages);
}
@@ -880,25 +879,17 @@
return args;
}
- String packagesArgument(String packageRoot, String packages) {
+ String packagesArgument(String packages) {
// If this test is inside a package, we will check if there is a
// pubspec.yaml file and if so, create a custom package root for it.
- if (packageRoot == null && packages == null) {
- if (configuration.packageRoot != null) {
- packageRoot = Path(configuration.packageRoot).toNativePath();
- }
-
- if (configuration.packages != null) {
- packages = Path(configuration.packages).toNativePath();
- }
+ if (packages == null && configuration.packages != null) {
+ packages = Path(configuration.packages).toNativePath();
}
- if (packageRoot == 'none' || packages == 'none') {
+ if (packages == 'none') {
return null;
} else if (packages != null) {
return '--packages=$packages';
- } else if (packageRoot != null) {
- return '--package-root=$packageRoot';
} else {
return null;
}
diff --git a/pkg/test_runner/lib/src/testing_servers.dart b/pkg/test_runner/lib/src/testing_servers.dart
index faf3ece..f46956c 100644
--- a/pkg/test_runner/lib/src/testing_servers.dart
+++ b/pkg/test_runner/lib/src/testing_servers.dart
@@ -6,7 +6,7 @@
import 'dart:convert' show HtmlEscape;
import 'dart:io';
-import 'package:package_resolver/package_resolver.dart';
+import 'package:package_config/package_config.dart';
import 'package:test_runner/src/configuration.dart';
import 'package:test_runner/src/repository.dart';
@@ -74,35 +74,28 @@
];
final List<HttpServer> _serverList = [];
- Uri _buildDirectory;
- Uri _dartDirectory;
- Uri _packageRoot;
- Uri _packages;
+ final Uri _buildDirectory;
+ final Uri _dartDirectory;
+ final Uri _packages;
+ PackageConfig _packageConfig;
final bool useContentSecurityPolicy;
final Runtime runtime;
DispatchingServer _server;
- SyncPackageResolver _resolver;
- TestingServers(String buildDirectory, this.useContentSecurityPolicy,
- [this.runtime = Runtime.none,
- String dartDirectory,
- String packageRoot,
- String packages]) {
- _buildDirectory = Uri.base.resolveUri(Uri.directory(buildDirectory));
- if (dartDirectory == null) {
- _dartDirectory = Repository.uri;
- } else {
- _dartDirectory = Uri.base.resolveUri(Uri.directory(dartDirectory));
- }
- if (packageRoot == null) {
- if (packages == null) {
- _packages = _dartDirectory.resolve('.packages');
- } else {
- _packages = Uri.file(packages);
- }
- } else {
- _packageRoot = Uri.directory(packageRoot);
- }
+ TestingServers._(this.useContentSecurityPolicy, this._buildDirectory,
+ this._dartDirectory, this._packages, this.runtime);
+
+ factory TestingServers(String buildDirectory, bool useContentSecurityPolicy,
+ [Runtime runtime = Runtime.none, String dartDirectory, String packages]) {
+ var buildDirectoryUri = Uri.base.resolveUri(Uri.directory(buildDirectory));
+ var dartDirectoryUri = dartDirectory == null
+ ? Repository.uri
+ : Uri.base.resolveUri(Uri.directory(dartDirectory));
+ var packagesUri = packages == null
+ ? dartDirectoryUri.resolve('.packages')
+ : Uri.file(packages);
+ return TestingServers._(useContentSecurityPolicy, buildDirectoryUri,
+ dartDirectoryUri, packagesUri, runtime);
}
String get network => _serverList[0].address.address;
@@ -122,11 +115,8 @@
/// "Access-Control-Allow-Credentials: true"
Future startServers(String host,
{int port = 0, int crossOriginPort = 0}) async {
- if (_packages != null) {
- _resolver = await SyncPackageResolver.loadConfig(_packages);
- } else {
- _resolver = SyncPackageResolver.root(_packageRoot);
- }
+ _packageConfig = await loadPackageConfigUri(_packages);
+
_server = await _startHttpServer(host, port: port);
await _startHttpServer(host,
port: crossOriginPort, allowedPort: _serverList[0].port);
@@ -150,10 +140,7 @@
'--build-directory=$buildDirectory',
'--runtime=${runtime.name}',
if (useContentSecurityPolicy) '--csp',
- if (_packages != null)
- '--packages=${_packages.toFilePath()}'
- else if (_packageRoot != null)
- '--package-root=${_packageRoot.toFilePath()}'
+ '--packages=${_packages.toFilePath()}'
].join(' ');
}
@@ -260,7 +247,7 @@
var packageUri = Uri(
scheme: 'package',
pathSegments: pathSegments.skip(packagesIndex + 1));
- return _resolver.resolveUri(packageUri);
+ return _packageConfig.resolve(packageUri);
}
if (pathSegments[0] == prefixBuildDir) {
return _buildDirectory.resolve(pathSegments.skip(1).join('/'));
diff --git a/pkg/test_runner/pubspec.yaml b/pkg/test_runner/pubspec.yaml
index ac6729b..b927d5b 100644
--- a/pkg/test_runner/pubspec.yaml
+++ b/pkg/test_runner/pubspec.yaml
@@ -11,8 +11,8 @@
path: ../expect
glob:
path: ../../third_party/pkg/glob
- package_resolver:
- path: ../../third_party/pkg_tested/package_resolver
+ package_config:
+ path: ../../third_party/pkg_tested/package_config
smith:
path: ../smith
status_file:
diff --git a/pkg/vm/bin/dump_kernel.dart b/pkg/vm/bin/dump_kernel.dart
index 1cc4883..6419750 100644
--- a/pkg/vm/bin/dump_kernel.dart
+++ b/pkg/vm/bin/dump_kernel.dart
@@ -16,6 +16,8 @@
show ProcedureAttributesMetadataRepository;
import 'package:vm/metadata/table_selector.dart'
show TableSelectorMetadataRepository;
+import 'package:vm/metadata/unboxing_info.dart'
+ show UnboxingInfoMetadataRepository;
import 'package:vm/metadata/unreachable.dart'
show UnreachableNodeMetadataRepository;
import 'package:vm/metadata/call_site_attributes.dart'
@@ -42,6 +44,7 @@
component.addMetadataRepository(new InferredTypeMetadataRepository());
component.addMetadataRepository(new ProcedureAttributesMetadataRepository());
component.addMetadataRepository(new TableSelectorMetadataRepository());
+ component.addMetadataRepository(new UnboxingInfoMetadataRepository());
component.addMetadataRepository(new UnreachableNodeMetadataRepository());
component.addMetadataRepository(new BytecodeMetadataRepository());
component.addMetadataRepository(new CallSiteAttributesMetadataRepository());
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index fe0e4da..5cd0297 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -33,6 +33,8 @@
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/api_unstable/vm.dart';
import 'package:kernel/binary/ast_to_binary.dart';
+import 'package:kernel/binary/ast_from_binary.dart'
+ show BinaryBuilderWithMetadata;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/kernel.dart' show Component, Library, Procedure;
@@ -51,6 +53,7 @@
final bool verbose = new bool.fromEnvironment('DFE_VERBOSE');
final bool dumpKernel = new bool.fromEnvironment('DFE_DUMP_KERNEL');
const String platformKernelFile = 'virtual_platform_kernel.dill';
+const String dotPackagesFile = '.packages';
// NOTE: Any changes to these tags need to be reflected in kernel_isolate.cc
// Tags used to indicate different requests to the dart frontend.
@@ -136,7 +139,6 @@
parseExperimentalArguments(expFlags),
onError: (msg) => errors.add(msg))
..environmentDefines = new EnvironmentMap()
- ..enableAsserts = enableAsserts
..nnbdMode = nullSafety ? NnbdMode.Strong : NnbdMode.Weak
..onDiagnostic = (DiagnosticMessage message) {
bool printMessage;
@@ -298,6 +300,29 @@
supportCodeCoverage: true,
packageConfig: packageConfig);
+ factory IncrementalCompilerWrapper.forExpressionCompilationOnly(
+ Component component,
+ int isolateId,
+ FileSystem fileSystem,
+ Uri platformKernelPath,
+ {bool suppressWarnings: false,
+ bool enableAsserts: false,
+ List<String> experimentalFlags: null,
+ bool bytecode: false,
+ String packageConfig: null}) {
+ IncrementalCompilerWrapper result = IncrementalCompilerWrapper(
+ isolateId, fileSystem, platformKernelPath,
+ suppressWarnings: suppressWarnings,
+ enableAsserts: enableAsserts,
+ experimentalFlags: experimentalFlags,
+ bytecode: bytecode);
+ result.generator = new IncrementalCompiler.forExpressionCompilationOnly(
+ component,
+ result.options,
+ component.mainMethod?.enclosingLibrary?.fileUri);
+ return result;
+ }
+
@override
Future<CompilerResult> compileInternal(Uri script) async {
if (generator == null) {
@@ -379,6 +404,8 @@
final Map<int, IncrementalCompilerWrapper> isolateCompilers =
new Map<int, IncrementalCompilerWrapper>();
final Map<int, List<Uri>> isolateDependencies = new Map<int, List<Uri>>();
+final Map<int, _ExpressionCompilationFromDillSettings> isolateLoadNotifies =
+ new Map<int, _ExpressionCompilationFromDillSettings>();
IncrementalCompilerWrapper lookupIncrementalCompiler(int isolateId) {
return isolateCompilers[isolateId];
@@ -469,9 +496,73 @@
final String libraryUri = request[6];
final String klass = request[7]; // might be null
final bool isStatic = request[8];
+ final List dillData = request[9];
+ final int hotReloadCount = request[10];
+ final bool suppressWarnings = request[11];
+ final bool enableAsserts = request[12];
+ final List<String> experimentalFlags =
+ request[13] != null ? request[13].cast<String>() : null;
+ final bool bytecode = request[14];
IncrementalCompilerWrapper compiler = isolateCompilers[isolateId];
+ _ExpressionCompilationFromDillSettings isolateLoadDillData =
+ isolateLoadNotifies[isolateId];
+ if (isolateLoadDillData != null) {
+ // Check if we can reuse the compiler.
+ if (isolateLoadDillData.hotReloadCount != hotReloadCount ||
+ isolateLoadDillData.prevDillCount != dillData.length) {
+ compiler = isolateCompilers[isolateId] = null;
+ }
+ }
+
+ if (compiler == null) {
+ if (dillData.isNotEmpty) {
+ if (verbose) {
+ print("DFE: Initializing compiler from ${dillData.length} dill files");
+ }
+ isolateLoadNotifies[isolateId] =
+ new _ExpressionCompilationFromDillSettings(
+ hotReloadCount, dillData.length);
+
+ Uri platformUri =
+ computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
+
+ List<List<int>> data = [];
+ data.add(new File.fromUri(platformUri).readAsBytesSync());
+ for (int i = 0; i < dillData.length; i++) {
+ data.add(dillData[i]);
+ }
+
+ // Create Component initialized from the bytes.
+ Component component = new Component();
+ for (List<int> bytes in data) {
+ // TODO(jensj): There might be an issue if main has changed.
+ new BinaryBuilderWithMetadata(bytes, alwaysCreateNewNamedNodes: true)
+ .readComponent(component);
+ }
+
+ FileSystem fileSystem =
+ _buildFileSystem([dotPackagesFile, <int>[]], null, null, null);
+
+ // TODO(aam): IncrementalCompilerWrapper instance created below have to be
+ // destroyed when corresponding isolate is shut down. To achieve that
+ // kernel isolate needs to receive a message indicating that particular
+ // isolate was shut down. Message should be handled here in this script.
+ compiler = new IncrementalCompilerWrapper.forExpressionCompilationOnly(
+ component, isolateId, fileSystem, null,
+ suppressWarnings: suppressWarnings,
+ enableAsserts: enableAsserts,
+ experimentalFlags: experimentalFlags,
+ bytecode: bytecode,
+ packageConfig: dotPackagesFile);
+ isolateCompilers[isolateId] = compiler;
+ await compiler.compile(
+ component.mainMethod?.enclosingLibrary?.importUri ??
+ component.libraries.last.importUri);
+ }
+ }
+
if (compiler == null) {
port.send(new CompilationResult.errors(
["No incremental compiler available for this isolate."], null)
@@ -574,6 +665,7 @@
final int isolateId = request[1];
isolateCompilers.remove(isolateId);
isolateDependencies.remove(isolateId);
+ isolateLoadNotifies.remove(isolateId);
}
Future _processLoadRequest(request) async {
@@ -994,3 +1086,11 @@
new File('kernel_service.tmp${_debugDumpCounter++}.dill')
.writeAsBytesSync(bytes);
}
+
+class _ExpressionCompilationFromDillSettings {
+ int hotReloadCount;
+ int prevDillCount;
+
+ _ExpressionCompilationFromDillSettings(
+ this.hotReloadCount, this.prevDillCount);
+}
diff --git a/pkg/vm/bin/protobuf_aware_treeshaker.dart b/pkg/vm/bin/protobuf_aware_treeshaker.dart
index ac3e756..0f9bf55 100644
--- a/pkg/vm/bin/protobuf_aware_treeshaker.dart
+++ b/pkg/vm/bin/protobuf_aware_treeshaker.dart
@@ -30,7 +30,6 @@
import 'package:args/args.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/binary/limited_ast_to_binary.dart';
import 'package:vm/kernel_front_end.dart'
show runGlobalTransformations, ErrorDetector;
import 'package:kernel/target/targets.dart' show TargetFlags, getTarget;
@@ -186,11 +185,11 @@
}
final sink = File(filename).openWrite();
- final printer = LimitedBinaryPrinter(sink, (lib) {
+ final printer = BinaryPrinter(sink, libraryFilter: (lib) {
if (removeCoreLibs && isCoreLibrary(lib)) return false;
if (isLibEmpty(lib)) return false;
return true;
- }, /*excludeUriToSource=*/ removeSource);
+ }, includeSources: !removeSource);
printer.writeComponentFile(component);
await sink.close();
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index d9d274d..10eeeaa 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -30,12 +30,14 @@
bool fullComponent = false;
Uri initializeFromDillUri;
Uri _entryPoint;
+ final bool forExpressionCompilationOnly;
Uri get entryPoint => _entryPoint;
IncrementalKernelGenerator get generator => _generator;
IncrementalCompiler(this._compilerOptions, this._entryPoint,
- {this.initializeFromDillUri, bool incrementalSerialization: true}) {
+ {this.initializeFromDillUri, bool incrementalSerialization: true})
+ : forExpressionCompilationOnly = false {
if (incrementalSerialization) {
incrementalSerializer = new IncrementalSerializer();
}
@@ -44,6 +46,14 @@
_pendingDeltas = <Component>[];
}
+ IncrementalCompiler.forExpressionCompilationOnly(
+ Component component, this._compilerOptions, this._entryPoint)
+ : forExpressionCompilationOnly = true {
+ _generator = new IncrementalKernelGenerator.forExpressionCompilationOnly(
+ _compilerOptions, _entryPoint, component);
+ _pendingDeltas = <Component>[];
+ }
+
/// Recompiles invalidated files, produces incremental component.
///
/// If [entryPoint] is specified, that points to new entry point for the
@@ -96,6 +106,10 @@
/// were accepted, don't need to be included into subsequent [compile] calls
/// results.
accept() {
+ if (forExpressionCompilationOnly) {
+ throw new StateError("Incremental compiler created for expression "
+ "compilation only; cannot accept");
+ }
Map<Uri, Library> combined = <Uri, Library>{};
Map<Uri, Source> uriToSource = <Uri, Source>{};
@@ -128,6 +142,10 @@
/// were rejected. Subsequent [compile] or [compileExpression] calls need to
/// be processed without changes picked up by rejected [compile] call.
reject() async {
+ if (forExpressionCompilationOnly) {
+ throw new StateError("Incremental compiler created for expression "
+ "compilation only; cannot reject");
+ }
_pendingDeltas.clear();
// Need to reset and warm up compiler so that expression evaluation requests
// are processed in that known good state.
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 9199fa9..1db09a1 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -39,8 +39,6 @@
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/ast.dart' show Component, Library, Reference;
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
-import 'package:kernel/binary/limited_ast_to_binary.dart'
- show LimitedBinaryPrinter;
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget;
@@ -207,9 +205,9 @@
final Uri packagesUri = packages != null ? resolveInputUri(packages) : null;
final platformKernelUri = Uri.base.resolveUri(new Uri.file(platformKernel));
- final List<Uri> linkedDependencies = <Uri>[];
+ final List<Uri> additionalDills = <Uri>[];
if (aot || linkPlatform) {
- linkedDependencies.add(platformKernelUri);
+ additionalDills.add(platformKernelUri);
}
Uri mainUri = resolveInputUri(input);
@@ -224,7 +222,7 @@
..sdkSummary = platformKernelUri
..target = target
..fileSystem = fileSystem
- ..linkedDependencies = linkedDependencies
+ ..additionalDills = additionalDills
..packagesFileUri = packagesUri
..experimentalFlags = parseExperimentalFlags(
parseExperimentalArguments(experimentalFlags),
@@ -236,7 +234,7 @@
..embedSourceText = embedSources;
final results = await compileToKernel(mainUri, compilerOptions,
- includePlatform: linkedDependencies.isNotEmpty,
+ includePlatform: additionalDills.isNotEmpty,
aot: aot,
useGlobalTypeFlowAnalysis: tfa,
environmentDefines: environmentDefines,
@@ -660,11 +658,9 @@
}
}
- final BinaryPrinter printer = new LimitedBinaryPrinter(
- sink,
- (lib) =>
- packageFor(lib, compilationResults.loadedLibraries) == package,
- false /* excludeUriToSource */);
+ final BinaryPrinter printer = new BinaryPrinter(sink,
+ libraryFilter: (lib) =>
+ packageFor(lib, compilationResults.loadedLibraries) == package);
printer.writeComponentFile(partComponent);
await sink.close();
diff --git a/pkg/vm/lib/metadata/unboxing_info.dart b/pkg/vm/lib/metadata/unboxing_info.dart
new file mode 100644
index 0000000..3824ca7
--- /dev/null
+++ b/pkg/vm/lib/metadata/unboxing_info.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, 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.
+
+import 'package:kernel/ast.dart';
+
+class UnboxingInfoMetadata {
+ static const kBoxed = 0;
+ static const kUnboxedIntCandidate = 1 << 0;
+ static const kUnboxedDoubleCandidate = 1 << 1;
+ static const kUnboxingCandidate =
+ kUnboxedIntCandidate | kUnboxedDoubleCandidate;
+
+ final List<int> unboxedArgsInfo;
+ int returnInfo;
+
+ UnboxingInfoMetadata(int argsLen) : unboxedArgsInfo = [] {
+ for (int i = 0; i < argsLen; i++) {
+ unboxedArgsInfo.add(kUnboxingCandidate);
+ }
+ returnInfo = kUnboxingCandidate;
+ }
+
+ UnboxingInfoMetadata.readFromBinary(BinarySource source)
+ : unboxedArgsInfo = List<int>.generate(
+ source.readUInt(), (_) => source.readByte(),
+ growable: true),
+ returnInfo = source.readByte();
+
+ void writeToBinary(BinarySink sink) {
+ sink.writeUInt30(unboxedArgsInfo.length);
+ for (int val in unboxedArgsInfo) {
+ sink.writeByte(val);
+ }
+ sink.writeByte(returnInfo);
+ }
+}
+
+class UnboxingInfoMetadataRepository
+ extends MetadataRepository<UnboxingInfoMetadata> {
+ static const repositoryTag = 'vm.unboxing-info.metadata';
+
+ @override
+ final String tag = repositoryTag;
+
+ @override
+ final Map<TreeNode, UnboxingInfoMetadata> mapping =
+ <TreeNode, UnboxingInfoMetadata>{};
+
+ @override
+ void writeToBinary(
+ UnboxingInfoMetadata metadata, Node node, BinarySink sink) {
+ metadata.writeToBinary(sink);
+ }
+
+ @override
+ UnboxingInfoMetadata readFromBinary(Node node, BinarySource source) {
+ return UnboxingInfoMetadata.readFromBinary(source);
+ }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index 39c24e7..cab8e4d 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -511,6 +511,7 @@
List<Statement> _statements = <Statement>[];
TypeExpr result = null;
+ Type resultType = EmptyType();
Summary(
{this.parameterCount: 0,
@@ -620,7 +621,9 @@
Statistics.summariesAnalyzed++;
- return result.getComputedType(types);
+ Type computedType = result.getComputedType(types);
+ resultType = resultType.union(computedType, typeHierarchy);
+ return computedType;
}
Args<Type> get argumentTypes {
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index da7813f..12a97c8 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -19,6 +19,7 @@
import 'summary.dart';
import 'table_selector.dart';
import 'types.dart';
+import 'unboxing_info.dart';
import 'utils.dart';
import '../pragma.dart';
import '../devirtualization.dart' show Devirtualization;
@@ -26,6 +27,7 @@
import '../../metadata/inferred_type.dart';
import '../../metadata/procedure_attributes.dart';
import '../../metadata/table_selector.dart';
+import '../../metadata/unboxing_info.dart';
import '../../metadata/unreachable.dart';
const bool kDumpClassHierarchy =
@@ -73,7 +75,12 @@
new TFADevirtualization(component, typeFlowAnalysis, hierarchy)
.visitComponent(component);
- new AnnotateKernel(component, typeFlowAnalysis).visitComponent(component);
+ final unboxingInfo = new UnboxingInfoManager(typeFlowAnalysis);
+
+ _makePartition(component, typeFlowAnalysis, unboxingInfo);
+
+ new AnnotateKernel(component, typeFlowAnalysis, unboxingInfo)
+ .visitComponent(component);
transformsStopWatch.stop();
@@ -117,10 +124,13 @@
final ProcedureAttributesMetadataRepository _procedureAttributesMetadata;
final TableSelectorMetadataRepository _tableSelectorMetadata;
final TableSelectorAssigner _tableSelectorAssigner;
+ final UnboxingInfoMetadataRepository _unboxingInfoMetadata;
+ final UnboxingInfoManager _unboxingInfo;
final Class _intClass;
Constant _nullConstant;
- AnnotateKernel(Component component, this._typeFlowAnalysis)
+ AnnotateKernel(
+ Component component, this._typeFlowAnalysis, this._unboxingInfo)
: _directCallMetadataRepository =
component.metadata[DirectCallMetadataRepository.repositoryTag],
_inferredTypeMetadata = new InferredTypeMetadataRepository(),
@@ -129,11 +139,13 @@
new ProcedureAttributesMetadataRepository(),
_tableSelectorMetadata = new TableSelectorMetadataRepository(),
_tableSelectorAssigner = new TableSelectorAssigner(),
+ _unboxingInfoMetadata = new UnboxingInfoMetadataRepository(),
_intClass = _typeFlowAnalysis.environment.coreTypes.intClass {
component.addMetadataRepository(_inferredTypeMetadata);
component.addMetadataRepository(_unreachableNodeMetadata);
component.addMetadataRepository(_procedureAttributesMetadata);
component.addMetadataRepository(_tableSelectorMetadata);
+ component.addMetadataRepository(_unboxingInfoMetadata);
}
// Query whether a call site was marked as a direct call by the analysis.
@@ -301,10 +313,35 @@
skipCheck: uncheckedParameters.contains(param));
}
+ final unboxingInfoMetadata =
+ _unboxingInfo.getUnboxingInfoOfMember(member);
+
+ if (unboxingInfoMetadata != null) {
+ _unboxingInfoMetadata.mapping[member] = unboxingInfoMetadata;
+ }
+
// TODO(alexmarkov): figure out how to pass receiver type.
}
} else if (!member.isAbstract) {
_setUnreachable(member);
+ } else if (member is! Field) {
+ final unboxingInfoMetadata =
+ _unboxingInfo.getUnboxingInfoOfMember(member);
+ if (unboxingInfoMetadata != null) {
+ // Check for partitions that only have abstract methods should be marked as boxed.
+ if (unboxingInfoMetadata.returnInfo ==
+ UnboxingInfoMetadata.kUnboxingCandidate) {
+ unboxingInfoMetadata.returnInfo = UnboxingInfoMetadata.kBoxed;
+ }
+ for (int i = 0; i < unboxingInfoMetadata.unboxedArgsInfo.length; i++) {
+ if (unboxingInfoMetadata.unboxedArgsInfo[i] ==
+ UnboxingInfoMetadata.kUnboxingCandidate) {
+ unboxingInfoMetadata.unboxedArgsInfo[i] =
+ UnboxingInfoMetadata.kBoxed;
+ }
+ }
+ _unboxingInfoMetadata.mapping[member] = unboxingInfoMetadata;
+ }
}
// We need to attach ProcedureAttributesMetadata to all members, even
@@ -424,6 +461,76 @@
}
}
+// Partition the methods in order to idenfity parameters and return values
+// that are unboxing candidates
+void _makePartition(Component component, TypeFlowAnalysis typeFlowAnalysis,
+ UnboxingInfoManager unboxingInfo) {
+ // Traverses all the members and creates the partition graph.
+ // Currently unboxed parameters and return value are not supported for
+ // closures, therefore they do not exist in this graph
+ for (bool registering in const [true, false]) {
+ for (Library library in component.libraries) {
+ for (Class cls in library.classes) {
+ for (Member member in cls.members) {
+ if (registering) {
+ unboxingInfo.registerMember(member);
+ } else {
+ unboxingInfo.linkWithSuperClasses(member);
+ }
+ }
+ }
+ if (registering) {
+ for (Member member in library.members) {
+ unboxingInfo.registerMember(member);
+ }
+ }
+ }
+ }
+ unboxingInfo.finishGraph();
+
+ for (Library library in component.libraries) {
+ for (Class cls in library.classes) {
+ for (Member member in cls.members) {
+ _updateUnboxingInfoOfMember(member, typeFlowAnalysis, unboxingInfo);
+ }
+ }
+ for (Member member in library.members) {
+ _updateUnboxingInfoOfMember(member, typeFlowAnalysis, unboxingInfo);
+ }
+ }
+}
+
+void _updateUnboxingInfoOfMember(Member member,
+ TypeFlowAnalysis typeFlowAnalysis, UnboxingInfoManager unboxingInfo) {
+ if (typeFlowAnalysis.isMemberUsed(member) && (member is! Field)) {
+ final Args<Type> argTypes = typeFlowAnalysis.argumentTypes(member);
+ assertx(argTypes != null);
+
+ final int firstParamIndex =
+ numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
+
+ final positionalParams = member.function.positionalParameters;
+ assertx(
+ argTypes.positionalCount == firstParamIndex + positionalParams.length);
+
+ for (int i = 0; i < positionalParams.length; i++) {
+ final inferredType = argTypes.values[firstParamIndex + i];
+ unboxingInfo.applyToArg(member, i, inferredType);
+ }
+
+ final names = argTypes.names;
+ for (int i = 0; i < names.length; i++) {
+ final inferredType =
+ argTypes.values[firstParamIndex + positionalParams.length + i];
+ unboxingInfo.applyToArg(
+ member, positionalParams.length + i, inferredType);
+ }
+
+ final Type resultType = typeFlowAnalysis.getSummary(member).resultType;
+ unboxingInfo.applyToReturn(member, resultType);
+ }
+}
+
/// Tree shaking based on results of type flow analysis (TFA).
///
/// TFA provides information about allocated classes and reachable member
diff --git a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
new file mode 100644
index 0000000..67be799
--- /dev/null
+++ b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
@@ -0,0 +1,286 @@
+// Copyright (c) 2020, 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.
+
+import 'dart:async';
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/external_name.dart' show getExternalName;
+import 'package:vm/transformations/type_flow/analysis.dart';
+import 'package:vm/transformations/type_flow/types.dart';
+
+import '../../metadata/unboxing_info.dart';
+import 'utils.dart';
+
+class UnboxingInfoManager {
+ final List<UnboxingInfoMetadata> _allUnboxingInfo = [];
+ final Map<Member, int> _memberIds = {};
+ final List<int> _partitionIds = [];
+ final List<int> _partitionRank = [];
+ final Set<Member> _mustBox = {};
+
+ final TypeHierarchy _typeHierarchy;
+ final CoreTypes _coreTypes;
+ bool _finishedGraph;
+
+ UnboxingInfoManager(TypeFlowAnalysis typeFlowAnalysis)
+ : _typeHierarchy = typeFlowAnalysis.hierarchyCache,
+ _coreTypes = typeFlowAnalysis.environment.coreTypes,
+ _finishedGraph = false;
+
+ void registerMember(Member member) {
+ member = _validMemberOrNull(member);
+ if (member == null) return;
+ _addMember(member);
+ }
+
+ UnboxingInfoMetadata getUnboxingInfoOfMember(Member member) {
+ assertx(_finishedGraph);
+ member = _validMemberOrNull(member);
+ if ((member == null || (!_memberIds.containsKey(member)))) {
+ return null;
+ }
+ final partitionId = _memberIds[member];
+ return _allUnboxingInfo[partitionId];
+ }
+
+ void linkWithSuperClasses(Member member) {
+ member = _validMemberOrNull(member);
+ if (member == null) return;
+ _linkRecursive(member, member.enclosingClass);
+ }
+
+ void finishGraph() {
+ assertx(!_finishedGraph);
+ final oldToNewId = {};
+ final newUnboxingInfo = <UnboxingInfoMetadata>[];
+ for (int i = 0; i < _allUnboxingInfo.length; i++) {
+ if (_find(i) == i) {
+ final newId = oldToNewId.length;
+ oldToNewId[i] = newId;
+ newUnboxingInfo.add(_allUnboxingInfo[i]);
+ }
+ }
+ for (final key in _memberIds.keys) {
+ final newId = oldToNewId[_partitionIds[_memberIds[key]]];
+ assertx(newId != null);
+ _memberIds[key] = newId;
+ }
+ _allUnboxingInfo.clear();
+ _allUnboxingInfo.insertAll(0, newUnboxingInfo);
+ _memberIds.forEach((member, id) {
+ if (_mustBox.contains(member)) {
+ _allUnboxingInfo[id].returnInfo = UnboxingInfoMetadata.kBoxed;
+ _allUnboxingInfo[id].unboxedArgsInfo.clear();
+ }
+ });
+ _partitionIds.clear();
+ _partitionRank.clear();
+ _finishedGraph = true;
+ }
+
+ void applyToArg(Member member, int argPos, Type type) {
+ assertx(_finishedGraph);
+ member = _validMemberOrNull(member);
+ if (member == null) return;
+ assertx(_memberIds.containsKey(member));
+ final partitionId = _memberIds[member];
+
+ if (argPos < 0 ||
+ _allUnboxingInfo[partitionId].unboxedArgsInfo.length <= argPos) {
+ return;
+ }
+
+ final unboxingInfo = _allUnboxingInfo[partitionId];
+
+ if (type is NullableType ||
+ (!type.isSubtypeOf(_typeHierarchy, _coreTypes.intClass) &&
+ !type.isSubtypeOf(_typeHierarchy, _coreTypes.doubleClass))) {
+ unboxingInfo.unboxedArgsInfo[argPos] = UnboxingInfoMetadata.kBoxed;
+ } else {
+ final unboxingType = type.isSubtypeOf(_typeHierarchy, _coreTypes.intClass)
+ ? UnboxingInfoMetadata.kUnboxedIntCandidate
+ : UnboxingInfoMetadata.kUnboxedDoubleCandidate;
+ unboxingInfo.unboxedArgsInfo[argPos] &= unboxingType;
+ }
+ }
+
+ void applyToReturn(Member member, Type type) {
+ assertx(_finishedGraph);
+ member = _validMemberOrNull(member);
+ if (member == null) return;
+ assertx(_memberIds.containsKey(member));
+ final partitionId = _memberIds[member];
+ final unboxingInfo = _allUnboxingInfo[partitionId];
+
+ if (type is NullableType ||
+ (!type.isSubtypeOf(_typeHierarchy, _coreTypes.intClass) &&
+ !type.isSubtypeOf(_typeHierarchy, _coreTypes.doubleClass))) {
+ unboxingInfo.returnInfo = UnboxingInfoMetadata.kBoxed;
+ } else {
+ final unboxingType = type.isSubtypeOf(_typeHierarchy, _coreTypes.intClass)
+ ? UnboxingInfoMetadata.kUnboxedIntCandidate
+ : UnboxingInfoMetadata.kUnboxedDoubleCandidate;
+ unboxingInfo.returnInfo &= unboxingType;
+ }
+ }
+
+ void _linkRecursive(Member member, Class cls) {
+ for (final superType in cls.supers) {
+ final superClass = superType.classNode;
+ bool linked = false;
+ superClass.procedures.forEach((Procedure procedure) {
+ if (member.name == procedure.name) {
+ _linkMembers(member, procedure);
+ linked = true;
+ }
+ });
+ if (!linked) {
+ _linkRecursive(member, superClass);
+ }
+ }
+ }
+
+ void _linkMembers(Member member1, Member member2) {
+ member1 = _validMemberOrNull(member1);
+ member2 = _validMemberOrNull(member2);
+ if (member1 == null ||
+ member2 == null ||
+ _isConstructorOrStatic(member1) ||
+ _isConstructorOrStatic(member2)) {
+ return;
+ }
+ _union(_getMemberId(member1), _getMemberId(member2));
+ }
+
+ Member _validMemberOrNull(Member member) {
+ if (member == null || (member is! Procedure && member is! Constructor)) {
+ return null;
+ }
+
+ // TODO(dartbug.com/33549): Support setters with unboxed arguments
+ // For this, fields should also be considered in the partition
+ // and be annotated with the UnboxingInfoMetadata.
+ if (member is Procedure && (member.isSetter || member.isGetter)) {
+ return null;
+ }
+
+ return member;
+ }
+
+ bool _isConstructorOrStatic(Member member) {
+ return ((member is Constructor) ||
+ ((member is Procedure) && member.isStatic));
+ }
+
+ void _addMember(Member member) {
+ assertx(!_finishedGraph);
+
+ if (_cannotUnbox(member)) {
+ _mustBox.add(member);
+ }
+
+ final int memberId = _allUnboxingInfo.length;
+ assertx(memberId == _partitionIds.length);
+ assertx(_partitionIds.length == _partitionRank.length);
+ final int argsLen = member.function.requiredParameterCount;
+ _memberIds[member] = memberId;
+ _allUnboxingInfo.add(UnboxingInfoMetadata(argsLen));
+ _partitionIds.add(memberId);
+ _partitionRank.add(1);
+ }
+
+ bool _cannotUnbox(Member member) {
+ // Methods that do not need dynamic invocation forwarders can not have
+ // unboxed parameters and return because dynamic calls always use boxed
+ // values.
+
+ return (_isNative(member) ||
+ _isEnclosingClassSubtypeOfNum(member) ||
+ (!_isConstructorOrStatic(member) &&
+ !_needsDynamicInvocationForwarder(member)));
+ }
+
+ bool _isNative(Member member) {
+ return (getExternalName(member) != null);
+ }
+
+ // TODO(dartbug.com/33549): Calls to these methods could be replaced by
+ // CheckedSmiOpInstr, so in order to allow the parameters and return
+ // value to be unboxed, the slow path for such instructions should be
+ // updated to be consistent with the representations from the target interface.
+ bool _isEnclosingClassSubtypeOfNum(Member member) {
+ return (member.enclosingClass != null &&
+ ConeType(_typeHierarchy.getTFClass(member.enclosingClass))
+ .isSubtypeOf(_typeHierarchy, _coreTypes.numClass));
+ }
+
+ bool _needsDynamicInvocationForwarder(Procedure procedure) {
+ for (var param in procedure.function.positionalParameters) {
+ if (!_isTopTypeForAssignability(param.type) &&
+ !param.isCovariant &&
+ !param.isGenericCovariantImpl) {
+ return true;
+ }
+ }
+
+ for (var param in procedure.function.namedParameters) {
+ if (!_isTopTypeForAssignability(param.type) &&
+ !param.isCovariant &&
+ !param.isGenericCovariantImpl) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool _isTopTypeForAssignability(DartType type) {
+ return (_coreTypes.isTop(type) || (type == Object) || (type == FutureOr));
+ }
+
+ int _getMemberId(Member member) {
+ return _memberIds[member];
+ }
+
+ int _find(int memberId) {
+ assertx(!_finishedGraph);
+ if (memberId == _partitionIds[memberId]) {
+ return memberId;
+ }
+ final partitionId = _find(_partitionIds[memberId]);
+ _allUnboxingInfo[memberId] = null;
+ _partitionIds[memberId] = partitionId;
+ return partitionId;
+ }
+
+ void _union(int memberId1, int memberId2) {
+ assertx(!_finishedGraph);
+ final partitionId1 = _find(memberId1);
+ final partitionId2 = _find(memberId2);
+
+ if (partitionId1 == partitionId2) {
+ return;
+ }
+
+ int from, to;
+ if (_partitionRank[partitionId1] < _partitionRank[partitionId2]) {
+ from = partitionId1;
+ to = partitionId2;
+ } else {
+ from = partitionId2;
+ to = partitionId1;
+ }
+ final fromArgsInfo = _allUnboxingInfo[from].unboxedArgsInfo;
+ final toArgsInfo = _allUnboxingInfo[to].unboxedArgsInfo;
+ if (fromArgsInfo.length < toArgsInfo.length) {
+ toArgsInfo.length = fromArgsInfo.length;
+ }
+ _allUnboxingInfo[from] = null;
+ _partitionIds[from] = to;
+ if (_partitionRank[from] == _partitionRank[to]) {
+ _partitionRank[to]++;
+ }
+ }
+}
diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
index afa5e6b..5473874 100644
--- a/pkg/vm/test/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -43,7 +43,7 @@
environmentDefines ??= <String, String>{};
final options = new CompilerOptions()
..target = target
- ..linkedDependencies = <Uri>[platformKernel]
+ ..additionalDills = <Uri>[platformKernel]
..environmentDefines = environmentDefines
..onDiagnostic = (DiagnosticMessage message) {
fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index 1399f8f..9ab5182 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -10,7 +10,6 @@
show CompilerOptions, DiagnosticMessage, computePlatformBinariesLocation;
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/binary/limited_ast_to_binary.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:kernel/text/ast_to_text.dart';
@@ -27,14 +26,19 @@
final platformKernel =
computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
final sdkRoot = computePlatformBinariesLocation();
- final options = new CompilerOptions()
- ..sdkRoot = sdkRoot
- ..target = new VmTarget(new TargetFlags())
- ..linkedDependencies = <Uri>[platformKernel]
- ..onDiagnostic = (DiagnosticMessage message) {
- fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
- }
- ..environmentDefines = const {};
+
+ CompilerOptions getFreshOptions() {
+ return new CompilerOptions()
+ ..sdkRoot = sdkRoot
+ ..target = new VmTarget(new TargetFlags())
+ ..additionalDills = <Uri>[platformKernel]
+ ..onDiagnostic = (DiagnosticMessage message) {
+ fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
+ }
+ ..environmentDefines = const {};
+ }
+
+ final options = getFreshOptions();
group('basic', () {
Directory mytest;
@@ -70,13 +74,8 @@
});
test('compile exclude sources', () async {
- CompilerOptions optionsExcludeSources = new CompilerOptions()
- ..sdkRoot = options.sdkRoot
- ..target = options.target
- ..linkedDependencies = options.linkedDependencies
- ..onDiagnostic = options.onDiagnostic
- ..embedSourceText = false
- ..environmentDefines = options.environmentDefines;
+ CompilerOptions optionsExcludeSources = getFreshOptions()
+ ..embedSourceText = false;
IncrementalCompiler compiler =
new IncrementalCompiler(optionsExcludeSources, main.uri);
Component component = await compiler.compile();
@@ -98,15 +97,11 @@
test('compile expressions errors are not re-reported', () async {
var errorsReported = 0;
- CompilerOptions optionsAcceptErrors = new CompilerOptions()
- ..sdkRoot = options.sdkRoot
- ..target = options.target
- ..linkedDependencies = options.linkedDependencies
+ CompilerOptions optionsAcceptErrors = getFreshOptions()
..onDiagnostic = (DiagnosticMessage message) {
errorsReported++;
message.plainTextFormatted.forEach(print);
- }
- ..environmentDefines = options.environmentDefines;
+ };
IncrementalCompiler compiler =
new IncrementalCompiler(optionsAcceptErrors, main.uri);
await compiler.compile();
@@ -309,18 +304,14 @@
new BinaryPrinter(new DevNullSink<List<int>>())
.writeComponentFile(component);
IOSink sink = mainDill.openWrite();
- BinaryPrinter printer = new LimitedBinaryPrinter(
- sink,
- (lib) => lib.fileUri.path.endsWith("main.dart"),
- false /* excludeUriToSource */);
+ BinaryPrinter printer = new BinaryPrinter(sink,
+ libraryFilter: (lib) => lib.fileUri.path.endsWith("main.dart"));
printer.writeComponentFile(component);
await sink.flush();
await sink.close();
sink = libDill.openWrite();
- printer = new LimitedBinaryPrinter(
- sink,
- (lib) => lib.fileUri.path.endsWith("lib.dart"),
- false /* excludeUriToSource */);
+ printer = new BinaryPrinter(sink,
+ libraryFilter: (lib) => lib.fileUri.path.endsWith("lib.dart"));
printer.writeComponentFile(component);
await sink.flush();
await sink.close();
@@ -550,26 +541,20 @@
new BinaryPrinter(new DevNullSink<List<int>>())
.writeComponentFile(component);
IOSink sink = mainDill.openWrite();
- BinaryPrinter printer = new LimitedBinaryPrinter(
- sink,
- (lib) => lib.fileUri.path.endsWith("main.dart"),
- false /* excludeUriToSource */);
+ BinaryPrinter printer = new BinaryPrinter(sink,
+ libraryFilter: (lib) => lib.fileUri.path.endsWith("main.dart"));
printer.writeComponentFile(component);
await sink.flush();
await sink.close();
sink = lib1Dill.openWrite();
- printer = new LimitedBinaryPrinter(
- sink,
- (lib) => lib.fileUri.path.endsWith("lib1.dart"),
- false /* excludeUriToSource */);
+ printer = new BinaryPrinter(sink,
+ libraryFilter: (lib) => lib.fileUri.path.endsWith("lib1.dart"));
printer.writeComponentFile(component);
await sink.flush();
await sink.close();
sink = lib2Dill.openWrite();
- printer = new LimitedBinaryPrinter(
- sink,
- (lib) => lib.fileUri.path.endsWith("lib2.dart"),
- false /* excludeUriToSource */);
+ printer = new BinaryPrinter(sink,
+ libraryFilter: (lib) => lib.fileUri.path.endsWith("lib2.dart"));
printer.writeComponentFile(component);
await sink.flush();
await sink.close();
@@ -627,9 +612,22 @@
});
group('reload', () {
+ Directory mytest;
+
+ setUpAll(() {
+ mytest = Directory.systemTemp.createTempSync('incremental');
+ });
+
+ tearDownAll(() {
+ try {
+ mytest.deleteSync(recursive: true);
+ } catch (_) {
+ // Ignore errors;
+ }
+ });
+
test('picks up after rejected delta', () async {
- var systemTempDir = Directory.systemTemp;
- var file = new File('${systemTempDir.path}/foo.dart')..createSync();
+ var file = new File('${mytest.path}/foo.dart')..createSync();
file.writeAsStringSync("import 'bar.dart';\n"
"import 'baz.dart';\n"
"main() {\n"
@@ -637,17 +635,17 @@
" openReceivePortSoWeWontDie();"
"}\n");
- var fileBar = new File('${systemTempDir.path}/bar.dart')..createSync();
+ var fileBar = new File('${mytest.path}/bar.dart')..createSync();
fileBar.writeAsStringSync("class A<T> { int _a; }\n");
- var fileBaz = new File('${systemTempDir.path}/baz.dart')..createSync();
+ var fileBaz = new File('${mytest.path}/baz.dart')..createSync();
fileBaz.writeAsStringSync("import 'dart:isolate';\n"
"openReceivePortSoWeWontDie() { new RawReceivePort(); }\n");
IncrementalCompiler compiler = new IncrementalCompiler(options, file.uri);
Component component = await compiler.compile();
- File outputFile = new File('${systemTempDir.path}/foo.dart.dill');
+ File outputFile = new File('${mytest.path}/foo.dart.dill');
await _writeProgramToFile(component, outputFile);
final List<String> vmArgs = [
@@ -755,9 +753,11 @@
"openReceivePortSoWeWontDie() { new RawReceivePort(); }\n");
Uri packageEntry = Uri.parse('package:foo/foo.dart');
- options.packagesFileUri = packageUri;
+
+ CompilerOptions optionsModified = getFreshOptions()
+ ..packagesFileUri = packageUri;
IncrementalCompiler compiler =
- new IncrementalCompiler(options, packageEntry);
+ new IncrementalCompiler(optionsModified, packageEntry);
{
Component component = await compiler.compile(entryPoint: packageEntry);
File outputFile = new File('${mytest.path}/foo.dart.dill');
@@ -786,12 +786,476 @@
}
});
});
+
+ group('expression evaluation', () {
+ Directory mytest;
+ Process vm;
+
+ setUpAll(() {
+ mytest = Directory.systemTemp.createTempSync('expression_evaluation');
+ });
+
+ tearDownAll(() {
+ try {
+ mytest.deleteSync(recursive: true);
+ } catch (_) {
+ // Ignore errors;
+ }
+ try {
+ vm.kill();
+ } catch (_) {
+ // Ignore errors;
+ }
+ });
+
+ launchBreakAndEvaluate(File scriptOrDill, String scriptUriToBreakIn,
+ int lineToBreakAt, List<String> expressionsAndExpectedResults,
+ {Future Function(RemoteVm remoteVm) callback}) async {
+ vm = await Process.start(Platform.resolvedExecutable, <String>[
+ "--pause-isolates-on-start",
+ "--enable-vm-service:0",
+ "--disable-service-auth-codes",
+ scriptOrDill.path
+ ]);
+
+ const kObservatoryListening = 'Observatory listening on ';
+ final RegExp observatoryPortRegExp =
+ new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)/");
+ int port;
+ final splitter = new LineSplitter();
+ Completer<String> portLineCompleter = new Completer<String>();
+ vm.stdout
+ .transform(utf8.decoder)
+ .transform(splitter)
+ .listen((String s) async {
+ print("vm stdout: $s");
+ if (s.startsWith(kObservatoryListening)) {
+ expect(observatoryPortRegExp.hasMatch(s), isTrue);
+ final match = observatoryPortRegExp.firstMatch(s);
+ port = int.parse(match.group(1));
+ RemoteVm remoteVm = new RemoteVm(port);
+
+ // Wait for the script to have loaded.
+ while (true) {
+ Map isolate = await remoteVm.getIsolate();
+ Map pauseEvent = isolate["pauseEvent"];
+ if (pauseEvent["kind"] == "PauseStart") break;
+ }
+
+ var breakpoint = await findScriptAndBreak(
+ remoteVm, scriptUriToBreakIn, lineToBreakAt);
+ await remoteVm.resume();
+ await waitForScriptToHavePaused(remoteVm);
+ await evaluateExpressions(expressionsAndExpectedResults, remoteVm);
+ await deletePossibleBreakpoint(remoteVm, breakpoint);
+
+ if (callback != null) {
+ await callback(remoteVm);
+ }
+
+ await remoteVm.resume();
+
+ if (!portLineCompleter.isCompleted) {
+ portLineCompleter.complete("done");
+ }
+ }
+ });
+ bool gotStdErrOutput = false;
+ vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
+ print("vm stderr: $s");
+ gotStdErrOutput = true;
+ });
+ await portLineCompleter.future;
+ int exitCode = await vm.exitCode;
+ print("Compiler terminated with ${exitCode} exit code");
+ expect(exitCode, equals(0));
+ expect(gotStdErrOutput, isFalse);
+ }
+
+ test('from source', () async {
+ Directory dir = mytest.createTempSync();
+ File mainFile = new File.fromUri(dir.uri.resolve("main.dart"));
+ mainFile.writeAsStringSync(r"""
+ var hello = "Hello";
+ main() {
+ var s = "$hello world!";
+ print(s);
+ }
+ int extra() { return 22; }
+ """);
+
+ await launchBreakAndEvaluate(mainFile, mainFile.uri.toString(), 4, [
+ // 1st expression
+ "s.length",
+ "12",
+
+ // 2nd expression
+ "s",
+ "Hello world!",
+
+ // 3rd expression
+ "hello",
+ "Hello",
+
+ // 4th expression
+ "extra()",
+ "22",
+ ]);
+ });
+
+ test('from dill', () async {
+ Directory dir = mytest.createTempSync();
+ File mainFile = new File.fromUri(dir.uri.resolve("main.dart"));
+ mainFile.writeAsStringSync(r"""
+ var hello = "Hello";
+ main() {
+ var s = "$hello world!";
+ print(s);
+ }
+ int extra() { return 22; }
+ """);
+ IncrementalCompiler compiler =
+ new IncrementalCompiler(options, mainFile.uri);
+ Component component = await compiler.compile();
+ File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
+ IOSink sink = mainDill.openWrite();
+ new BinaryPrinter(sink).writeComponentFile(component);
+ await sink.flush();
+ await sink.close();
+
+ mainFile.deleteSync();
+
+ await launchBreakAndEvaluate(mainDill, mainFile.uri.toString(), 4, [
+ // 1st expression
+ "s.length",
+ "12",
+
+ // 2nd expression
+ "s",
+ "Hello world!",
+
+ // 3rd expression
+ "hello",
+ "Hello",
+
+ // 4th expression
+ "extra()",
+ "22",
+ ]);
+ });
+
+ test('from dill with reload', () async {
+ Directory dir = mytest.createTempSync();
+ File mainFile = new File.fromUri(dir.uri.resolve("main.dart"));
+ mainFile.writeAsStringSync(r"""
+ import 'dart:async';
+ import 'helper.dart';
+ main() {
+ int latestReloadTime;
+ int noChangeCount = 0;
+ int numChanges = 0;
+ new Timer.periodic(new Duration(milliseconds: 5), (timer) async {
+ var result = reloadTime();
+ if (latestReloadTime != result) {
+ latestReloadTime = result;
+ numChanges++;
+ helperMethod();
+ } else {
+ noChangeCount++;
+ }
+ if (latestReloadTime == 42) {
+ timer.cancel();
+ }
+ if (numChanges > 20) {
+ timer.cancel();
+ }
+ if (noChangeCount >= 400) {
+ // ~2 seconds with no change.
+ throw "Expected to be done but wasn't";
+ }
+ });
+ }
+ """);
+ File helperFile = new File.fromUri(dir.uri.resolve("helper.dart"));
+ helperFile.writeAsStringSync(r"""
+ int reloadTime() {
+ return 0;
+ }
+ void helperMethod() {
+ var hello = "Hello";
+ var s = "$hello world!";
+ print(s);
+ }
+ """);
+ IncrementalCompiler compiler =
+ new IncrementalCompiler(options, mainFile.uri);
+ Component component = await compiler.compile();
+ File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
+ IOSink sink = mainDill.openWrite();
+ new BinaryPrinter(sink).writeComponentFile(component);
+ await sink.flush();
+ await sink.close();
+ print("=> Notice main file has size ${mainDill.lengthSync()}");
+
+ helperFile.writeAsStringSync(r"""
+ int reloadTime() {
+ return 1;
+ }
+ void helperMethod() {
+ var hello = "Hello";
+ var s = "$hello world!!!";
+ print(s);
+ }
+ int helperMethod2() {
+ return 42;
+ }
+ """);
+ compiler.invalidate(helperFile.uri);
+ component = await compiler.compile();
+ File partial1Dill =
+ new File.fromUri(mainFile.uri.resolve("partial1.dill"));
+ sink = partial1Dill.openWrite();
+ new BinaryPrinter(sink).writeComponentFile(component);
+ await sink.flush();
+ await sink.close();
+ print("=> Notice partial file #1 has size ${partial1Dill.lengthSync()}");
+
+ helperFile.writeAsStringSync(r"""
+ int reloadTime() {
+ return 2;
+ }
+ void helperMethod() {
+ var hello = "Hello";
+ var s = "$hello world!!!!";
+ print(s);
+ }
+ int helperMethod2() {
+ return 21;
+ }
+ int helperMethod3() {
+ return 84;
+ }
+ """);
+ compiler.invalidate(helperFile.uri);
+ component = await compiler.compile();
+ File partial2Dill =
+ new File.fromUri(mainFile.uri.resolve("partial2.dill"));
+ sink = partial2Dill.openWrite();
+ new BinaryPrinter(sink).writeComponentFile(component);
+ await sink.flush();
+ await sink.close();
+ print("=> Notice partial file #2 has size ${partial2Dill.lengthSync()}");
+
+ mainFile.deleteSync();
+ helperFile.deleteSync();
+
+ await launchBreakAndEvaluate(mainDill, helperFile.uri.toString(), 7, [
+ // 1st expression
+ "s.length",
+ "12",
+
+ // 2nd expression
+ "s",
+ "Hello world!",
+
+ // 3rd expression
+ "hello",
+ "Hello",
+
+ // 4th expression
+ "reloadTime()",
+ "0",
+ ], callback: (RemoteVm remoteVm) async {
+ for (int q = 0; q < 10; q++) {
+ var reloadResult = await remoteVm.reload(partial1Dill.uri);
+ expect(reloadResult is Map, isTrue);
+ expect(reloadResult["success"], equals(true));
+
+ await remoteVm.forceGc();
+
+ var breakpoint =
+ await findScriptAndBreak(remoteVm, helperFile.uri.toString(), 7);
+ await remoteVm.resume();
+ await waitForScriptToHavePaused(remoteVm);
+ await evaluateExpressions([
+ // 1st expression
+ "s.length",
+ "14",
+
+ // 2nd expression
+ "s",
+ "Hello world!!!",
+
+ // 3rd expression
+ "hello",
+ "Hello",
+
+ // 4th expression
+ "reloadTime()",
+ "1",
+
+ // 5th expression
+ "helperMethod2()",
+ "42",
+ ], remoteVm);
+ await deletePossibleBreakpoint(remoteVm, breakpoint);
+
+ reloadResult = await remoteVm.reload(partial2Dill.uri);
+ expect(reloadResult is Map, isTrue);
+ expect(reloadResult["success"], equals(true));
+
+ await remoteVm.forceGc();
+
+ breakpoint =
+ await findScriptAndBreak(remoteVm, helperFile.uri.toString(), 7);
+ await remoteVm.resume();
+ await waitForScriptToHavePaused(remoteVm);
+ await evaluateExpressions([
+ // 1st expression
+ "s.length",
+ "15",
+
+ // 2nd expression
+ "s",
+ "Hello world!!!!",
+
+ // 3rd expression
+ "hello",
+ "Hello",
+
+ // 4th expression
+ "reloadTime()",
+ "2",
+
+ // 5th expression
+ "helperMethod2()",
+ "21",
+
+ // 6th expression
+ "helperMethod3()",
+ "84",
+ ], remoteVm);
+ await deletePossibleBreakpoint(remoteVm, breakpoint);
+ }
+ });
+ });
+
+ test('from dill with package uri', () async {
+ // 2 iterations: One where the .packages file is deleted, and one where
+ // it is not.
+ for (int i = 0; i < 2; i++) {
+ Directory dir = mytest.createTempSync();
+ File mainFile = new File.fromUri(dir.uri.resolve("main.dart"));
+ mainFile.writeAsStringSync(r"""
+ var hello = "Hello";
+ main() {
+ var s = "$hello world!";
+ print(s);
+ }
+ int extra() { return 22; }
+ """);
+
+ File packagesFile = new File.fromUri(dir.uri.resolve(".packages"));
+ packagesFile.writeAsStringSync("foo:.");
+
+ Uri mainUri = Uri.parse("package:foo/main.dart");
+
+ CompilerOptions optionsModified = getFreshOptions()
+ ..packagesFileUri = packagesFile.uri;
+ IncrementalCompiler compiler =
+ new IncrementalCompiler(optionsModified, mainUri);
+
+ Component component = await compiler.compile();
+ File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
+ IOSink sink = mainDill.openWrite();
+ new BinaryPrinter(sink).writeComponentFile(component);
+ await sink.flush();
+ await sink.close();
+
+ mainFile.deleteSync();
+ if (i == 0) {
+ packagesFile.deleteSync();
+ }
+
+ await launchBreakAndEvaluate(mainDill, mainUri.toString(), 4, [
+ // 1st expression
+ "s.length",
+ "12",
+
+ // 2nd expression
+ "s",
+ "Hello world!",
+
+ // 3rd expression
+ "hello",
+ "Hello",
+
+ // 4th expression
+ "extra()",
+ "22",
+ ]);
+
+ try {
+ dir.deleteSync(recursive: true);
+ } catch (e) {
+ // ignore.
+ }
+ }
+ });
+ });
+}
+
+Future evaluateExpressions(
+ List<String> expressionsAndExpectedResults, RemoteVm remoteVm) async {
+ for (int i = 0; i < expressionsAndExpectedResults.length; i += 2) {
+ String expression = expressionsAndExpectedResults[i];
+ String expectedResult = expressionsAndExpectedResults[i + 1];
+
+ print("Evaluating $expression (expecting $expectedResult)");
+ var result = await remoteVm.evaluateInFrame(expression);
+ expect(result is Map, isTrue);
+ expect(result["type"], equals("@Instance"));
+ expect(result["valueAsString"], equals(expectedResult));
+ }
+}
+
+Future waitForScriptToHavePaused(RemoteVm remoteVm) async {
+ // Wait for the script to have paused.
+ while (true) {
+ Map isolate = await remoteVm.getIsolate();
+ Map pauseEvent = isolate["pauseEvent"];
+ if (pauseEvent["kind"] == "PauseBreakpoint") break;
+ }
+}
+
+Future findScriptAndBreak(
+ RemoteVm remoteVm, String scriptUriToBreakIn, int lineToBreakAt) async {
+ Map scriptsMap = await remoteVm.getScripts();
+ List scripts = scriptsMap["scripts"];
+ String scriptId;
+ for (int i = 0; i < scripts.length; i++) {
+ Map script = scripts[i];
+ String scriptUri = script["uri"];
+ if (scriptUri == scriptUriToBreakIn) {
+ scriptId = script["id"];
+ break;
+ }
+ }
+ expect(scriptId, isNotNull);
+
+ return await remoteVm.addBreakpoint(scriptId, lineToBreakAt);
+}
+
+Future deletePossibleBreakpoint(
+ RemoteVm remoteVm, dynamic possibleBreakpoint) async {
+ if (possibleBreakpoint is Map && possibleBreakpoint["id"] is String) {
+ return await remoteVm.removeBreakpoint(possibleBreakpoint["id"]);
+ }
}
_writeProgramToFile(Component component, File outputFile) async {
final IOSink sink = outputFile.openWrite();
- final BinaryPrinter printer = new LimitedBinaryPrinter(
- sink, (_) => true /* predicate */, false /* excludeUriToSource */);
+ final BinaryPrinter printer = new BinaryPrinter(sink);
printer.writeComponentFile(component);
await sink.flush();
await sink.close();
@@ -903,6 +1367,46 @@
});
}
+ Future addBreakpoint(String scriptId, int line) async {
+ var id = await mainId;
+ return await rpc.sendRequest('addBreakpoint', {
+ 'isolateId': id,
+ 'scriptId': scriptId,
+ 'line': line,
+ });
+ }
+
+ Future removeBreakpoint(String breakpointId) async {
+ var id = await mainId;
+ return await rpc.sendRequest('removeBreakpoint', {
+ 'isolateId': id,
+ 'breakpointId': breakpointId,
+ });
+ }
+
+ Future evaluateInFrame(String expression) async {
+ var id = await mainId;
+ var frameIndex = 0;
+ return await rpc.sendRequest('evaluateInFrame', {
+ 'isolateId': id,
+ "frameIndex": frameIndex,
+ 'expression': expression,
+ });
+ }
+
+ Future forceGc() async {
+ int expectGcAfter = new DateTime.now().millisecondsSinceEpoch;
+ while (true) {
+ var id = await mainId;
+ Map result = await rpc.sendRequest('getAllocationProfile', {
+ 'isolateId': id,
+ "gc": true,
+ });
+ String lastGc = result["dateLastServiceGC"];
+ if (lastGc != null && int.parse(lastGc) >= expectGcAfter) return;
+ }
+ }
+
/// Close any connections used to communicate with the VM.
Future disconnect() async {
if (_rpc == null) return null;
diff --git a/pkg/vm/test/modular_kernel_plus_aot_test.dart b/pkg/vm/test/modular_kernel_plus_aot_test.dart
index d382501..594e11e 100644
--- a/pkg/vm/test/modular_kernel_plus_aot_test.dart
+++ b/pkg/vm/test/modular_kernel_plus_aot_test.dart
@@ -36,21 +36,14 @@
await File.fromUri(mixinFilename).writeAsStringSync(mixinFile);
await compileToKernel(vmTarget, librariesFile, sdkSummary, packagesFile,
- mixinDillFilename, <Uri>[mixinFilename], <Uri>[], <Uri>[]);
+ mixinDillFilename, <Uri>[mixinFilename], <Uri>[]);
final mainFilename = uri.resolve('main.dart');
final mainDillFilename = uri.resolve('main.dart.dill');
await File.fromUri(mainFilename).writeAsStringSync(mainFile);
- await compileToKernel(
- vmTarget,
- librariesFile,
- sdkSummary,
- packagesFile,
- mainDillFilename,
- <Uri>[mainFilename],
- <Uri>[mixinDillFilename],
- <Uri>[]);
+ await compileToKernel(vmTarget, librariesFile, sdkSummary, packagesFile,
+ mainDillFilename, <Uri>[mainFilename], <Uri>[mixinDillFilename]);
final bytes = concat(
await File.fromUri(sdkSummary).readAsBytes(),
@@ -84,15 +77,13 @@
Uri packagesFile,
Uri outputFile,
List<Uri> sources,
- List<Uri> linkedInputs,
- List<Uri> summaryInputs) async {
+ List<Uri> additionalDills) async {
final state = await fe.initializeCompiler(
null,
sdkSummary,
librariesFile,
packagesFile,
- summaryInputs,
- linkedInputs,
+ additionalDills,
target,
StandardFileSystem.instance, const <String>[], const <String, String>{});
diff --git a/pkg/vm/test/transformations/protobuf_aware_treeshaker/treeshaker_test.dart b/pkg/vm/test/transformations/protobuf_aware_treeshaker/treeshaker_test.dart
index 2b2397a..58b77d7 100644
--- a/pkg/vm/test/transformations/protobuf_aware_treeshaker/treeshaker_test.dart
+++ b/pkg/vm/test/transformations/protobuf_aware_treeshaker/treeshaker_test.dart
@@ -7,7 +7,7 @@
import 'package:kernel/target/targets.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/kernel.dart';
-import 'package:kernel/binary/limited_ast_to_binary.dart';
+import 'package:kernel/binary/ast_to_binary.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
@@ -45,8 +45,7 @@
new File('${systemTempDir.path}/${source.pathSegments.last}.dill');
try {
final sink = file.openWrite();
- final printer =
- LimitedBinaryPrinter(sink, (lib) => true, /*excludeUriToSource=*/ true);
+ final printer = BinaryPrinter(sink, includeSources: false);
printer.writeComponentFile(component);
await sink.close();
diff --git a/pkg/vm/test/unlinked_ast_to_text_test.dart b/pkg/vm/test/unlinked_ast_to_text_test.dart
index ee580e2..8b03a2c 100644
--- a/pkg/vm/test/unlinked_ast_to_text_test.dart
+++ b/pkg/vm/test/unlinked_ast_to_text_test.dart
@@ -7,7 +7,7 @@
import 'package:args/args.dart';
import 'package:expect/expect.dart';
import 'package:kernel/kernel.dart';
-import 'package:kernel/binary/limited_ast_to_binary.dart';
+import 'package:kernel/binary/ast_to_binary.dart';
import 'package:vm/kernel_front_end.dart';
main() async {
@@ -44,8 +44,8 @@
// Load the dart2js.dart.dill and write the unlinked version.
final component = loadComponentFromBinary(dillFile);
final IOSink sink = new File(unlinkedDillFile).openWrite();
- final printer = new LimitedBinaryPrinter(
- sink, (lib) => lib.importUri.scheme != 'dart', false);
+ final printer = new BinaryPrinter(sink,
+ libraryFilter: (lib) => lib.importUri.scheme != 'dart');
printer.writeComponentFile(component);
await sink.close();
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 831596f..d015481 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -2060,7 +2060,7 @@
dart.core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- dart.core::int* :async_temporary_0;
+ dynamic :async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
@@ -2068,7 +2068,7 @@
[yield] let dynamic #t2 = dart.async::_awaitHelper(a, :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = dart._internal::unsafeCast<dart.core::int*>(:result);
[yield] let dynamic #t3 = dart.async::_awaitHelper(b, :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :async_temporary_0.{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result));
+ :return_value = dart._internal::unsafeCast<dart.core::int*>(:async_temporary_0).{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result));
break #L3;
}
dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -2092,8 +2092,8 @@
dart.core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
- dart.core::int* :async_temporary_0;
- dart.core::int* :async_temporary_1;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
@@ -2108,7 +2108,7 @@
:async_temporary_1 = sum;
:async_temporary_0 = i.{dart.core::num::+}(j);
[yield] let dynamic #t4 = dart.async::_awaitHelper(#lib::foo(), :async_op_then, :async_op_error, :async_op) in null;
- sum = :async_temporary_1.{dart.core::num::+}(:async_temporary_0.{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result)));
+ sum = dart._internal::unsafeCast<dart.core::int*>(:async_temporary_1).{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:async_temporary_0).{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result)));
}
}
}
@@ -2144,9 +2144,9 @@
dynamic :saved_try_context_var2;
dynamic :exception0;
dynamic :stack_trace0;
- dart.core::int* :async_temporary_0;
- dart.core::int* :async_temporary_1;
- dart.core::int* :async_temporary_2;
+ dynamic :async_temporary_0;
+ dynamic :async_temporary_1;
+ dynamic :async_temporary_2;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L5:
@@ -2156,7 +2156,7 @@
try {
:async_temporary_0 = x;
[yield] let dynamic #t5 = dart.async::_awaitHelper(a, :async_op_then, :async_op_error, :async_op) in null;
- x = :async_temporary_0.{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result));
+ x = dart._internal::unsafeCast<dart.core::int*>(:async_temporary_0).{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result));
}
on dynamic catch(final dynamic e) {
if(e is dart.core::Error*) {
@@ -2165,14 +2165,14 @@
}
:async_temporary_1 = x;
[yield] let dynamic #t6 = dart.async::_awaitHelper(b, :async_op_then, :async_op_error, :async_op) in null;
- x = :async_temporary_1.{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result));
+ x = dart._internal::unsafeCast<dart.core::int*>(:async_temporary_1).{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result));
rethrow;
}
finally {
dart.core::print("fin");
:async_temporary_2 = x;
[yield] let dynamic #t7 = dart.async::_awaitHelper(c, :async_op_then, :async_op_error, :async_op) in null;
- x = :async_temporary_2.{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result));
+ x = dart._internal::unsafeCast<dart.core::int*>(:async_temporary_2).{dart.core::num::+}(dart._internal::unsafeCast<dart.core::int*>(:result));
:return_value = x;
break #L5;
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/abstract_class_entry_point.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/abstract_class_entry_point.dart.expect
index 3864b4c..cbf2f0b 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/abstract_class_entry_point.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/abstract_class_entry_point.dart.expect
@@ -5,4 +5,4 @@
@#C3
abstract class AbstractEmptyClass extends core::Object {
}
-static method main() → dynamic {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → dynamic {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
index a866265..fb1f6ec 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -18,21 +18,21 @@
[@vm.unreachable.metadata=] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] final field self::ParametrizedAnnotation::T* foo;
}
abstract class A extends core::Object {
- static method staticMethod() → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] static method staticMethod() → void {}
}
@#C6
class B extends core::Object {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] @#C8
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] @#C8
method instanceMethod() → void {}
}
-static method foo([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (core::List<core::int*>*) →* void a) → core::int* {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (core::List<core::int*>*) →* void a) → core::int* {
@#C9 core::int* x = 2;
return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] x.{core::num::+}(2);
}
-@#C11
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']@#C11
static method main(core::List<core::String*>* args) → dynamic {
self::A::staticMethod();
[@vm.direct-call.metadata=#lib::B::instanceMethod] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::instanceMethod}();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
index d79868a..052f360 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
import "dart:_internal" as _in;
-static method isPrime([@vm.inferred-type.metadata=int] dynamic n) → core::bool* {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method isPrime([@vm.inferred-type.metadata=int] dynamic n) → core::bool* {
if(_in::unsafeCast<core::bool*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool] n.<(2)))
return false;
for (core::int* i = 2; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<=] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=dart.core::_IntegerImplementation::*] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::*}(i).{core::num::<=}(_in::unsafeCast<core::num*>(n)); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
@@ -12,7 +12,7 @@
}
return true;
}
-static method nThPrimeNumber([@vm.inferred-type.metadata=dart.core::_Smi (value: 50000)] core::int* n) → core::int* {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method nThPrimeNumber([@vm.inferred-type.metadata=dart.core::_Smi (value: 50000)] core::int* n) → core::int* {
core::int* counter = 0;
for (core::int* i = 1; ; i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
if([@vm.inferred-type.metadata=dart.core::bool] self::isPrime(i))
@@ -22,14 +22,14 @@
}
}
}
-static method run() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method run() → void {
core::int* e = 611953;
core::int* p = [@vm.inferred-type.metadata=int?] self::nThPrimeNumber(50000);
if(![@vm.inferred-type.metadata=dart.core::bool] p.{core::num::==}(e)) {
throw core::Exception::•("Unexpected result: ${p} != ${e}");
}
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
core::Stopwatch* timer = let final core::Stopwatch* #t1 = new core::Stopwatch::•() in let final void #t2 = [@vm.direct-call.metadata=dart.core::Stopwatch::start] [@vm.inferred-type.metadata=!? (skip check)] #t1.{core::Stopwatch::start}() in #t1;
for (core::int* i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
self::run();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
index 09996bb..68decfe 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
@@ -9,15 +9,15 @@
[@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] final field core::int* _offset;
[@vm.inferred-type.metadata=dart.core::_Smi (value: 10)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] final field core::int* _length;
[@vm.inferred-type.metadata=dart.typed_data::_Float64List] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8,getterSelectorId:9] final field core::List<core::double*>* _elements;
- constructor •([@vm.inferred-type.metadata=dart.core::_Smi (value: 10)] core::int* size) → self::_Vector*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] constructor •([@vm.inferred-type.metadata=dart.core::_Smi (value: 10)] core::int* size) → self::_Vector*
: self::_Vector::_offset = 0, self::_Vector::_length = size, self::_Vector::_elements = [@vm.inferred-type.metadata=dart.typed_data::_Float64List] typ::Float64List::•(size), super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1] operator []([@vm.inferred-type.metadata=!] core::int* i) → core::double*
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] operator []([@vm.inferred-type.metadata=!] core::int* i) → core::double*
return [@vm.direct-call.metadata=dart.typed_data::_Float64List::[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}([@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] this.{self::_Vector::_offset}));
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2] operator []=([@vm.inferred-type.metadata=dart.core::_OneByteString] core::int* i, core::double* value) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] operator []=([@vm.inferred-type.metadata=dart.core::_OneByteString] core::int* i, core::double* value) → void {
let dynamic #t1 = [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements} in let dynamic #t2 = i in let dynamic #t3 = [@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] this.{self::_Vector::_offset} in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3] operator *([@vm.inferred-type.metadata=#lib::_Vector?] self::_Vector* a) → core::double* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] operator *([@vm.inferred-type.metadata=#lib::_Vector?] self::_Vector* a) → core::double* {
core::double* result = 0.0;
for (core::int* i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}([@vm.direct-call.metadata=#lib::_Vector::_length] [@vm.inferred-type.metadata=dart.core::_Smi (value: 10)] this.{self::_Vector::_length}); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1))
result = [@vm.direct-call.metadata=dart.core::_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] result.{core::double::+}([@vm.direct-call.metadata=dart.core::_Double::*] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=#lib::_Vector::[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] this.{self::_Vector::[]}(i).{core::double::*}([@vm.direct-call.metadata=#lib::_Vector::[]??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] a.{self::_Vector::[]}(i)));
@@ -26,7 +26,7 @@
}
[@vm.inferred-type.metadata=#lib::_Vector?]static field self::_Vector* v = new self::_Vector::•(10);
[@vm.inferred-type.metadata=dart.core::_Double?]static field core::double* x = 0.0;
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
core::Stopwatch* timer = let final core::Stopwatch* #t4 = new core::Stopwatch::•() in let final void #t5 = [@vm.direct-call.metadata=dart.core::Stopwatch::start] [@vm.inferred-type.metadata=!? (skip check)] #t4.{core::Stopwatch::start}() in #t4;
for (core::int* i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100000000); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
self::x = [@vm.direct-call.metadata=dart.core::_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.inferred-type.metadata=dart.core::_Double?] self::x.{core::double::+}([@vm.direct-call.metadata=#lib::_Vector::*??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.inferred-type.metadata=#lib::_Vector?] self::v.{self::_Vector::*}([@vm.inferred-type.metadata=#lib::_Vector?] self::v));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_basic.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_basic.dart.expect
index fd9dd20..6140efa 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_basic.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_basic.dart.expect
@@ -3,44 +3,44 @@
import "dart:core" as core;
class C<T extends core::Object* = dynamic> extends core::Object {
- synthetic constructor •() → self::C<self::C::T*>*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → dynamic
return new self::D::•<self::C::T*>();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method id1([@vm.inferred-type.metadata=#lib::Y (skip check)] generic-covariant-impl self::C::T* x) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method id1([@vm.inferred-type.metadata=#lib::Y (skip check)] generic-covariant-impl self::C::T* x) → dynamic
return x;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method id2([@vm.inferred-type.metadata=#lib::Z] generic-covariant-impl self::C::T* x) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method id2([@vm.inferred-type.metadata=#lib::Z] generic-covariant-impl self::C::T* x) → dynamic
return x;
}
class D<T extends core::Object* = dynamic> extends core::Object {
- synthetic constructor •() → self::D<self::D::T*>*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::D<self::D::T*>*
: super core::Object::•()
;
}
class E<S extends core::Object* = dynamic, T extends core::Object* = dynamic> extends self::C<self::E::T*> {
- synthetic constructor •() → self::E<self::E::S*, self::E::T*>*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::E<self::E::S*, self::E::T*>*
: super self::C::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → dynamic
return [@vm.inferred-type.metadata=#lib::D<dart.core::String*>] super.{self::C::foo}();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method bar() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bar() → dynamic
return new self::D::•<self::E::S*>();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method baz() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method baz() → dynamic
return new self::D::•<self::E::T*>();
}
abstract class X extends core::Object {
- synthetic constructor •() → self::X*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::X*
: super core::Object::•()
;
}
class Y extends self::X {
- synthetic constructor •() → self::Y*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::Y*
: super self::X::•()
;
}
class Z extends self::X {
- synthetic constructor •() → self::Z*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::Z*
: super self::X::•()
;
}
@@ -49,20 +49,20 @@
abstract class J extends self::I<core::int*> {
}
class K<T extends core::Object* = dynamic> extends core::Object {
- synthetic constructor •() → self::K<self::K::T*>*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::K<self::K::T*>*
: super core::Object::•()
;
}
class C2<T extends core::Object* = dynamic> extends core::Object {
- synthetic constructor •() → self::C2<self::C2::T*>*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::C2<self::C2::T*>*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method id3([@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.0)] generic-covariant-impl core::Comparable<self::C2::T*>* x) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method id3([@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.0)] generic-covariant-impl core::Comparable<self::C2::T*>* x) → dynamic
return x;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method id4([@vm.inferred-type.metadata=#lib::K<#lib::J*> (skip check)] generic-covariant-impl self::K<self::I<self::C2::T*>*>* x) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method id4([@vm.inferred-type.metadata=#lib::K<#lib::J*> (skip check)] generic-covariant-impl self::K<self::I<self::C2::T*>*>* x) → dynamic
return x;
}
-static method main() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → dynamic {
core::print([@vm.direct-call.metadata=#lib::C::foo] [@vm.inferred-type.metadata=#lib::D<dart.core::int*> (skip check)] new self::C::•<core::int*>().{self::C::foo}());
core::print([@vm.direct-call.metadata=#lib::E::foo] [@vm.inferred-type.metadata=#lib::D<dart.core::String*> (skip check)] new self::E::•<core::int*, core::String*>().{self::E::foo}());
core::print([@vm.direct-call.metadata=#lib::E::bar] [@vm.inferred-type.metadata=#lib::D<dart.core::int*> (skip check)] new self::E::•<core::int*, core::String*>().{self::E::bar}());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
index 8c4940c..f919630 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
@@ -5,20 +5,20 @@
import "dart:collection";
class Element extends core::Object {
- synthetic constructor •() → self::Element*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::Element*
: super core::Object::•()
;
}
class InheritedElement extends self::Element {
[@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<#lib::Element*, dart.core::Object*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] final field core::Map<self::Element*, core::Object*>* _dependents = <self::Element*, core::Object*>{};
- synthetic constructor •() → self::InheritedElement*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::InheritedElement*
: super self::Element::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method setDependencies([@vm.inferred-type.metadata=!] self::Element* dependent, [@vm.inferred-type.metadata=dart.core::_Smi?] core::Object* value) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method setDependencies([@vm.inferred-type.metadata=!] self::Element* dependent, [@vm.inferred-type.metadata=dart.core::_Smi?] core::Object* value) → void {
[@vm.call-site-attributes.metadata=receiverType:dart.core::Map<#lib::Element*, dart.core::Object*>*] [@vm.direct-call.metadata=dart.collection::__InternalLinkedHashMap&_HashVMBase&MapMixin&_LinkedHashMapMixin::[]=] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::InheritedElement::_dependents] [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<#lib::Element*, dart.core::Object*>] this.{self::InheritedElement::_dependents}.{core::Map::[]=}(dependent, value);
}
}
-static method main() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → dynamic {
self::InheritedElement* ie = new self::InheritedElement::•();
[@vm.direct-call.metadata=#lib::InheritedElement::setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(ie, 0);
[@vm.direct-call.metadata=#lib::InheritedElement::setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(new self::Element::•(), null);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
index 4c84b68..e0f5062 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
@@ -3,53 +3,53 @@
import "dart:core" as core;
class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1] get foo() → core::String*
return "foo";
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3] method getBar() → core::String*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method getBar() → core::String*
return "bar";
}
class B extends core::Object /*isEnum*/ {
[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] final field core::int* index;
[@vm.inferred-type.metadata=dart.core::_OneByteString (value: B.b2)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8,getterSelectorId:9] final field core::String* _name;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] method toString() → core::String*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method toString() → core::String*
return [@vm.inferred-type.metadata=dart.core::_OneByteString (value: B.b2)] this.{=self::B::_name};
}
-static method test0([@vm.inferred-type.metadata=dart.core::_Smi (value: 40)] core::int* arg) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method test0([@vm.inferred-type.metadata=dart.core::_Smi (value: 40)] core::int* arg) → void {
core::print(arg);
}
-static method test1([[@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] core::int* arg = #C1]) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method test1([[@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] core::int* arg = #C1]) → void {
core::print(arg);
}
-static method test2({[@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* arg = #C2}) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method test2({[@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* arg = #C2}) → void {
core::print(arg);
}
static get getD() → dynamic
return 100.0;
-static method testDouble([@vm.inferred-type.metadata=dart.core::_Double (value: 3.14)] core::double* arg) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method testDouble([@vm.inferred-type.metadata=dart.core::_Double (value: 3.14)] core::double* arg) → void {
core::print(arg);
core::print([@vm.inferred-type.metadata=dart.core::_Double (value: 100.0)] self::getD);
}
-static method testStrings([@vm.inferred-type.metadata=#lib::A] self::A* a0, [@vm.inferred-type.metadata=dart.core::_OneByteString (value: bazz)] core::String* a1) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method testStrings([@vm.inferred-type.metadata=#lib::A] self::A* a0, [@vm.inferred-type.metadata=dart.core::_OneByteString (value: bazz)] core::String* a1) → void {
core::print([@vm.direct-call.metadata=#lib::A::foo] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: foo)] a0.{self::A::foo});
core::print([@vm.direct-call.metadata=#lib::A::getBar] [@vm.inferred-type.metadata=dart.core::_OneByteString (skip check) (value: bar)] a0.{self::A::getBar}());
core::print(a1);
}
-static method testPassEnum([@vm.inferred-type.metadata=#lib::B (value: #lib::B {index: 1, #lib::_name: B.b2, })] self::B* arg) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method testPassEnum([@vm.inferred-type.metadata=#lib::B (value: #lib::B {index: 1, #lib::_name: B.b2, })] self::B* arg) → void {
self::testPassEnum2(arg);
}
-static method testPassEnum2([@vm.inferred-type.metadata=#lib::B (value: #lib::B {index: 1, #lib::_name: B.b2, })] self::B* arg) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method testPassEnum2([@vm.inferred-type.metadata=#lib::B (value: #lib::B {index: 1, #lib::_name: B.b2, })] self::B* arg) → void {
core::print(arg);
}
-static method getList() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getList() → dynamic
return #C6;
-static method testList([@vm.inferred-type.metadata=dart.core::_ImmutableList (value: ListConstant<dart.core::int*>([1, 2, 3]))] dynamic arg1, [[@vm.inferred-type.metadata=dart.core::_ImmutableList (value: ListConstant<dart.core::int*>([4, 5]))] dynamic arg2 = #C9]) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method testList([@vm.inferred-type.metadata=dart.core::_ImmutableList (value: ListConstant<dart.core::int*>([1, 2, 3]))] dynamic arg1, [[@vm.inferred-type.metadata=dart.core::_ImmutableList (value: ListConstant<dart.core::int*>([4, 5]))] dynamic arg2 = #C9]) → void {
core::print(arg1);
core::print(arg2);
}
-static method main() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → dynamic {
self::test0(40);
self::test1();
self::test2();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
index 1469023..087a1100 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -3,58 +3,58 @@
import "dart:core" as core;
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → core::int*;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → core::int*
return 1;
}
class C extends core::Object implements self::A {
- synthetic constructor •() → self::C*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::C*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → core::int*
return 2;
}
class D extends self::C {
- synthetic constructor •() → self::D*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::D*
: super self::C::•()
;
}
class E extends core::Object {
- synthetic constructor •() → self::E*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::E*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method toString() → core::String*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method toString() → core::String*
return "D";
}
[@vm.inferred-type.metadata=#lib::D?]static field self::A* dd;
[@vm.inferred-type.metadata=#lib::E?]static field self::E* ee = new self::E::•();
-static method callerA1([@vm.inferred-type.metadata=!] self::A* aa) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method callerA1([@vm.inferred-type.metadata=!] self::A* aa) → void {
[@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
-static method callerA2([@vm.inferred-type.metadata=#lib::B] self::A* aa) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method callerA2([@vm.inferred-type.metadata=#lib::B] self::A* aa) → void {
[@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
-static method callerA3({[@vm.inferred-type.metadata=#lib::C] self::A* aa = #C1}) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method callerA3({[@vm.inferred-type.metadata=#lib::C] self::A* aa = #C1}) → void {
[@vm.direct-call.metadata=#lib::C::foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
-static method callerA4([@vm.inferred-type.metadata=#lib::D?] self::A* aa) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method callerA4([@vm.inferred-type.metadata=#lib::D?] self::A* aa) → void {
[@vm.direct-call.metadata=#lib::C::foo??] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
-static method callerE1([@vm.inferred-type.metadata=dart.core::_OneByteString (value: abc)] dynamic x) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method callerE1([@vm.inferred-type.metadata=dart.core::_OneByteString (value: abc)] dynamic x) → void {
[@vm.direct-call.metadata=dart.core::_StringBase::toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)] x.{core::Object::toString}();
}
-static method callerE2([@vm.inferred-type.metadata=#lib::E?] dynamic x) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method callerE2([@vm.inferred-type.metadata=#lib::E?] dynamic x) → void {
[@vm.inferred-type.metadata=!? (receiver not int)] x.{core::Object::toString}();
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
self::callerA1(new self::B::•());
self::callerA1(new self::C::•());
self::callerA2(new self::B::•());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart.expect
index 2f98a40..fbd47a2 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/dynamic_list_access.dart.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-static method main() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → dynamic {
dynamic x = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::•<core::int*>(10);
[@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.direct-call.metadata=dart.core::_List::[]] [@vm.inferred-type.metadata=int? (receiver not int)] x.[](0).+(10);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect
index be83db0..0714c99 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect
@@ -6,21 +6,21 @@
import "dart:async";
class C<T extends core::Object* = dynamic> extends core::Object {
- synthetic constructor •() → self::C<self::C::T*>*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method test2c([@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] generic-covariant-impl asy::FutureOr<self::C::T*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method test3c([@vm.inferred-type.metadata=dart.async::_Future<dart.core::int*> (skip check)] generic-covariant-impl asy::Future<self::C::T*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method test4c([@vm.inferred-type.metadata=dart.async::_Future<dart.core::int*> (skip check)] generic-covariant-impl asy::FutureOr<self::C::T*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method test2r([@vm.inferred-type.metadata=#lib::C<dart.core::int*> (skip check)] generic-covariant-impl self::C<asy::FutureOr<self::C::T*>*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method test3r([@vm.inferred-type.metadata=#lib::C<dart.async::Future<dart.core::int*>*> (skip check)] generic-covariant-impl self::C<asy::Future<self::C::T*>*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method test4r([@vm.inferred-type.metadata=#lib::C<dart.async::Future<dart.core::int*>*> (skip check)] generic-covariant-impl self::C<asy::FutureOr<self::C::T*>*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method test5r([@vm.inferred-type.metadata=#lib::C<dart.async::FutureOr<dart.core::int*>*>] generic-covariant-impl self::C<asy::Future<self::C::T*>*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method test6r([@vm.inferred-type.metadata=#lib::C<dart.async::FutureOr<dart.core::int*>*> (skip check)] generic-covariant-impl self::C<asy::FutureOr<self::C::T*>*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method test7r([@vm.inferred-type.metadata=#lib::C<dart.async::FutureOr<dart.core::int*>*>] generic-covariant-impl self::C<self::C::T*>* x) → void {}
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method test8r([@vm.inferred-type.metadata=#lib::C<dart.async::Future<dart.core::int*>*>] generic-covariant-impl self::C<self::C::T*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test2c([@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] generic-covariant-impl asy::FutureOr<self::C::T*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test3c([@vm.inferred-type.metadata=dart.async::_Future<dart.core::int*> (skip check)] generic-covariant-impl asy::Future<self::C::T*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test4c([@vm.inferred-type.metadata=dart.async::_Future<dart.core::int*> (skip check)] generic-covariant-impl asy::FutureOr<self::C::T*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test2r([@vm.inferred-type.metadata=#lib::C<dart.core::int*> (skip check)] generic-covariant-impl self::C<asy::FutureOr<self::C::T*>*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test3r([@vm.inferred-type.metadata=#lib::C<dart.async::Future<dart.core::int*>*> (skip check)] generic-covariant-impl self::C<asy::Future<self::C::T*>*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test4r([@vm.inferred-type.metadata=#lib::C<dart.async::Future<dart.core::int*>*> (skip check)] generic-covariant-impl self::C<asy::FutureOr<self::C::T*>*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test5r([@vm.inferred-type.metadata=#lib::C<dart.async::FutureOr<dart.core::int*>*>] generic-covariant-impl self::C<asy::Future<self::C::T*>*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test6r([@vm.inferred-type.metadata=#lib::C<dart.async::FutureOr<dart.core::int*>*> (skip check)] generic-covariant-impl self::C<asy::FutureOr<self::C::T*>*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test7r([@vm.inferred-type.metadata=#lib::C<dart.async::FutureOr<dart.core::int*>*>] generic-covariant-impl self::C<self::C::T*>* x) → void {}
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method test8r([@vm.inferred-type.metadata=#lib::C<dart.async::Future<dart.core::int*>*>] generic-covariant-impl self::C<self::C::T*>* x) → void {}
}
-static method main() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → dynamic {
dynamic c = new self::C::•<core::int*>();
[@vm.direct-call.metadata=#lib::C::test2c] [@vm.inferred-type.metadata=!? (receiver not int)] c.test2c(3);
[@vm.direct-call.metadata=#lib::C::test3c] [@vm.inferred-type.metadata=!? (receiver not int)] c.test3c([@vm.inferred-type.metadata=dart.async::_Future<dart.core::int*>] asy::Future::value<core::int*>(3));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
index d7385b2..fb078b8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
@@ -6,39 +6,39 @@
import "dart:async";
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super self::A::•()
;
}
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method foo1_a1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {}
-static method foo1_a2([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {}
-static method foo1_a3([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {}
-static method foo1_a4([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {}
-static method foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::Future<self::A*>* a1, [@vm.inferred-type.metadata=#lib::B] self::A* a2, [@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::FutureOr<self::A*>* a3, [@vm.inferred-type.metadata=#lib::B] asy::FutureOr<self::A*>* a4) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo1_a1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo1_a2([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo1_a3([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo1_a4([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::Future<self::A*>* a1, [@vm.inferred-type.metadata=#lib::B] self::A* a2, [@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::FutureOr<self::A*>* a3, [@vm.inferred-type.metadata=#lib::B] asy::FutureOr<self::A*>* a4) → void {
self::foo1_a1(a1);
self::foo1_a2(a2);
self::foo1_a3(a3);
self::foo1_a4(a4);
}
-static method foo2_a1([@vm.inferred-type.metadata=dart.async::_Future?] dynamic x) → void {}
-static method foo2_a2([@vm.inferred-type.metadata=#lib::B?] dynamic x) → void {}
-static method foo2_a3(dynamic x) → void {}
-static method foo2_a4(dynamic x) → void {}
-static method foo2([@vm.inferred-type.metadata=dart.async::_Future?] asy::Future<self::A*>* a1, [@vm.inferred-type.metadata=#lib::B?] self::A* a2, asy::FutureOr<self::A*>* a3, asy::FutureOr<self::A*>* a4) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo2_a1([@vm.inferred-type.metadata=dart.async::_Future?] dynamic x) → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo2_a2([@vm.inferred-type.metadata=#lib::B?] dynamic x) → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo2_a3(dynamic x) → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo2_a4(dynamic x) → void {}
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo2([@vm.inferred-type.metadata=dart.async::_Future?] asy::Future<self::A*>* a1, [@vm.inferred-type.metadata=#lib::B?] self::A* a2, asy::FutureOr<self::A*>* a3, asy::FutureOr<self::A*>* a4) → void {
self::foo2_a1(a1);
self::foo2_a2(a2);
self::foo2_a3(a3);
self::foo2_a4(a4);
}
-static method getDynamic() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call();
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
self::foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::Future::value<self::B*>(new self::B::•()), new self::B::•(), [@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::Future::value<self::B*>(new self::B::•()), new self::B::•());
self::foo2(self::getDynamic() as{TypeError,ForDynamic} asy::Future<self::A*>*, self::getDynamic() as{TypeError,ForDynamic} self::A*, self::getDynamic() as{TypeError,ForDynamic} asy::FutureOr<self::A*>*, self::getDynamic() as{TypeError,ForDynamic} asy::FutureOr<self::A*>*);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart.expect
index 2296f5b..63026c8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart.expect
@@ -3,12 +3,12 @@
import "dart:core" as core;
class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
}
-static method foo() → core::Object*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo() → core::Object*
return new self::A::•();
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
core::print([@vm.inferred-type.metadata=#lib::A] self::foo());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
index 5226932..2d5e9ca 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
@@ -3,100 +3,100 @@
import "dart:core" as core;
abstract class StreamSubscription extends core::Object {
- synthetic constructor •() → self::StreamSubscription*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::StreamSubscription*
: super core::Object::•()
;
}
class _BufferingStreamSubscription extends self::StreamSubscription {
- synthetic constructor •() → self::_BufferingStreamSubscription*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::_BufferingStreamSubscription*
: super self::StreamSubscription::•()
;
}
class _BroadcastSubscription extends self::StreamSubscription {
- synthetic constructor •() → self::_BroadcastSubscription*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::_BroadcastSubscription*
: super self::StreamSubscription::•()
;
}
abstract class Stream extends core::Object {
- synthetic constructor •() → self::Stream*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::Stream*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foobar((dynamic) →* void onData, {core::Function* onError = #C1}) → self::StreamSubscription*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foobar((dynamic) →* void onData, {core::Function* onError = #C1}) → self::StreamSubscription*;
}
abstract class _StreamImpl extends self::Stream {
- synthetic constructor •() → self::_StreamImpl*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::_StreamImpl*
: super self::Stream::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foobar([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → self::StreamSubscription* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foobar([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → self::StreamSubscription* {
return [@vm.inferred-type.metadata=! (skip check)] this.{self::_StreamImpl::_createSubscription}();
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method _createSubscription() → self::StreamSubscription* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method _createSubscription() → self::StreamSubscription* {
return new self::_BufferingStreamSubscription::•();
}
}
class _ControllerStream extends self::_StreamImpl {
- synthetic constructor •() → self::_ControllerStream*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::_ControllerStream*
: super self::_StreamImpl::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method _createSubscription() → self::StreamSubscription* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method _createSubscription() → self::StreamSubscription* {
return new self::_BroadcastSubscription::•();
}
}
class _GeneratedStreamImpl extends self::_StreamImpl {
- synthetic constructor •() → self::_GeneratedStreamImpl*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::_GeneratedStreamImpl*
: super self::_StreamImpl::•()
;
}
abstract class StreamView extends self::Stream {
[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] final field self::Stream* _stream;
- constructor •([@vm.inferred-type.metadata=!] self::Stream* stream) → self::StreamView*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] constructor •([@vm.inferred-type.metadata=!] self::Stream* stream) → self::StreamView*
: self::StreamView::_stream = stream, super self::Stream::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foobar([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → self::StreamSubscription* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foobar([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData, {[@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → self::StreamSubscription* {
return [@vm.direct-call.metadata=#lib::StreamView::_stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}.{self::Stream::foobar}(onData, onError: onError);
}
}
class ByteStream extends self::StreamView {
- constructor •([@vm.inferred-type.metadata=!] self::Stream* stream) → self::ByteStream*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] constructor •([@vm.inferred-type.metadata=!] self::Stream* stream) → self::ByteStream*
: super self::StreamView::•(stream)
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method super_foobar1([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method super_foobar1([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData) → dynamic {
super.{self::StreamView::foobar}(onData);
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method super_foobar2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method super_foobar2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData) → dynamic {
super.{self::StreamView::foobar}(onData);
}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method super_foobar3({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method super_foobar3({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → dynamic {
super.{self::StreamView::foobar}(onData, onError: onError);
}
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:13] get super_stream() → self::Stream*
return [@vm.inferred-type.metadata=!] super.{self::StreamView::_stream};
}
class _HandleErrorStream extends self::Stream {
- synthetic constructor •() → self::_HandleErrorStream*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::_HandleErrorStream*
: super self::Stream::•()
;
}
-static method round0() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method round0() → void {
new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
}
-static method round1({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1}) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method round1({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1}) → void {
self::ByteStream* x = new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
[@vm.direct-call.metadata=#lib::ByteStream::super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}(onData);
}
-static method round2({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method round2({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → void {
new self::_ControllerStream::•();
self::Stream* x = new self::_GeneratedStreamImpl::•();
x = new self::ByteStream::•(x);
[@vm.direct-call.metadata=#lib::StreamView::foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(onData, onError: onError);
}
-static method round3({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method round3({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → void {
self::Stream* x = new self::_GeneratedStreamImpl::•();
x = new self::ByteStream::•(x);
x = new self::_ControllerStream::•();
[@vm.direct-call.metadata=#lib::_StreamImpl::foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(onData, onError: onError);
}
-static method round4({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1}) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method round4({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1}) → void {
self::ByteStream* x = new self::ByteStream::•(new self::_ControllerStream::•());
self::Stream* y = [@vm.direct-call.metadata=#lib::ByteStream::super_stream] [@vm.inferred-type.metadata=!] x.{self::ByteStream::super_stream};
self::Stream* z = [@vm.direct-call.metadata=#lib::StreamView::_stream] [@vm.inferred-type.metadata=!] x.{self::StreamView::_stream};
@@ -104,12 +104,12 @@
[@vm.direct-call.metadata=#lib::ByteStream::super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}(onData);
}
}
-static method round5() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method round5() → void {
self::ByteStream* x = new self::ByteStream::•(new self::_GeneratedStreamImpl::•());
new self::_HandleErrorStream::•();
[@vm.direct-call.metadata=#lib::ByteStream::super_foobar3] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar3}();
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
new self::_GeneratedStreamImpl::•();
self::round0();
self::round1();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
index 6d5cf67..d5ff659 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
@@ -3,80 +3,80 @@
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super core::Object::•()
;
}
abstract class A extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → core::Object*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → core::Object*;
}
class B extends core::Object implements self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::Object*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → core::Object*
return new self::T1::•();
}
class C extends core::Object implements self::A {
- synthetic constructor •() → self::C*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::C*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::Object*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → core::Object*
return new self::T2::•();
}
class DeepCaller1 extends core::Object {
- synthetic constructor •() → self::DeepCaller1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::DeepCaller1*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method barL1() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL1() → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1::barL2] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL2}();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL2() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL2() → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1::barL3] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL3}();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL3() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL3() → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1::barL4] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL4}();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL4() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL4() → dynamic
return self::field1;
}
class D extends core::Object {
[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] field core::Object* field2 = [@vm.inferred-type.metadata=!] self::getValue();
- synthetic constructor •() → self::D*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::D*
: super core::Object::•()
;
}
class DeepCaller2 extends core::Object {
- synthetic constructor •() → self::DeepCaller2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::DeepCaller2*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method barL1([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL1([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2::barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(dd);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL2([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL2([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2::barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(dd);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL3([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL3([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2::barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(dd);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL4([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL4([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
return [@vm.direct-call.metadata=#lib::D::field2] [@vm.inferred-type.metadata=!] dd.{self::D::field2};
}
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
static field core::Object* field1 = [@vm.inferred-type.metadata=!] self::getValue();
-static method getDynamic() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call();
-static method getValue() → core::Object* {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getValue() → core::Object* {
self::A* aa = self::getDynamic() as{TypeError,ForDynamic} self::A*;
return [@vm.inferred-type.metadata=!] aa.{self::A::foo}();
}
-static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1* x) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1* x) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1::barL1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::DeepCaller1::barL1}();
-static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2* x) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2* x) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2::barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(new self::D::•());
-static method createC() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method createC() → dynamic {
new self::C::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
new self::B::•();
self::use1(new self::DeepCaller1::•());
self::use2(new self::DeepCaller2::•());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
index 95c4d00..0c1a531 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
@@ -3,41 +3,41 @@
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
}
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → dynamic;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → dynamic
return new self::T1::•();
}
class Intermediate extends core::Object {
- synthetic constructor •() → self::Intermediate*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::Intermediate*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar([@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bar([@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::B::foo??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] aa.{self::A::foo}();
}
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method use1([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, [@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use1([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, [@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa);
-static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, [@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, [@vm.inferred-type.metadata=#lib::B?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa);
-static method getDynamic() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call();
-static method allocateB() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method allocateB() → dynamic {
new self::B::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
self::allocateB();
self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
index 6149267..145cb92 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
@@ -3,70 +3,70 @@
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super core::Object::•()
;
}
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → dynamic;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → dynamic
return new self::T1::•();
}
abstract class C extends core::Object implements self::B {
}
abstract class D extends core::Object {
- synthetic constructor •() → self::D*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::D*
: super core::Object::•()
;
}
abstract class _E&D&C extends self::D implements self::C /*isAnonymousMixin,isEliminatedMixin*/ {
- synthetic constructor •() → self::_E&D&C*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::_E&D&C*
: super self::D::•()
;
}
class E extends self::_E&D&C {
- synthetic constructor •() → self::E*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::E*
: super self::_E&D&C::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → dynamic
return new self::T2::•();
}
class Intermediate extends core::Object {
- synthetic constructor •() → self::Intermediate*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::Intermediate*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar(self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bar(self::A* aa) → dynamic
return [@vm.inferred-type.metadata=!] aa.{self::A::foo}();
}
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method use1([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use1([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa);
-static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa);
-static method use3([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use3([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate* i, self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa);
-static method getDynamic() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call();
-static method allocateB() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method allocateB() → dynamic {
new self::B::•();
}
-static method allocateE() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method allocateE() → dynamic {
new self::E::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
self::allocateB();
self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError,ForDynamic} self::A*);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
index c86de6e..e950fb6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
@@ -3,60 +3,60 @@
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super core::Object::•()
;
}
class T3 extends core::Object {
- synthetic constructor •() → self::T3*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T3*
: super core::Object::•()
;
}
class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → dynamic
return new self::T1::•();
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar() → dynamic
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bar() → dynamic
return new self::T2::•();
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method bazz() → dynamic
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bazz() → dynamic
return new self::T3::•();
}
class B extends core::Object {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → dynamic
return new self::T1::•();
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar() → dynamic
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bar() → dynamic
return new self::T2::•();
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method bazz() → dynamic
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bazz() → dynamic
return new self::T3::•();
}
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method use_foo1(dynamic x) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use_foo1(dynamic x) → dynamic
return [@vm.inferred-type.metadata=#lib::T1] x.foo();
-static method use_foo2(dynamic x) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use_foo2(dynamic x) → dynamic
return [@vm.inferred-type.metadata=#lib::T1] x.foo();
-static method use_bar(dynamic x) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use_bar(dynamic x) → dynamic
return [@vm.inferred-type.metadata=#lib::T2] x.bar();
-static method use_bazz(dynamic x) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use_bazz(dynamic x) → dynamic
return [@vm.inferred-type.metadata=#lib::T3] x.bazz();
-static method getDynamic() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call();
-static method allocateA() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method allocateA() → dynamic {
new self::A::•();
}
-static method allocateB() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method allocateB() → dynamic {
new self::B::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
self::use_foo1(self::getDynamic());
self::allocateA();
self::use_foo2(self::getDynamic());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
index 6698bb7..6cc04be 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
@@ -3,59 +3,59 @@
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super core::Object::•()
;
}
class A extends core::Object {
[@vm.inferred-type.metadata=#lib::T1] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] field dynamic field1 = new self::T1::•();
[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field dynamic field2 = new self::T1::•();
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
}
class DeepCaller1 extends core::Object {
- synthetic constructor •() → self::DeepCaller1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::DeepCaller1*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1::barL2] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL2}(aa);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1::barL3] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL3}(aa);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1::barL4] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL4}(aa);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::A::field1??] [@vm.inferred-type.metadata=#lib::T1] aa.{self::A::field1};
}
class DeepCaller2 extends core::Object {
- synthetic constructor •() → self::DeepCaller2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::DeepCaller2*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2::barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(aa);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2::barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(aa);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2::barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(aa);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::A::field2??] [@vm.inferred-type.metadata=!] aa.{self::A::field2};
}
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1* x, [@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1* x, [@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller1::barL1] [@vm.inferred-type.metadata=#lib::T1 (skip check)] x.{self::DeepCaller1::barL1}(aa);
-static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2* x, [@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2* x, [@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
return [@vm.direct-call.metadata=#lib::DeepCaller2::barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(aa);
-static method getDynamic() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call();
-static method setField2([@vm.inferred-type.metadata=#lib::A] self::A* aa, [@vm.inferred-type.metadata=#lib::T2] dynamic value) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method setField2([@vm.inferred-type.metadata=#lib::A] self::A* aa, [@vm.inferred-type.metadata=#lib::T2] dynamic value) → void {
[@vm.direct-call.metadata=#lib::A::field2] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::field2} = value;
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
new self::A::•();
new self::T1::•();
new self::T2::•();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
index 9372e70..4ed4d6c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
@@ -3,40 +3,40 @@
import "dart:core" as core;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method go() → self::T3*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method go() → self::T3*
return new self::T3::•();
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super core::Object::•()
;
}
class T3 extends core::Object {
- synthetic constructor •() → self::T3*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T3*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method run() → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method run() → dynamic {
core::print("hi");
}
}
class Q<T extends core::Object* = dynamic> extends core::Object {
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] final field self::Q::T* result;
- constructor •(self::Q::T* result) → self::Q<self::Q::T*>*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] constructor •(self::Q::T* result) → self::Q<self::Q::T*>*
: self::Q::result = result, super core::Object::•()
;
}
-static method foo1([@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::T1*>] core::List<self::T1*>* list) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo1([@vm.inferred-type.metadata=dart.core::_GrowableList<#lib::T1*>] core::List<self::T1*>* list) → dynamic {
[@vm.direct-call.metadata=#lib::T3::run] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::T1::go??] [@vm.inferred-type.metadata=#lib::T3 (skip check)] [@vm.direct-call.metadata=#lib::Q::result??] [@vm.direct-call.metadata=dart._internal::ListIterable::first] [@vm.inferred-type.metadata=#lib::Q?] [@vm.direct-call.metadata=dart.collection::_ListBase&Object&ListMixin::map] [@vm.inferred-type.metadata=dart._internal::MappedListIterable<#lib::T1*, ?> (skip check)] list.{core::Iterable::map}<self::Q<self::T1*>*>((self::T1* t1) → self::Q<self::T1*>* => new self::Q::•<self::T1*>(t1)).{core::Iterable::first}.{self::Q::result}.{self::T1::go}().{self::T3::run}();
}
-static method foo2NewValue() → self::Q<dynamic>*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo2NewValue() → self::Q<dynamic>*
return new self::Q::•<self::T2*>(new self::T2::•());
-static method foo3NewT1() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo3NewT1() → dynamic {
new self::T1::•();
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
self::foo1(<self::T1*>[]);
self::foo2NewValue();
self::foo3NewT1();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
index 3390a91..bb8ca0f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
@@ -3,34 +3,34 @@
import "dart:core" as core;
abstract class I extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → void;
}
class T1 extends core::Object implements self::I {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → void {}
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → void {}
}
class T2 extends core::Object implements self::I {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → void {}
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → void {}
}
class Point extends core::Object /*hasConstConstructor*/ {
[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] final field self::I* x;
- const constructor •([@vm.inferred-type.metadata=!] self::I* x) → self::Point*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] const constructor •([@vm.inferred-type.metadata=!] self::I* x) → self::Point*
: self::Point::x = x, super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method newPoint1() → self::Point*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method newPoint1() → self::Point*
return new self::Point::•([@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method newPoint2() → self::Point*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method newPoint2() → self::Point*
return new self::Point::•([@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
}
-static method getX([@vm.inferred-type.metadata=#lib::Point] dynamic point) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getX([@vm.inferred-type.metadata=#lib::Point] dynamic point) → dynamic {
[@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!? (receiver not int)] point.x;
}
-static method main() → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → dynamic {
self::Point* a = new self::Point::•(new self::T1::•());
core::print([@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] a.{self::Point::x});
self::Point* c = new self::Point::•(new self::T2::•());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index fa129ad..d8952be 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -4,118 +4,118 @@
import "dart:_internal" as _in;
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super core::Object::•()
;
}
class T4 extends core::Object {
- synthetic constructor •() → self::T4*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T4*
: super core::Object::•()
;
}
class T5 extends core::Object {
- synthetic constructor •() → self::T5*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T5*
: super core::Object::•()
;
}
class T6 extends core::Object {
- synthetic constructor •() → self::T6*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T6*
: super core::Object::•()
;
}
class T7 extends core::Object {
- synthetic constructor •() → self::T7*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T7*
: super core::Object::•()
;
}
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → dynamic;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] abstract get bar() → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] abstract method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4 = #C1, dynamic a5 = #C1]) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4 = #C1, dynamic a5 = #C1]) → dynamic;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method noSuchMethod(core::Invocation* invocation) → dynamic {
return new self::T1::•();
}
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] no-such-method-forwarder get bar() → dynamic
return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] no-such-method-forwarder method foo() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] no-such-method-forwarder method foo() → dynamic
return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic a5 = #C1]) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic a5 = #C1]) → dynamic
return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
}
abstract class C extends core::Object {
- synthetic constructor •() → self::C*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::C*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method noSuchMethod(core::Invocation* invocation) → dynamic {
return new self::T2::•();
}
}
class D extends self::C implements self::A {
- synthetic constructor •() → self::D*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::D*
: super self::C::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] no-such-method-forwarder get bar() → dynamic
return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] no-such-method-forwarder method foo() → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] no-such-method-forwarder method foo() → dynamic
return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic a5 = #C1]) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic a5 = #C1]) → dynamic
return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
}
class E extends core::Object implements self::A {
- synthetic constructor •() → self::E*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::E*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method noSuchMethod(core::Invocation* invocation) → dynamic {
return new self::T4::•();
}
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3] no-such-method-forwarder get bar() → dynamic
return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::E::noSuchMethod] [@vm.inferred-type.metadata=#lib::T4 (skip check)] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
}
class F extends core::Object {
- synthetic constructor •() → self::F*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::F*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method noSuchMethod(core::Invocation* invocation) → dynamic {
return new self::T2::•();
}
}
class G extends core::Object {
- synthetic constructor •() → self::G*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::G*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method noSuchMethod(core::Invocation* invocation) → dynamic {
return new self::T5::•();
}
}
class H extends core::Object {
- synthetic constructor •() → self::H*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::H*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo({[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic left = #C1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic right = #C1}) → dynamic
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo({[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic left = #C1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic right = #C1}) → dynamic
return new self::T6::•();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method noSuchMethod(core::Invocation* invocation) → dynamic {
return new self::T7::•();
}
}
[@vm.inferred-type.metadata=#lib::B?]static field self::A* bb = new self::B::•();
[@vm.inferred-type.metadata=#lib::D?]static field self::A* dd = new self::D::•();
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method getDynamic() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call();
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
core::print([@vm.direct-call.metadata=#lib::B::foo??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::foo}());
core::print([@vm.direct-call.metadata=#lib::B::bar??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bar});
core::print([@vm.direct-call.metadata=#lib::B::bazz??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bazz}(1, 2, 3, 4));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
index 0378cce..f28ccae 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
@@ -3,56 +3,56 @@
import "dart:core" as core;
abstract class T0 extends core::Object {
- synthetic constructor •() → self::T0*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T0*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → void;
}
class T2 extends self::T0 {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super self::T0::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → void {}
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → void {}
}
class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method method1(self::T0* t0) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method method1(self::T0* t0) → void {
[@vm.direct-call.metadata=#lib::T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
}
abstract class B extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] abstract method method2(covariant dynamic arg) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method method2(covariant dynamic arg) → void;
}
class C extends core::Object implements self::B {
- synthetic constructor •() → self::C*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::C*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method method2(covariant self::T0* t0) → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method method2(covariant self::T0* t0) → void {
[@vm.direct-call.metadata=#lib::T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
}
class D extends core::Object {
- synthetic constructor •() → self::D*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::D*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method method3(self::T0* t0) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method method3(self::T0* t0) → void {
[@vm.direct-call.metadata=#lib::T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
}
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method func1([@vm.inferred-type.metadata=#lib::T2?] self::T0* t0) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method func1([@vm.inferred-type.metadata=#lib::T2?] self::T0* t0) → void {
[@vm.direct-call.metadata=#lib::T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
-static method func2(self::T0* t0) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method func2(self::T0* t0) → void {
[@vm.direct-call.metadata=#lib::T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
-static method getDynamic() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call();
-static method use(dynamic x) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method use(dynamic x) → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown.call(x);
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
self::func1(self::getDynamic() as{TypeError,ForDynamic} self::T0*);
self::use(#C1);
self::use(new self::A::•().{self::A::method1});
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_37455.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_37455.dart.expect
index a7ca2b5..37be74f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_37455.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_37455.dart.expect
@@ -4,17 +4,17 @@
class A extends core::Object {
[@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] final field core::List<dynamic>* afield;
- constructor •([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::List<dynamic>* afield) → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] constructor •([@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] core::List<dynamic>* afield) → self::A*
: self::A::afield = afield, super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method toString() → core::String*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method toString() → core::String*
return [@vm.direct-call.metadata=dart.core::_GrowableList::toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)] [@vm.direct-call.metadata=#lib::A::afield] [@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic>] this.{self::A::afield}.{core::Object::toString}();
}
class B extends core::Object {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method _foo([@vm.inferred-type.metadata=dart._internal::ListIterator<dart.core::int*>] core::Iterator<core::int*>* iter) → core::List<dynamic>* {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method _foo([@vm.inferred-type.metadata=dart._internal::ListIterator<dart.core::int*>] core::Iterator<core::int*>* iter) → core::List<dynamic>* {
core::List<dynamic>* result = <dynamic>[];
while ([@vm.direct-call.metadata=dart._internal::ListIterator::moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] iter.{core::Iterator::moveNext}()) {
if([@vm.direct-call.metadata=dart.core::_IntegerImplementation::<??] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=dart._internal::ListIterator::current] [@vm.inferred-type.metadata=int?] iter.{core::Iterator::current}.{core::num::<}(0)) {
@@ -25,7 +25,7 @@
return result;
}
}
-static method main() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → void {
core::List<dynamic>* list = [@vm.direct-call.metadata=#lib::B::_foo] [@vm.inferred-type.metadata=dart.core::_GrowableList<dynamic> (skip check)] new self::B::•().{self::B::_foo}([@vm.direct-call.metadata=dart.core::_GrowableList::iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<dart.core::int*>]<core::int*>[1, 2, 3].{core::Iterable::iterator});
core::print(list);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_37719.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_37719.dart.expect
index 2cbbfed..823e781 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_37719.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_37719.dart.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-static method foo([@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::List<core::int*>* x) → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method foo([@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::List<core::int*>* x) → dynamic
return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=dart.core::_GrowableList::[]] [@vm.inferred-type.metadata=int? (skip check)] x.{core::List::[]}(0));
-static method main() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → dynamic
return [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::print([@vm.inferred-type.metadata=int] self::foo(<core::int*>[1]));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
index ab1a24e..ce77fcd 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
@@ -7,104 +7,104 @@
import "package:expect/expect.dart";
class T1 extends core::Object {
- synthetic constructor •() → self::T1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T1*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method doTest1() → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method doTest1() → void {
self::ok = true;
}
}
class A1 extends core::Object {
[@vm.inferred-type.metadata=#lib::T1?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field self::T1* foo = null;
- synthetic constructor •() → self::A1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A1*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = #C1]) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A1::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A1::foo} = _in::unsafeCast<self::T1*>(a5);
}
}
class B1 extends core::Object {
[@vm.inferred-type.metadata=#lib::A1] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] field self::A1* aa1 = new self::A1::•();
- synthetic constructor •() → self::B1*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B1*
: super core::Object::•()
;
}
class T2 extends core::Object {
- synthetic constructor •() → self::T2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T2*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method doTest2() → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method doTest2() → void {
self::ok = true;
}
}
class A2 extends core::Object {
[@vm.inferred-type.metadata=#lib::T2?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field dynamic foo = null;
- synthetic constructor •() → self::A2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A2*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = #C1]) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A2::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A2::foo} = a6;
}
}
abstract class B2Base extends core::Object {
[@vm.inferred-type.metadata=#lib::A2] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:12,getterSelectorId:13] field dynamic _aa = new self::A2::•();
- synthetic constructor •() → self::B2Base*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B2Base*
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:11] get aa2() → dynamic
return [@vm.direct-call.metadata=#lib::B2Base::_aa] [@vm.inferred-type.metadata=#lib::A2] this.{self::B2Base::_aa};
}
class B2 extends self::B2Base {
- synthetic constructor •() → self::B2*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B2*
: super self::B2Base::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:14,getterSelectorId:15] method doSuperCall() → void {
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:14,getterSelectorId:15] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method doSuperCall() → void {
[@vm.call-site-attributes.metadata=receiverType:dynamic] [@vm.direct-call.metadata=#lib::A2::call] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::A2] super.{self::B2Base::aa2}.call(1, 2, 3, 4, 5, new self::T2::•());
}
}
class T3 extends core::Object {
- synthetic constructor •() → self::T3*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T3*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:16,getterSelectorId:17] method doTest3() → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:16,getterSelectorId:17] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method doTest3() → void {
self::ok = true;
}
}
class A3 extends core::Object {
[@vm.inferred-type.metadata=#lib::T3?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field dynamic foo = null;
- synthetic constructor •() → self::A3*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A3*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = #C1]) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A3::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A3::foo} = a7;
}
}
class B3 extends core::Object {
[@vm.inferred-type.metadata=#lib::A3] [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:18,getterSelectorId:19] field self::A3* aa3 = new self::A3::•();
- synthetic constructor •() → self::B3*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B3*
: super core::Object::•()
;
}
class T4 extends core::Object {
- synthetic constructor •() → self::T4*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::T4*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:20,getterSelectorId:21] method doTest4() → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:20,getterSelectorId:21] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method doTest4() → void {
self::ok = true;
}
}
class A4 extends core::Object {
[@vm.inferred-type.metadata=#lib::T4?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field dynamic foo = null;
- synthetic constructor •() → self::A4*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A4*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = #C1, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = #C1]) → void {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = #C1, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A4::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A4::foo} = a8;
}
}
class B4 extends core::Object {
[@vm.inferred-type.metadata=#lib::A4] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:12,getterSelectorId:13] field dynamic _aa = new self::A4::•();
- synthetic constructor •() → self::B4*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B4*
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,getterSelectorId:22] get aa4() → dynamic
@@ -115,37 +115,37 @@
[@vm.inferred-type.metadata=dart.core::_Closure?]static field core::Function* unknown3 = () → dynamic => self::bb3;
[@vm.inferred-type.metadata=#lib::B4?]static field dynamic bb4 = new self::B4::•();
[@vm.inferred-type.metadata=dart.core::_Closure?]static field core::Function* unknown4 = () → dynamic => self::bb4;
-static method test1() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method test1() → void {
self::B1* bb = new self::B1::•();
let final self::B1* #t1 = bb in let final core::int* #t2 = 1 in let final core::int* #t3 = 2 in let final core::int* #t4 = 3 in let final core::int* #t5 = 4 in let final self::T1* #t6 = new self::T1::•() in [@vm.call-site-attributes.metadata=receiverType:#lib::A1*] [@vm.direct-call.metadata=#lib::A1::call] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::B1::aa1] [@vm.inferred-type.metadata=#lib::A1] #t1.{self::B1::aa1}.{self::A1::call}(#t2, #t3, #t4, #t5, #t6);
self::ok = false;
[@vm.direct-call.metadata=#lib::T1::doTest1??] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=#lib::A1::foo] [@vm.inferred-type.metadata=#lib::T1?] [@vm.direct-call.metadata=#lib::B1::aa1] [@vm.inferred-type.metadata=#lib::A1] bb.{self::B1::aa1}.{self::A1::foo}.{self::T1::doTest1}();
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
}
-static method test2() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method test2() → void {
self::B2* bb = new self::B2::•();
[@vm.direct-call.metadata=#lib::B2::doSuperCall] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B2::doSuperCall}();
self::ok = false;
[@vm.direct-call.metadata=#lib::T2::doTest2??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::A2::foo] [@vm.inferred-type.metadata=#lib::T2? (receiver not int)] [@vm.direct-call.metadata=#lib::B2Base::aa2] [@vm.inferred-type.metadata=#lib::A2] bb.{self::B2Base::aa2}.foo.doTest2();
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
}
-static method getDynamic3() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic3() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown3.call();
-static method test3() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method test3() → void {
self::getDynamic3().aa3(1, 2, 3, 4, 5, 6, new self::T3::•());
self::ok = false;
[@vm.direct-call.metadata=#lib::T3::doTest3??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::A3::foo] [@vm.inferred-type.metadata=#lib::T3? (receiver not int)] [@vm.direct-call.metadata=#lib::B3::aa3??] [@vm.inferred-type.metadata=#lib::A3 (receiver not int)] [@vm.inferred-type.metadata=#lib::B3?] self::bb3.aa3.foo.doTest3();
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
}
-static method getDynamic4() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method getDynamic4() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] self::unknown4.call();
-static method test4() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method test4() → void {
self::getDynamic4().aa4(1, 2, 3, 4, 5, 6, 7, new self::T4::•());
self::ok = false;
[@vm.direct-call.metadata=#lib::T4::doTest4??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=#lib::A4::foo] [@vm.inferred-type.metadata=#lib::T4? (receiver not int)] [@vm.inferred-type.metadata=#lib::A4] self::getDynamic4().aa4.foo.doTest4();
exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
}
-static method main() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → void {
self::test1();
self::test2();
self::test3();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
index e3c2996..9caa665 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
@@ -3,27 +3,27 @@
import "dart:core" as core;
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
+[@vm.procedure-attributes.metadata=hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → core::int*
return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=! (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError,ForDynamic} core::num*) as{TypeError} core::int*;
}
class TearOffDynamicMethod extends core::Object {
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] field dynamic bazz;
- constructor •(dynamic arg) → self::TearOffDynamicMethod*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] constructor •(dynamic arg) → self::TearOffDynamicMethod*
: self::TearOffDynamicMethod::bazz = arg.foo, super core::Object::•() {
[@vm.call-site-attributes.metadata=receiverType:dynamic] [@vm.direct-call.metadata=#lib::TearOffDynamicMethod::bazz] this.{self::TearOffDynamicMethod::bazz}.call();
}
}
-static method knownResult() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method knownResult() → dynamic
return new self::B::•();
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
core::Function* closure = () → self::B* => new self::B::•();
new self::TearOffDynamicMethod::•([@vm.call-site-attributes.metadata=receiverType:dart.core::Function*] closure.call());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
index 48d30e5..94cf14a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
@@ -4,28 +4,28 @@
import "dart:_internal" as _in;
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → core::int*;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → core::int*
return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num*>([@vm.direct-call.metadata=#lib::B::bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 3) (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult().bar())));
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar() → core::int*
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bar() → core::int*
return 3;
}
class TearOffInterfaceMethod extends core::Object {
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field dynamic bazz;
- constructor •([@vm.inferred-type.metadata=#lib::B] self::A* arg) → self::TearOffInterfaceMethod*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] constructor •([@vm.inferred-type.metadata=#lib::B] self::A* arg) → self::TearOffInterfaceMethod*
: self::TearOffInterfaceMethod::bazz = arg.{self::A::foo}, super core::Object::•()
;
}
-static method knownResult() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method knownResult() → dynamic
return new self::B::•();
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
[@vm.call-site-attributes.metadata=receiverType:dynamic] [@vm.direct-call.metadata=#lib::TearOffInterfaceMethod::bazz] new self::TearOffInterfaceMethod::•(new self::B::•()).{self::TearOffInterfaceMethod::bazz}.call();
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
index 557d8ea..7c51147 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
@@ -4,38 +4,38 @@
import "dart:_internal" as _in;
abstract class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] abstract method foo() → core::int*;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] abstract method foo() → core::int*;
}
class B extends self::A {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → core::int*
return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num*>([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
}
abstract class Base extends core::Object {
- synthetic constructor •() → self::Base*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::Base*
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method foo() → core::int*
return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 3.{core::num::+}(_in::unsafeCast<core::num*>([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method doCall(dynamic x) → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method doCall(dynamic x) → core::int*
return [@vm.call-site-attributes.metadata=receiverType:dynamic] x.call() as{TypeError,ForDynamic} core::int*;
}
class TearOffSuperMethod extends self::Base {
- synthetic constructor •() → self::TearOffSuperMethod*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::TearOffSuperMethod*
: super self::Base::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method bar() → core::int*
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] method bar() → core::int*
return [@vm.direct-call.metadata=#lib::Base::doCall] [@vm.inferred-type.metadata=int? (skip check)] this.{self::Base::doCall}(super.{self::Base::foo});
}
[@vm.inferred-type.metadata=#lib::B?]static field self::A* aa = new self::B::•();
-static method knownResult() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method knownResult() → dynamic
return new self::B::•();
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
[@vm.direct-call.metadata=#lib::TearOffSuperMethod::bar] [@vm.inferred-type.metadata=!? (skip check)] new self::TearOffSuperMethod::•().{self::TearOffSuperMethod::bar}();
[@vm.direct-call.metadata=#lib::B::foo??] [@vm.inferred-type.metadata=!? (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::aa.{self::A::foo}();
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unfinished_static_field_init.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unfinished_static_field_init.dart.expect
index 74d3bb3..4e012e2 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unfinished_static_field_init.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unfinished_static_field_init.dart.expect
@@ -3,17 +3,17 @@
import "dart:core" as core;
class A extends core::Object {
- synthetic constructor •() → self::A*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::A*
: super core::Object::•()
;
}
[@vm.inferred-type.metadata=#lib::A?]static field dynamic static_field_good = [@vm.inferred-type.metadata=#lib::A] self::good();
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field dynamic static_field_bad = [@vm.inferred-type.metadata=!] self::bad();
-static method good() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method good() → dynamic
return new self::A::•();
-static method bad() → dynamic
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method bad() → dynamic
return throw "No return!";
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
core::print([@vm.inferred-type.metadata=#lib::A?] self::static_field_good);
core::print([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::static_field_bad);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
index 47a15c4..2e7e6be 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
@@ -7,16 +7,16 @@
abstract class A extends core::Object implements self::I {
}
class B extends core::Object implements self::I {
- synthetic constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::B*
: super core::Object::•()
;
}
[@vm.inferred-type.metadata=#lib::B?]static field self::I* ii = new self::B::•();
-static method bar([@vm.inferred-type.metadata=#lib::B?] self::I* i) → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method bar([@vm.inferred-type.metadata=#lib::B?] self::I* i) → void {
if(i is self::A*) {
let dynamic #t1 = i{self::A*} in let dynamic #t2 = 42 in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
}
}
-static method main(core::List<core::String*>* args) → dynamic {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main(core::List<core::String*>* args) → dynamic {
self::bar([@vm.inferred-type.metadata=#lib::B?] self::ii);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
index e02c5ea..ec1d988 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
@@ -5,19 +5,19 @@
abstract class A extends core::Object {
}
class B extends core::Object {
- constructor •() → self::B*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] constructor •() → self::B*
: super core::Object::•() {
core::print("B");
}
}
class C extends core::Object {
[@vm.inferred-type.metadata=#lib::B?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] field self::B* instanceField = new self::B::•();
- synthetic constructor •() → self::C*
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata'] synthetic constructor •() → self::C*
: super core::Object::•()
;
}
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field self::A* field = throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
-static method main() → void {
+[@vm.unboxing-info.metadata=Instance of 'UnboxingInfoMetadata']static method main() → void {
self::field = null;
[@vm.direct-call.metadata=#lib::C::instanceField] [@vm.inferred-type.metadata=!? (skip check)] new self::C::•().{self::C::instanceField} = null;
}
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 2041a96..6758942 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,7 +1,14 @@
# Changelog
+## 4.0.0
+- **breaking**: RPCs which can return a `Sentinel` will now throw the `Sentinel`
+ it is received as a response.
+- **breaking**: RPCs which can return multiple values now return
+ `Future<Response>` rather than `Future<dynamic>`.
+- `RPCError` now implements `Exception`.
+
## 3.0.0
-**breaking**: RPCs which have an isolateId parameter now return
+- **breaking**: RPCs which have an isolateId parameter now return
`Future<dynamic>` as a `Sentinel` can be returned if the target isolate no
longer exists.
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 563d826d..7fc8e94 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -80,11 +80,9 @@
if (json is List) {
return json.map((e) => creator(e)).toList();
} else if (json is Map) {
- Map<String, dynamic> map = {};
- for (dynamic key in json.keys) {
- map[key as String] = json[key];
- }
- return creator(map);
+ return creator({
+ for (String key in json.keys) key: json[key],
+ });
} else {
// Handle simple types.
return json;
@@ -187,47 +185,47 @@
};
Map<String, List<String>> _methodReturnTypes = {
- 'addBreakpoint': const ['Breakpoint', 'Sentinel'],
- 'addBreakpointWithScriptUri': const ['Breakpoint', 'Sentinel'],
- 'addBreakpointAtEntry': const ['Breakpoint', 'Sentinel'],
- 'clearCpuSamples': const ['Success', 'Sentinel'],
+ 'addBreakpoint': const ['Breakpoint'],
+ 'addBreakpointWithScriptUri': const ['Breakpoint'],
+ 'addBreakpointAtEntry': const ['Breakpoint'],
+ 'clearCpuSamples': const ['Success'],
'clearVMTimeline': const ['Success'],
- 'invoke': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
- 'evaluate': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
- 'evaluateInFrame': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
- 'getAllocationProfile': const ['AllocationProfile', 'Sentinel'],
+ 'invoke': const ['InstanceRef', 'ErrorRef'],
+ 'evaluate': const ['InstanceRef', 'ErrorRef'],
+ 'evaluateInFrame': const ['InstanceRef', 'ErrorRef'],
+ 'getAllocationProfile': const ['AllocationProfile'],
'getClientName': const ['ClientName'],
- 'getCpuSamples': const ['CpuSamples', 'Sentinel'],
+ 'getCpuSamples': const ['CpuSamples'],
'getFlagList': const ['FlagList'],
- 'getInboundReferences': const ['InboundReferences', 'Sentinel'],
- 'getInstances': const ['InstanceSet', 'Sentinel'],
- 'getIsolate': const ['Isolate', 'Sentinel'],
- 'getIsolateGroup': const ['IsolateGroup', 'Sentinel'],
- 'getMemoryUsage': const ['MemoryUsage', 'Sentinel'],
- 'getIsolateGroupMemoryUsage': const ['MemoryUsage', 'Sentinel'],
- 'getScripts': const ['ScriptList', 'Sentinel'],
- 'getObject': const ['Obj', 'Sentinel'],
- 'getRetainingPath': const ['RetainingPath', 'Sentinel'],
- 'getStack': const ['Stack', 'Sentinel'],
- 'getSourceReport': const ['SourceReport', 'Sentinel'],
+ 'getInboundReferences': const ['InboundReferences'],
+ 'getInstances': const ['InstanceSet'],
+ 'getIsolate': const ['Isolate'],
+ 'getIsolateGroup': const ['IsolateGroup'],
+ 'getMemoryUsage': const ['MemoryUsage'],
+ 'getIsolateGroupMemoryUsage': const ['MemoryUsage'],
+ 'getScripts': const ['ScriptList'],
+ 'getObject': const ['Obj'],
+ 'getRetainingPath': const ['RetainingPath'],
+ 'getStack': const ['Stack'],
+ 'getSourceReport': const ['SourceReport'],
'getVersion': const ['Version'],
'getVM': const ['VM'],
'getVMTimeline': const ['Timeline'],
'getVMTimelineFlags': const ['TimelineFlags'],
'getVMTimelineMicros': const ['Timestamp'],
- 'pause': const ['Success', 'Sentinel'],
- 'kill': const ['Success', 'Sentinel'],
+ 'pause': const ['Success'],
+ 'kill': const ['Success'],
'registerService': const ['Success'],
- 'reloadSources': const ['ReloadReport', 'Sentinel'],
- 'removeBreakpoint': const ['Success', 'Sentinel'],
- 'requestHeapSnapshot': const ['Success', 'Sentinel'],
+ 'reloadSources': const ['ReloadReport'],
+ 'removeBreakpoint': const ['Success'],
+ 'requestHeapSnapshot': const ['Success'],
'requirePermissionToResume': const ['Success'],
- 'resume': const ['Success', 'Sentinel'],
+ 'resume': const ['Success'],
'setClientName': const ['Success'],
- 'setExceptionPauseMode': const ['Success', 'Sentinel'],
+ 'setExceptionPauseMode': const ['Success'],
'setFlag': const ['Success', 'Error'],
- 'setLibraryDebuggable': const ['Success', 'Sentinel'],
- 'setName': const ['Success', 'Sentinel'],
+ 'setLibraryDebuggable': const ['Success'],
+ 'setName': const ['Success'],
'setVMName': const ['Success'],
'setVMTimelineFlags': const ['Success'],
'streamCancel': const ['Success'],
@@ -274,8 +272,9 @@
///
/// See [Breakpoint].
///
- /// The return value can be one of [Breakpoint] or [Sentinel].
- Future<dynamic> addBreakpoint(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Breakpoint> addBreakpoint(
String isolateId,
String scriptId,
int line, {
@@ -310,8 +309,9 @@
///
/// See [Breakpoint].
///
- /// The return value can be one of [Breakpoint] or [Sentinel].
- Future<dynamic> addBreakpointWithScriptUri(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Breakpoint> addBreakpointWithScriptUri(
String isolateId,
String scriptUri,
int line, {
@@ -331,8 +331,9 @@
///
/// Note that breakpoints are added and removed on a per-isolate basis.
///
- /// The return value can be one of [Breakpoint] or [Sentinel].
- Future<dynamic> addBreakpointAtEntry(String isolateId, String functionId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Breakpoint> addBreakpointAtEntry(String isolateId, String functionId);
/// Clears all CPU profiling samples.
///
@@ -341,8 +342,9 @@
///
/// See [Success].
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> clearCpuSamples(String isolateId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> clearCpuSamples(String isolateId);
/// Clears all VM timeline events.
///
@@ -381,8 +383,11 @@
/// If the invocation is evaluated successfully, an [InstanceRef] reference
/// will be returned.
///
- /// The return value can be one of [InstanceRef], [ErrorRef] or [Sentinel].
- Future<dynamic> invoke(
+ /// The return value can be one of [InstanceRef] or [ErrorRef].
+ ///
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Response> invoke(
String isolateId,
String targetId,
String selector,
@@ -424,8 +429,11 @@
/// If the expression is evaluated successfully, an [InstanceRef] reference
/// will be returned.
///
- /// The return value can be one of [InstanceRef], [ErrorRef] or [Sentinel].
- Future<dynamic> evaluate(
+ /// The return value can be one of [InstanceRef] or [ErrorRef].
+ ///
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Response> evaluate(
String isolateId,
String targetId,
String expression, {
@@ -459,8 +467,11 @@
/// If `isolateId` refers to an isolate which has exited, then the `Collected`
/// [Sentinel] is returned.
///
- /// The return value can be one of [InstanceRef], [ErrorRef] or [Sentinel].
- Future<dynamic> evaluateInFrame(
+ /// The return value can be one of [InstanceRef] or [ErrorRef].
+ ///
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Response> evaluateInFrame(
String isolateId,
int frameIndex,
String expression, {
@@ -481,8 +492,10 @@
/// If `isolateId` refers to an isolate which has exited, then the `Collected`
/// [Sentinel] is returned.
///
- /// The return value can be one of [AllocationProfile] or [Sentinel].
- Future<dynamic> getAllocationProfile(String isolateId, {bool reset, bool gc});
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<AllocationProfile> getAllocationProfile(String isolateId,
+ {bool reset, bool gc});
/// The `getClientName` RPC is used to retrieve the name associated with the
/// currently connected VM service client. If no name was previously set
@@ -502,8 +515,9 @@
///
/// See [CpuSamples].
///
- /// The return value can be one of [CpuSamples] or [Sentinel].
- Future<dynamic> getCpuSamples(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<CpuSamples> getCpuSamples(
String isolateId, int timeOriginMicros, int timeExtentMicros);
/// The `getFlagList` RPC returns a list of all command line flags in the VM
@@ -537,8 +551,9 @@
///
/// See [InboundReferences].
///
- /// The return value can be one of [InboundReferences] or [Sentinel].
- Future<dynamic> getInboundReferences(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<InboundReferences> getInboundReferences(
String isolateId, String targetId, int limit);
/// The `getInstances` RPC is used to retrieve a set of instances which are of
@@ -563,8 +578,10 @@
///
/// See [InstanceSet].
///
- /// The return value can be one of [InstanceSet] or [Sentinel].
- Future<dynamic> getInstances(String isolateId, String objectId, int limit);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<InstanceSet> getInstances(
+ String isolateId, String objectId, int limit);
/// The `getIsolate` RPC is used to lookup an `Isolate` object by its `id`.
///
@@ -573,8 +590,9 @@
///
/// See [Isolate].
///
- /// The return value can be one of [Isolate] or [Sentinel].
- Future<dynamic> getIsolate(String isolateId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Isolate> getIsolate(String isolateId);
/// The `getIsolateGroup` RPC is used to lookup an `IsolateGroup` object by
/// its `id`.
@@ -588,8 +606,9 @@
///
/// See [IsolateGroup], [VM].
///
- /// The return value can be one of [IsolateGroup] or [Sentinel].
- Future<dynamic> getIsolateGroup(String isolateGroupId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<IsolateGroup> getIsolateGroup(String isolateGroupId);
/// The `getMemoryUsage` RPC is used to lookup an isolate's memory usage
/// statistics by its `id`.
@@ -599,8 +618,9 @@
///
/// See [Isolate].
///
- /// The return value can be one of [MemoryUsage] or [Sentinel].
- Future<dynamic> getMemoryUsage(String isolateId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<MemoryUsage> getMemoryUsage(String isolateId);
/// The `getIsolateGroupMemoryUsage` RPC is used to lookup an isolate group's
/// memory usage statistics by its `id`.
@@ -610,8 +630,9 @@
///
/// See [IsolateGroup].
///
- /// The return value can be one of [MemoryUsage] or [Sentinel].
- Future<dynamic> getIsolateGroupMemoryUsage(String isolateGroupId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<MemoryUsage> getIsolateGroupMemoryUsage(String isolateGroupId);
/// The `getScripts` RPC is used to retrieve a `ScriptList` containing all
/// scripts for an isolate based on the isolate's `isolateId`.
@@ -621,8 +642,9 @@
///
/// See [ScriptList].
///
- /// The return value can be one of [ScriptList] or [Sentinel].
- Future<dynamic> getScripts(String isolateId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<ScriptList> getScripts(String isolateId);
/// The `getObject` RPC is used to lookup an `object` from some isolate by its
/// `id`.
@@ -648,8 +670,9 @@
/// Int32List, Int64List, Flooat32List, Float64List, Inst32x3List,
/// Float32x4List, and Float64x2List. These parameters are otherwise ignored.
///
- /// The return value can be one of [Obj] or [Sentinel].
- Future<dynamic> getObject(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Obj> getObject(
String isolateId,
String objectId, {
int offset,
@@ -678,8 +701,9 @@
///
/// See [RetainingPath].
///
- /// The return value can be one of [RetainingPath] or [Sentinel].
- Future<dynamic> getRetainingPath(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<RetainingPath> getRetainingPath(
String isolateId, String targetId, int limit);
/// The `getStack` RPC is used to retrieve the current execution stack and
@@ -690,8 +714,9 @@
///
/// See [Stack].
///
- /// The return value can be one of [Stack] or [Sentinel].
- Future<dynamic> getStack(String isolateId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Stack> getStack(String isolateId);
/// The `getSourceReport` RPC is used to generate a set of reports tied to
/// source locations in an isolate.
@@ -730,8 +755,9 @@
///
/// See [SourceReport].
///
- /// The return value can be one of [SourceReport] or [Sentinel].
- Future<dynamic> getSourceReport(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<SourceReport> getSourceReport(
String isolateId,
/*List<SourceReportKind>*/
List<String> reports, {
@@ -801,8 +827,9 @@
///
/// See [Success].
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> pause(String isolateId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> pause(String isolateId);
/// The `kill` RPC is used to kill an isolate as if by dart:isolate's
/// `Isolate.kill(IMMEDIATE)`.
@@ -814,8 +841,9 @@
///
/// See [Success].
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> kill(String isolateId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> kill(String isolateId);
/// Registers a service that can be invoked by other VM service clients, where
/// `service` is the name of the service to advertise and `alias` is an
@@ -845,8 +873,9 @@
/// If `isolateId` refers to an isolate which has exited, then the `Collected`
/// [Sentinel] is returned.
///
- /// The return value can be one of [ReloadReport] or [Sentinel].
- Future<dynamic> reloadSources(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<ReloadReport> reloadSources(
String isolateId, {
bool force,
bool pause,
@@ -863,8 +892,9 @@
///
/// See [Success].
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> removeBreakpoint(String isolateId, String breakpointId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> removeBreakpoint(String isolateId, String breakpointId);
/// Requests a dump of the Dart heap of the given isolate.
///
@@ -877,8 +907,9 @@
/// If `isolateId` refers to an isolate which has exited, then the `Collected`
/// [Sentinel] is returned.
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> requestHeapSnapshot(String isolateId);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> requestHeapSnapshot(String isolateId);
/// The `requirePermissionToResume` RPC is used to change the pause/resume
/// behavior of isolates by providing a way for the VM service to wait for
@@ -932,8 +963,9 @@
///
/// See [Success], [StepOption].
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> resume(String isolateId,
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> resume(String isolateId,
{/*StepOption*/ String step, int frameIndex});
/// The `setClientName` RPC is used to set a name to be associated with the
@@ -957,8 +989,9 @@
/// If `isolateId` refers to an isolate which has exited, then the `Collected`
/// [Sentinel] is returned.
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> setExceptionPauseMode(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> setExceptionPauseMode(
String isolateId, /*ExceptionPauseMode*/ String mode);
/// The `setFlag` RPC is used to set a VM flag at runtime. Returns an error if
@@ -968,7 +1001,7 @@
/// The following flags may be set at runtime:
///
/// The return value can be one of [Success] or [Error].
- Future<dynamic> setFlag(String name, String value);
+ Future<Response> setFlag(String name, String value);
/// The `setLibraryDebuggable` RPC is used to enable or disable whether
/// breakpoints and stepping work for a given library.
@@ -978,8 +1011,9 @@
///
/// See [Success].
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> setLibraryDebuggable(
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> setLibraryDebuggable(
String isolateId, String libraryId, bool isDebuggable);
/// The `setName` RPC is used to change the debugging name for an isolate.
@@ -989,8 +1023,9 @@
///
/// See [Success].
///
- /// The return value can be one of [Success] or [Sentinel].
- Future<dynamic> setName(String isolateId, String name);
+ /// This method will throw a [SentinelException] in the case a [Sentinel] is
+ /// returned.
+ Future<Success> setName(String isolateId, String name);
/// The `setVMName` RPC is used to change the debugging name for the vm.
///
@@ -1542,210 +1577,179 @@
Stream<Event> get onStderrEvent => _getEventController('Stderr').stream;
@override
- Future<dynamic> addBreakpoint(
+ Future<Breakpoint> addBreakpoint(
String isolateId,
String scriptId,
int line, {
int column,
- }) {
- Map m = {'isolateId': isolateId, 'scriptId': scriptId, 'line': line};
- if (column != null) {
- m['column'] = column;
- }
- return _call('addBreakpoint', m);
- }
+ }) =>
+ _call('addBreakpoint', {
+ 'isolateId': isolateId,
+ 'scriptId': scriptId,
+ 'line': line,
+ if (column != null) 'column': column,
+ });
@override
- Future<dynamic> addBreakpointWithScriptUri(
+ Future<Breakpoint> addBreakpointWithScriptUri(
String isolateId,
String scriptUri,
int line, {
int column,
- }) {
- Map m = {'isolateId': isolateId, 'scriptUri': scriptUri, 'line': line};
- if (column != null) {
- m['column'] = column;
- }
- return _call('addBreakpointWithScriptUri', m);
- }
+ }) =>
+ _call('addBreakpointWithScriptUri', {
+ 'isolateId': isolateId,
+ 'scriptUri': scriptUri,
+ 'line': line,
+ if (column != null) 'column': column,
+ });
@override
- Future<dynamic> addBreakpointAtEntry(String isolateId, String functionId) {
- return _call('addBreakpointAtEntry',
- {'isolateId': isolateId, 'functionId': functionId});
- }
+ Future<Breakpoint> addBreakpointAtEntry(
+ String isolateId, String functionId) =>
+ _call('addBreakpointAtEntry',
+ {'isolateId': isolateId, 'functionId': functionId});
@override
- Future<dynamic> clearCpuSamples(String isolateId) {
- return _call('clearCpuSamples', {'isolateId': isolateId});
- }
+ Future<Success> clearCpuSamples(String isolateId) =>
+ _call('clearCpuSamples', {'isolateId': isolateId});
@override
Future<Success> clearVMTimeline() => _call('clearVMTimeline');
@override
- Future<dynamic> invoke(
+ Future<Response> invoke(
String isolateId,
String targetId,
String selector,
List<String> argumentIds, {
bool disableBreakpoints,
- }) {
- Map m = {
- 'isolateId': isolateId,
- 'targetId': targetId,
- 'selector': selector,
- 'argumentIds': argumentIds
- };
- if (disableBreakpoints != null) {
- m['disableBreakpoints'] = disableBreakpoints;
- }
- return _call('invoke', m);
- }
+ }) =>
+ _call('invoke', {
+ 'isolateId': isolateId,
+ 'targetId': targetId,
+ 'selector': selector,
+ 'argumentIds': argumentIds,
+ if (disableBreakpoints != null)
+ 'disableBreakpoints': disableBreakpoints,
+ });
@override
- Future<dynamic> evaluate(
+ Future<Response> evaluate(
String isolateId,
String targetId,
String expression, {
Map<String, String> scope,
bool disableBreakpoints,
- }) {
- Map m = {
- 'isolateId': isolateId,
- 'targetId': targetId,
- 'expression': expression
- };
- if (scope != null) {
- m['scope'] = scope;
- }
- if (disableBreakpoints != null) {
- m['disableBreakpoints'] = disableBreakpoints;
- }
- return _call('evaluate', m);
- }
+ }) =>
+ _call('evaluate', {
+ 'isolateId': isolateId,
+ 'targetId': targetId,
+ 'expression': expression,
+ if (scope != null) 'scope': scope,
+ if (disableBreakpoints != null)
+ 'disableBreakpoints': disableBreakpoints,
+ });
@override
- Future<dynamic> evaluateInFrame(
+ Future<Response> evaluateInFrame(
String isolateId,
int frameIndex,
String expression, {
Map<String, String> scope,
bool disableBreakpoints,
- }) {
- Map m = {
- 'isolateId': isolateId,
- 'frameIndex': frameIndex,
- 'expression': expression
- };
- if (scope != null) {
- m['scope'] = scope;
- }
- if (disableBreakpoints != null) {
- m['disableBreakpoints'] = disableBreakpoints;
- }
- return _call('evaluateInFrame', m);
- }
+ }) =>
+ _call('evaluateInFrame', {
+ 'isolateId': isolateId,
+ 'frameIndex': frameIndex,
+ 'expression': expression,
+ if (scope != null) 'scope': scope,
+ if (disableBreakpoints != null)
+ 'disableBreakpoints': disableBreakpoints,
+ });
@override
- Future<dynamic> getAllocationProfile(String isolateId,
- {bool reset, bool gc}) {
- Map m = {'isolateId': isolateId};
- if (reset != null && reset) {
- m['reset'] = reset;
- }
- if (gc != null && gc) {
- m['gc'] = gc;
- }
- return _call('getAllocationProfile', m);
- }
+ Future<AllocationProfile> getAllocationProfile(String isolateId,
+ {bool reset, bool gc}) =>
+ _call('getAllocationProfile', {
+ 'isolateId': isolateId,
+ if (reset != null && reset) 'reset': reset,
+ if (gc != null && gc) 'gc': gc,
+ });
@override
Future<ClientName> getClientName() => _call('getClientName');
@override
- Future<dynamic> getCpuSamples(
- String isolateId, int timeOriginMicros, int timeExtentMicros) {
- return _call('getCpuSamples', {
- 'isolateId': isolateId,
- 'timeOriginMicros': timeOriginMicros,
- 'timeExtentMicros': timeExtentMicros
- });
- }
+ Future<CpuSamples> getCpuSamples(
+ String isolateId, int timeOriginMicros, int timeExtentMicros) =>
+ _call('getCpuSamples', {
+ 'isolateId': isolateId,
+ 'timeOriginMicros': timeOriginMicros,
+ 'timeExtentMicros': timeExtentMicros
+ });
@override
Future<FlagList> getFlagList() => _call('getFlagList');
@override
- Future<dynamic> getInboundReferences(
- String isolateId, String targetId, int limit) {
- return _call('getInboundReferences',
- {'isolateId': isolateId, 'targetId': targetId, 'limit': limit});
- }
+ Future<InboundReferences> getInboundReferences(
+ String isolateId, String targetId, int limit) =>
+ _call('getInboundReferences',
+ {'isolateId': isolateId, 'targetId': targetId, 'limit': limit});
@override
- Future<dynamic> getInstances(String isolateId, String objectId, int limit) {
- return _call('getInstances',
- {'isolateId': isolateId, 'objectId': objectId, 'limit': limit});
- }
+ Future<InstanceSet> getInstances(
+ String isolateId, String objectId, int limit) =>
+ _call('getInstances',
+ {'isolateId': isolateId, 'objectId': objectId, 'limit': limit});
@override
- Future<dynamic> getIsolate(String isolateId) {
- return _call('getIsolate', {'isolateId': isolateId});
- }
+ Future<Isolate> getIsolate(String isolateId) =>
+ _call('getIsolate', {'isolateId': isolateId});
@override
- Future<dynamic> getIsolateGroup(String isolateGroupId) {
- return _call('getIsolateGroup', {'isolateGroupId': isolateGroupId});
- }
+ Future<IsolateGroup> getIsolateGroup(String isolateGroupId) =>
+ _call('getIsolateGroup', {'isolateGroupId': isolateGroupId});
@override
- Future<dynamic> getMemoryUsage(String isolateId) {
- return _call('getMemoryUsage', {'isolateId': isolateId});
- }
+ Future<MemoryUsage> getMemoryUsage(String isolateId) =>
+ _call('getMemoryUsage', {'isolateId': isolateId});
@override
- Future<dynamic> getIsolateGroupMemoryUsage(String isolateGroupId) {
- return _call(
- 'getIsolateGroupMemoryUsage', {'isolateGroupId': isolateGroupId});
- }
+ Future<MemoryUsage> getIsolateGroupMemoryUsage(String isolateGroupId) =>
+ _call('getIsolateGroupMemoryUsage', {'isolateGroupId': isolateGroupId});
@override
- Future<dynamic> getScripts(String isolateId) {
- return _call('getScripts', {'isolateId': isolateId});
- }
+ Future<ScriptList> getScripts(String isolateId) =>
+ _call('getScripts', {'isolateId': isolateId});
@override
- Future<dynamic> getObject(
+ Future<Obj> getObject(
String isolateId,
String objectId, {
int offset,
int count,
- }) {
- Map m = {'isolateId': isolateId, 'objectId': objectId};
- if (offset != null) {
- m['offset'] = offset;
- }
- if (count != null) {
- m['count'] = count;
- }
- return _call('getObject', m);
- }
+ }) =>
+ _call('getObject', {
+ 'isolateId': isolateId,
+ 'objectId': objectId,
+ if (offset != null) 'offset': offset,
+ if (count != null) 'count': count,
+ });
@override
- Future<dynamic> getRetainingPath(
- String isolateId, String targetId, int limit) {
- return _call('getRetainingPath',
- {'isolateId': isolateId, 'targetId': targetId, 'limit': limit});
- }
+ Future<RetainingPath> getRetainingPath(
+ String isolateId, String targetId, int limit) =>
+ _call('getRetainingPath',
+ {'isolateId': isolateId, 'targetId': targetId, 'limit': limit});
@override
- Future<dynamic> getStack(String isolateId) {
- return _call('getStack', {'isolateId': isolateId});
- }
+ Future<Stack> getStack(String isolateId) =>
+ _call('getStack', {'isolateId': isolateId});
@override
- Future<dynamic> getSourceReport(
+ Future<SourceReport> getSourceReport(
String isolateId,
/*List<SourceReportKind>*/
List<String> reports, {
@@ -1753,22 +1757,15 @@
int tokenPos,
int endTokenPos,
bool forceCompile,
- }) {
- Map m = {'isolateId': isolateId, 'reports': reports};
- if (scriptId != null) {
- m['scriptId'] = scriptId;
- }
- if (tokenPos != null) {
- m['tokenPos'] = tokenPos;
- }
- if (endTokenPos != null) {
- m['endTokenPos'] = endTokenPos;
- }
- if (forceCompile != null) {
- m['forceCompile'] = forceCompile;
- }
- return _call('getSourceReport', m);
- }
+ }) =>
+ _call('getSourceReport', {
+ 'isolateId': isolateId,
+ 'reports': reports,
+ if (scriptId != null) 'scriptId': scriptId,
+ if (tokenPos != null) 'tokenPos': tokenPos,
+ if (endTokenPos != null) 'endTokenPos': endTokenPos,
+ if (forceCompile != null) 'forceCompile': forceCompile,
+ });
@override
Future<Version> getVersion() => _call('getVersion');
@@ -1777,16 +1774,12 @@
Future<VM> getVM() => _call('getVM');
@override
- Future<Timeline> getVMTimeline({int timeOriginMicros, int timeExtentMicros}) {
- Map m = {};
- if (timeOriginMicros != null) {
- m['timeOriginMicros'] = timeOriginMicros;
- }
- if (timeExtentMicros != null) {
- m['timeExtentMicros'] = timeExtentMicros;
- }
- return _call('getVMTimeline', m);
- }
+ Future<Timeline> getVMTimeline(
+ {int timeOriginMicros, int timeExtentMicros}) =>
+ _call('getVMTimeline', {
+ if (timeOriginMicros != null) 'timeOriginMicros': timeOriginMicros,
+ if (timeExtentMicros != null) 'timeExtentMicros': timeExtentMicros,
+ });
@override
Future<TimelineFlags> getVMTimelineFlags() => _call('getVMTimelineFlags');
@@ -1795,135 +1788,100 @@
Future<Timestamp> getVMTimelineMicros() => _call('getVMTimelineMicros');
@override
- Future<dynamic> pause(String isolateId) {
- return _call('pause', {'isolateId': isolateId});
- }
+ Future<Success> pause(String isolateId) =>
+ _call('pause', {'isolateId': isolateId});
@override
- Future<dynamic> kill(String isolateId) {
- return _call('kill', {'isolateId': isolateId});
- }
+ Future<Success> kill(String isolateId) =>
+ _call('kill', {'isolateId': isolateId});
@override
- Future<Success> registerService(String service, String alias) {
- return _call('registerService', {'service': service, 'alias': alias});
- }
+ Future<Success> registerService(String service, String alias) =>
+ _call('registerService', {'service': service, 'alias': alias});
@override
- Future<dynamic> reloadSources(
+ Future<ReloadReport> reloadSources(
String isolateId, {
bool force,
bool pause,
String rootLibUri,
String packagesUri,
- }) {
- Map m = {'isolateId': isolateId};
- if (force != null) {
- m['force'] = force;
- }
- if (pause != null) {
- m['pause'] = pause;
- }
- if (rootLibUri != null) {
- m['rootLibUri'] = rootLibUri;
- }
- if (packagesUri != null) {
- m['packagesUri'] = packagesUri;
- }
- return _call('reloadSources', m);
- }
+ }) =>
+ _call('reloadSources', {
+ 'isolateId': isolateId,
+ if (force != null) 'force': force,
+ if (pause != null) 'pause': pause,
+ if (rootLibUri != null) 'rootLibUri': rootLibUri,
+ if (packagesUri != null) 'packagesUri': packagesUri,
+ });
@override
- Future<dynamic> removeBreakpoint(String isolateId, String breakpointId) {
- return _call('removeBreakpoint',
- {'isolateId': isolateId, 'breakpointId': breakpointId});
- }
+ Future<Success> removeBreakpoint(String isolateId, String breakpointId) =>
+ _call('removeBreakpoint',
+ {'isolateId': isolateId, 'breakpointId': breakpointId});
@override
- Future<dynamic> requestHeapSnapshot(String isolateId) {
- return _call('requestHeapSnapshot', {'isolateId': isolateId});
- }
+ Future<Success> requestHeapSnapshot(String isolateId) =>
+ _call('requestHeapSnapshot', {'isolateId': isolateId});
@override
Future<Success> requirePermissionToResume(
- {bool onPauseStart, bool onPauseReload, bool onPauseExit}) {
- Map m = {};
- if (onPauseStart != null) {
- m['onPauseStart'] = onPauseStart;
- }
- if (onPauseReload != null) {
- m['onPauseReload'] = onPauseReload;
- }
- if (onPauseExit != null) {
- m['onPauseExit'] = onPauseExit;
- }
- return _call('requirePermissionToResume', m);
- }
+ {bool onPauseStart, bool onPauseReload, bool onPauseExit}) =>
+ _call('requirePermissionToResume', {
+ if (onPauseStart != null) 'onPauseStart': onPauseStart,
+ if (onPauseReload != null) 'onPauseReload': onPauseReload,
+ if (onPauseExit != null) 'onPauseExit': onPauseExit,
+ });
@override
- Future<dynamic> resume(String isolateId,
- {/*StepOption*/ String step, int frameIndex}) {
- Map m = {'isolateId': isolateId};
- if (step != null) {
- m['step'] = step;
- }
- if (frameIndex != null) {
- m['frameIndex'] = frameIndex;
- }
- return _call('resume', m);
- }
+ Future<Success> resume(String isolateId,
+ {/*StepOption*/ String step, int frameIndex}) =>
+ _call('resume', {
+ 'isolateId': isolateId,
+ if (step != null) 'step': step,
+ if (frameIndex != null) 'frameIndex': frameIndex,
+ });
@override
- Future<Success> setClientName(String name) {
- return _call('setClientName', {'name': name});
- }
+ Future<Success> setClientName(String name) =>
+ _call('setClientName', {'name': name});
@override
- Future<dynamic> setExceptionPauseMode(
- String isolateId, /*ExceptionPauseMode*/ String mode) {
- return _call(
- 'setExceptionPauseMode', {'isolateId': isolateId, 'mode': mode});
- }
+ Future<Success> setExceptionPauseMode(
+ String isolateId, /*ExceptionPauseMode*/ String mode) =>
+ _call('setExceptionPauseMode', {'isolateId': isolateId, 'mode': mode});
@override
- Future<dynamic> setFlag(String name, String value) {
- return _call('setFlag', {'name': name, 'value': value});
- }
+ Future<Response> setFlag(String name, String value) =>
+ _call('setFlag', {'name': name, 'value': value});
@override
- Future<dynamic> setLibraryDebuggable(
- String isolateId, String libraryId, bool isDebuggable) {
- return _call('setLibraryDebuggable', {
- 'isolateId': isolateId,
- 'libraryId': libraryId,
- 'isDebuggable': isDebuggable
- });
- }
+ Future<Success> setLibraryDebuggable(
+ String isolateId, String libraryId, bool isDebuggable) =>
+ _call('setLibraryDebuggable', {
+ 'isolateId': isolateId,
+ 'libraryId': libraryId,
+ 'isDebuggable': isDebuggable
+ });
@override
- Future<dynamic> setName(String isolateId, String name) {
- return _call('setName', {'isolateId': isolateId, 'name': name});
- }
+ Future<Success> setName(String isolateId, String name) =>
+ _call('setName', {'isolateId': isolateId, 'name': name});
@override
- Future<Success> setVMName(String name) {
- return _call('setVMName', {'name': name});
- }
+ Future<Success> setVMName(String name) => _call('setVMName', {'name': name});
@override
- Future<Success> setVMTimelineFlags(List<String> recordedStreams) {
- return _call('setVMTimelineFlags', {'recordedStreams': recordedStreams});
- }
+ Future<Success> setVMTimelineFlags(List<String> recordedStreams) =>
+ _call('setVMTimelineFlags', {'recordedStreams': recordedStreams});
@override
- Future<Success> streamCancel(String streamId) {
- return _call('streamCancel', {'streamId': streamId});
- }
+ Future<Success> streamCancel(String streamId) =>
+ _call('streamCancel', {'streamId': streamId});
@override
- Future<Success> streamListen(String streamId) {
- return _call('streamListen', {'streamId': streamId});
- }
+ Future<Success> streamListen(String streamId) =>
+ _call('streamListen', {'streamId': streamId});
/// Call an arbitrary service protocol method. This allows clients to call
/// methods not explicitly exposed by this library.
@@ -2063,7 +2021,9 @@
} else {
Map<String, dynamic> result = json['result'] as Map<String, dynamic>;
String type = result['type'];
- if (_typeFactories[type] == null) {
+ if (type == 'Sentinel') {
+ completer.completeError(SentinelException.parse(methodName, result));
+ } else if (_typeFactories[type] == null) {
completer.complete(Response.parse(result));
} else {
completer.complete(createServiceObject(result, returnTypes));
@@ -2116,7 +2076,7 @@
typedef DisposeHandler = Future Function();
-class RPCError {
+class RPCError implements Exception {
static RPCError parse(String callingMethod, dynamic json) {
return RPCError(callingMethod, json['code'], json['message'], json['data']);
}
@@ -2139,6 +2099,17 @@
}
}
+/// Thrown when an RPC response is a [Sentinel].
+class SentinelException implements Exception {
+ final String callingMethod;
+ final Sentinel sentinel;
+
+ SentinelException.parse(this.callingMethod, Map<String, dynamic> data)
+ : sentinel = Sentinel.parse(data);
+
+ String toString() => '$sentinel from ${callingMethod}()';
+}
+
/// An `ExtensionData` is an arbitrary map that can have any contents.
class ExtensionData {
static ExtensionData parse(Map json) =>
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index 99a3026..366bd74 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -2,7 +2,7 @@
description: >-
A library to communicate with a service implementing the Dart VM
service protocol.
-version: 3.0.0+1
+version: 4.0.0
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
diff --git a/pkg/vm_service/test/async_generator_breakpoint_test.dart b/pkg/vm_service/test/async_generator_breakpoint_test.dart
index 4d52ce4..3cf2655 100644
--- a/pkg/vm_service/test/async_generator_breakpoint_test.dart
+++ b/pkg/vm_service/test/async_generator_breakpoint_test.dart
@@ -48,7 +48,7 @@
Future testAsync(VmService service, IsolateRef isolateRef) async {
final isolate = await service.getIsolate(isolateRef.id);
- final lib = await service.getObject(isolate.id, isolate.rootLib.id);
+ final Library lib = await service.getObject(isolate.id, isolate.rootLib.id);
final script = lib.scripts[0];
final bp1 = await service.addBreakpoint(isolate.id, script.id, 11);
@@ -77,10 +77,10 @@
// ignore: unawaited_futures
service
.evaluate(isolate.id, lib.id, 'testerReady = true')
- .then((result) async {
- result = await service.getObject(isolate.id, result.id);
- print(result);
- expect((result as Instance).valueAsString, equals('true'));
+ .then((Response result) async {
+ Obj res = await service.getObject(isolate.id, (result as InstanceRef).id);
+ print(res);
+ expect((res as Instance).valueAsString, equals('true'));
});
final stream = service.onDebugEvent;
diff --git a/pkg/vm_service/test/common/service_test_common.dart b/pkg/vm_service/test/common/service_test_common.dart
index e5dea67..55edf13 100644
--- a/pkg/vm_service/test/common/service_test_common.dart
+++ b/pkg/vm_service/test/common/service_test_common.dart
@@ -117,7 +117,7 @@
return (VmService service, IsolateRef isolateRef) async {
print("Setting breakpoint for line $line");
final isolate = await service.getIsolate(isolateRef.id);
- final lib = await service.getObject(isolate.id, isolate.rootLib.id);
+ final Library lib = await service.getObject(isolate.id, isolate.rootLib.id);
final script = lib.scripts.first;
Breakpoint bpt = await service.addBreakpoint(isolate.id, script.id, line);
@@ -139,7 +139,8 @@
expect(frames.length, greaterThanOrEqualTo(1));
final top = frames[0];
- final script = await service.getObject(isolate.id, top.location.script.id);
+ final Script script =
+ await service.getObject(isolate.id, top.location.script.id);
int actualLine = script.getLineNumberFromTokenPos(top.location.tokenPos);
if (actualLine != line) {
print("Actual: $actualLine Line: $line");
diff --git a/pkg/vm_service/test/coverage_leaf_function_test.dart b/pkg/vm_service/test/coverage_leaf_function_test.dart
index fe28924..eac959f 100644
--- a/pkg/vm_service/test/coverage_leaf_function_test.dart
+++ b/pkg/vm_service/test/coverage_leaf_function_test.dart
@@ -37,9 +37,11 @@
expect(stack.frames.length, greaterThanOrEqualTo(1));
expect(stack.frames[0].function.name, 'testFunction');
- final root = await service.getObject(isolate.id, isolate.rootLib.id);
- var func = root.functions.singleWhere((f) => f.name == 'leafFunction');
- func = await service.getObject(isolate.id, func.id);
+ final Library root =
+ await service.getObject(isolate.id, isolate.rootLib.id);
+ FuncRef funcRef =
+ root.functions.singleWhere((f) => f.name == 'leafFunction');
+ Func func = await service.getObject(isolate.id, funcRef.id) as Func;
final expectedRange = {
'scriptIndex': 0,
@@ -73,9 +75,11 @@
expect(stack.frames.length, greaterThanOrEqualTo(1));
expect(stack.frames[0].function.name, 'testFunction');
- final root = await service.getObject(isolate.id, isolate.rootLib.id);
- var func = root.functions.singleWhere((f) => f.name == 'leafFunction');
- func = await service.getObject(isolate.id, func.id);
+ final Library root =
+ await service.getObject(isolate.id, isolate.rootLib.id);
+ FuncRef funcRef =
+ root.functions.singleWhere((f) => f.name == 'leafFunction');
+ Func func = await service.getObject(isolate.id, funcRef.id) as Func;
var expectedRange = {
'scriptIndex': 0,
diff --git a/pkg/vm_service/test/debugging_test.dart b/pkg/vm_service/test/debugging_test.dart
index 8bfefd6..df3a1ed 100644
--- a/pkg/vm_service/test/debugging_test.dart
+++ b/pkg/vm_service/test/debugging_test.dart
@@ -80,16 +80,14 @@
}
});
await service.streamListen(EventStreams.kDebug);
- final script =
+ final Script script =
await service.getObject(isolate.id, rootLib.scripts.first.id);
// Add the breakpoint.
- final Breakpoint result =
+ final Breakpoint bpt =
await service.addBreakpoint(isolate.id, script.id, 16);
- print(result);
- expect(result is Breakpoint, isTrue);
- Breakpoint bpt = result;
- expect(bpt.location.script.id, script.id);
- expect(script.getLineNumberFromTokenPos(bpt.location.tokenPos), 16);
+ final SourceLocation location = bpt.location;
+ expect(location.script.id, script.id);
+ expect(script.getLineNumberFromTokenPos(location.tokenPos), 16);
isolate = await service.getIsolate(isolate.id);
expect(isolate.breakpoints.length, 1);
diff --git a/pkg/vm_service/test/eval_test.dart b/pkg/vm_service/test/eval_test.dart
index b751001..4eb8bb5 100644
--- a/pkg/vm_service/test/eval_test.dart
+++ b/pkg/vm_service/test/eval_test.dart
@@ -45,7 +45,7 @@
// Make sure we are in the right place.
expect(stack.frames.length, greaterThanOrEqualTo(2));
expect(stack.frames[0].function.name, 'method');
- expect(stack.frames[0].function.owner.name, 'MyClass');
+ expect((stack.frames[0].function.owner as ClassRef).name, 'MyClass');
final LibraryRef lib = isolate.rootLib;
final ClassRef cls = stack.frames[0].function.owner;
@@ -81,11 +81,12 @@
// Make sure we are in the right place.
expect(stack.frames.length, greaterThanOrEqualTo(2));
expect(stack.frames[0].function.name, 'foo');
- expect(stack.frames[0].function.owner.name, '_MyClass');
+ expect((stack.frames[0].function.owner as ClassRef).name, '_MyClass');
final ClassRef cls = stack.frames[0].function.owner;
- final result = await service.evaluate(isolate.id, cls.id, "1+1");
+ final InstanceRef result =
+ await service.evaluate(isolate.id, cls.id, "1+1");
print(result);
expect(result.valueAsString, "2");
}
diff --git a/pkg/vm_service/test/evaluate_with_scope_test.dart b/pkg/vm_service/test/evaluate_with_scope_test.dart
index ad4a106..38588d8 100644
--- a/pkg/vm_service/test/evaluate_with_scope_test.dart
+++ b/pkg/vm_service/test/evaluate_with_scope_test.dart
@@ -22,13 +22,13 @@
final tests = <IsolateTest>[
(VmService service, IsolateRef isolateRef) async {
final isolate = await service.getIsolate(isolateRef.id);
- final lib = await service.getObject(isolate.id, isolate.rootLib.id);
+ final Library lib = await service.getObject(isolate.id, isolate.rootLib.id);
- final field1 = await service.getObject(
+ final Field field1 = await service.getObject(
isolate.id, lib.variables.singleWhere((v) => v.name == 'thing1').id);
final thing1 = (await service.getObject(isolate.id, field1.staticValue.id));
- final field2 = await service.getObject(
+ final Field field2 = await service.getObject(
isolate.id, lib.variables.singleWhere((v) => v.name == 'thing2').id);
final thing2 = (await service.getObject(isolate.id, field2.staticValue.id));
diff --git a/pkg/vm_service/test/get_flag_list_rpc_test.dart b/pkg/vm_service/test/get_flag_list_rpc_test.dart
index f7a8b70..8b6c337 100644
--- a/pkg/vm_service/test/get_flag_list_rpc_test.dart
+++ b/pkg/vm_service/test/get_flag_list_rpc_test.dart
@@ -22,16 +22,14 @@
var tests = <VMTest>[
// Modify a flag which does not exist.
(VmService service) async {
- final result = await service.setFlag('does_not_exist', 'true');
- expect(result, TypeMatcher<Error>());
+ final Error result = await service.setFlag('does_not_exist', 'true');
expect(result.message, 'Cannot set flag: flag not found');
},
// Modify a flag with the wrong value type.
(VmService service) async {
- final result =
+ final Error result =
await service.setFlag('pause_isolates_on_start', 'not-boolean');
- expect(result, TypeMatcher<Error>());
expect(result.message, equals('Cannot set flag: invalid value'));
},
@@ -43,8 +41,7 @@
// Modify a flag which cannot be set at runtime.
(VmService service) async {
- final result = await service.setFlag('random_seed', '42');
- expect(result, TypeMatcher<Error>());
+ final Error result = await service.setFlag('random_seed', '42');
expect(result.message, 'Cannot set flag: cannot change at runtime');
},
diff --git a/pkg/vm_service/test/invoke_test.dart b/pkg/vm_service/test/invoke_test.dart
index dcbb16e..651e39e 100644
--- a/pkg/vm_service/test/invoke_test.dart
+++ b/pkg/vm_service/test/invoke_test.dart
@@ -31,7 +31,7 @@
hasStoppedAtBreakpoint,
(VmService service, IsolateRef isolateRef) async {
final isolate = await service.getIsolate(isolateRef.id);
- final lib = await service.getObject(isolate.id, isolate.rootLib.id);
+ final Library lib = await service.getObject(isolate.id, isolate.rootLib.id);
final cls = lib.classes.singleWhere((cls) => cls.name == "Klass");
FieldRef fieldRef =
lib.variables.singleWhere((field) => field.name == "instance");
diff --git a/pkg/vm_service/test/throws_sentinel_test.dart b/pkg/vm_service/test/throws_sentinel_test.dart
new file mode 100644
index 0000000..b399f06
--- /dev/null
+++ b/pkg/vm_service/test/throws_sentinel_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, 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.
+
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/test_helper.dart';
+
+var tests = <VMTest>[
+ (VmService vm) async {
+ try {
+ final res = await vm.getIsolate('isolates/12321');
+ fail('Expected SentinelException, got $res');
+ } on SentinelException catch (e) {
+ // Expected.
+ } catch (e) {
+ fail('Expected SentinelException, got $e');
+ }
+ },
+];
+
+main([args = const <String>[]]) async => await runVMTests(args, tests);
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 158e24f..eb2e6e8 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -210,7 +210,9 @@
} else {
Map<String, dynamic> result = json['result'] as Map<String, dynamic>;
String type = result['type'];
- if (_typeFactories[type] == null) {
+ if (type == 'Sentinel') {
+ completer.completeError(SentinelException.parse(methodName, result));
+ } else if (_typeFactories[type] == null) {
completer.complete(Response.parse(result));
} else {
completer.complete(createServiceObject(result, returnTypes));
@@ -265,7 +267,7 @@
typedef DisposeHandler = Future Function();
-class RPCError {
+class RPCError implements Exception {
static RPCError parse(String callingMethod, dynamic json) {
return RPCError(callingMethod, json['code'], json['message'], json['data']);
}
@@ -288,6 +290,17 @@
}
}
+/// Thrown when an RPC response is a [Sentinel].
+class SentinelException implements Exception {
+ final String callingMethod;
+ final Sentinel sentinel;
+
+ SentinelException.parse(this.callingMethod, Map<String, dynamic> data) :
+ sentinel = Sentinel.parse(data);
+
+ String toString() => '$sentinel from ${callingMethod}()';
+}
+
/// An `ExtensionData` is an arbitrary map that can have any contents.
class ExtensionData {
static ExtensionData parse(Map json) =>
@@ -512,11 +525,10 @@
if (json is List) {
return json.map((e) => creator(e)).toList();
} else if (json is Map) {
- Map<String, dynamic> map = {};
- for (dynamic key in json.keys) {
- map[key as String] = json[key];
- }
- return creator(map);
+ return creator({
+ for (String key in json.keys)
+ key: json[key],
+ });
} else {
// Handle simple types.
return json;
@@ -1067,35 +1079,31 @@
if (!hasArgs) {
gen.writeStatement("=> _call('${name}');");
} else if (hasOptionalArgs) {
- gen.writeStatement('{');
- gen.write('Map m = {');
+ gen.writeStatement("=> _call('$name', {");
gen.write(args
.where((MethodArg a) => !a.optional)
- .map((arg) => "'${arg.name}': ${arg.name}")
- .join(', '));
- gen.writeln('};');
+ .map((arg) => "'${arg.name}': ${arg.name},")
+ .join());
+
args.where((MethodArg a) => a.optional).forEach((MethodArg arg) {
String valueRef = arg.name;
// Special case for `getAllocationProfile`. We do not want to add these
// params if they are false.
if (name == 'getAllocationProfile') {
- gen.writeln("if (${arg.name} != null && ${arg.name}) {");
+ gen.writeln("if (${arg.name} != null && ${arg.name})");
} else {
- gen.writeln("if (${arg.name} != null) {");
+ gen.writeln("if (${arg.name} != null)");
}
- gen.writeln("m['${arg.name}'] = ${valueRef};");
- gen.writeln("}");
+ gen.writeln("'${arg.name}': $valueRef,");
});
- gen.writeStatement("return _call('${name}', m);");
- gen.writeStatement('}');
+
+ gen.writeln('});');
} else {
- gen.writeStatement('{');
- gen.write("return _call('${name}', {");
+ gen.write("=> _call('${name}', {");
gen.write(args.map((MethodArg arg) {
return "'${arg.name}': ${arg.name}";
}).join(', '));
gen.writeStatement('});');
- gen.writeStatement('}');
}
}
@@ -1115,6 +1123,11 @@
'${joinLast(returnType.types.map((t) => '[${t}]'), ', ', ' or ')}.';
_docs = _docs.trim();
}
+ if (returnType.canReturnSentinel) {
+ _docs +=
+ '\n\nThis method will throw a [SentinelException] in the case a [Sentinel] is returned.';
+ _docs = _docs.trim();
+ }
if (_docs.isNotEmpty) gen.writeDocs(_docs);
}
if (withOverrides) gen.writeln('@override');
@@ -1152,10 +1165,11 @@
MemberType();
- void parse(Parser parser) {
+ void parse(Parser parser, {bool isReturnType = false}) {
// foo|bar[]|baz
// (@Instance|Sentinel)[]
bool loop = true;
+ this.isReturnType = isReturnType;
while (loop) {
if (parser.consume('(')) {
@@ -1177,7 +1191,11 @@
parser.expect(']');
ref.arrayDepth++;
}
- types.add(ref);
+ if (isReturnType && ref.name == 'Sentinel') {
+ canReturnSentinel = true;
+ } else {
+ types.add(ref);
+ }
}
loop = parser.consume('|');
@@ -1187,9 +1205,13 @@
String get name {
if (types.isEmpty) return '';
if (types.length == 1) return types.first.ref;
+ if (isReturnType) return 'Response';
return 'dynamic';
}
+ bool isReturnType = false;
+ bool canReturnSentinel = false;
+
bool get isMultipleReturns => types.length > 1;
bool get isSimple => types.length == 1 && types.first.isSimple;
@@ -1928,7 +1950,7 @@
// method is return type, name, (, args )
// args is type name, [optional], comma
- method.returnType.parse(this);
+ method.returnType.parse(this, isReturnType: true);
Token t = expectName();
validate(
diff --git a/runtime/bin/elf_loader.h b/runtime/bin/elf_loader.h
index 759d01e..483fbe79 100644
--- a/runtime/bin/elf_loader.h
+++ b/runtime/bin/elf_loader.h
@@ -37,6 +37,7 @@
#endif
#if !defined(__Fuchsia__)
+/// Please see documentation for Dart_LoadElf_Fd.
DART_EXPORT Dart_LoadedElf* Dart_LoadELF(const char* filename,
uint64_t file_offset,
const char** error,
@@ -46,6 +47,7 @@
const uint8_t** vm_isolate_instrs);
#endif
+/// Please see documentation for Dart_LoadElf_Fd.
DART_EXPORT Dart_LoadedElf* Dart_LoadELF_Memory(
const uint8_t* snapshot,
uint64_t snapshot_size,
@@ -55,6 +57,11 @@
const uint8_t** vm_isolate_data,
const uint8_t** vm_isolate_instrs);
+/// Unloads an ELF object loaded through Dart_LoadELF{_Fd, _Memory}.
+///
+/// Unlike dlclose(), this does not use reference counting.
+/// Dart_LoadELF{_Fd, _Memory} will return load the target library separately
+/// each time it is called, and the results must be unloaded separately.
DART_EXPORT void Dart_UnloadELF(Dart_LoadedElf* loaded);
#endif // RUNTIME_BIN_ELF_LOADER_H_
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 2716d41..ac89688 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -196,7 +196,7 @@
// when the file is explicitly closed and the finalizer is no longer
// needed.
void DeleteWeakHandle(Dart_Isolate isolate) {
- Dart_DeleteWeakPersistentHandle(isolate, weak_handle_);
+ Dart_DeleteWeakPersistentHandle(weak_handle_);
weak_handle_ = NULL;
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index eef0f09..0da49b0 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -79,6 +79,7 @@
* set by any call to Dart_CreateIsolateGroup or Dart_EnterIsolate.
*/
typedef struct _Dart_Isolate* Dart_Isolate;
+typedef struct _Dart_IsolateGroup* Dart_IsolateGroup;
/**
* An object reference managed by the Dart VM garbage collector.
@@ -441,8 +442,6 @@
/**
* Deallocates a persistent handle.
- *
- * Requires there to be a current isolate.
*/
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object);
@@ -456,13 +455,16 @@
* calling Dart_DeleteWeakPersistentHandle.
*
* If the object becomes unreachable the callback is invoked with the weak
- * persistent handle and the peer as arguments. The callback is invoked on the
- * thread that has entered the isolate at the time of garbage collection. This
- * gives the embedder the ability to cleanup data associated with the object and
- * clear out any cached references to the handle. All references to this handle
- * after the callback will be invalid. It is illegal to call into the VM from
- * the callback. If the handle is deleted before the object becomes unreachable,
- * the callback is never invoked.
+ * persistent handle and the peer as arguments. The callback can be executed
+ * on any thread, will not have a current isolate, and can only call
+ * Dart_DeletePersistentHandle or Dart_DeleteWeakPersistentHandle. The callback
+ * must not call Dart_DeleteWeakPersistentHandle for the handle being finalized,
+ * as it is automatically deleted by the VM after the callback returns.
+ * This gives the embedder the ability to cleanup data associated with the
+ * object and clear out any cached references to the handle. All references to
+ * this handle after the callback will be invalid. It is illegal to call into
+ * the VM from the callback. If the handle is deleted before the object becomes
+ * unreachable, the callback is never invoked.
*
* Requires there to be a current isolate.
*
@@ -485,7 +487,6 @@
Dart_WeakPersistentHandleFinalizer callback);
DART_EXPORT void Dart_DeleteWeakPersistentHandle(
- Dart_Isolate isolate,
Dart_WeakPersistentHandle object);
/*
@@ -992,6 +993,12 @@
DART_EXPORT void* Dart_IsolateData(Dart_Isolate isolate);
/**
+ * Returns the current isolate group. Will return NULL if there is no
+ * current isolate group.
+ */
+DART_EXPORT Dart_IsolateGroup Dart_CurrentIsolateGroup();
+
+/**
* Returns the callback data associated with the current isolate group. This
* data was passed to the isolate group when it was created.
*/
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index 79af3a3..47ead67 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -325,8 +325,7 @@
// the function so that we can reuse the function for each c function with
// the same signature.
const Context& context = Context::Handle(Context::New(1));
- context.SetAt(0,
- Integer::Handle(zone, Integer::New(pointer.NativeAddress())));
+ context.SetAt(0, pointer);
return Closure::New(Object::null_type_arguments(),
Object::null_type_arguments(), function, context,
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 4311238..502fe47 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -20,8 +20,8 @@
const Array& fun_arg_names =
Array::CheckedHandle(zone, arguments->NativeArgAt(1));
const Array& fun_args_desc = Array::Handle(
- zone, ArgumentsDescriptor::New(kTypeArgsLen, fun_arguments.Length(),
- fun_arg_names));
+ zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, fun_arguments.Length(),
+ fun_arg_names));
const Object& result = Object::Handle(
zone, DartEntry::InvokeClosure(fun_arguments, fun_args_desc));
if (result.IsError()) {
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index bb59896..e931966 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1510,7 +1510,7 @@
const int kTypeArgsLen = 0;
const Array& args_descriptor_array = Array::Handle(
- ArgumentsDescriptor::New(kTypeArgsLen, args.Length(), arg_names));
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length(), arg_names));
ArgumentsDescriptor args_descriptor(args_descriptor_array);
if (!redirected_constructor.AreValidArguments(args_descriptor, NULL)) {
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 4463e66..acdaddc 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -320,11 +320,11 @@
Array& args_desc = Array::Handle(zone);
Array& args = Array::Handle(zone);
if (extracted_type_args.IsNull()) {
- args_desc = ArgumentsDescriptor::New(0, 1);
+ args_desc = ArgumentsDescriptor::NewBoxed(0, 1);
args = Array::New(1);
args.SetAt(0, extract);
} else {
- args_desc = ArgumentsDescriptor::New(num_type_args, 1);
+ args_desc = ArgumentsDescriptor::NewBoxed(num_type_args, 1);
args = Array::New(2);
args.SetAt(0, extracted_type_args);
args.SetAt(1, extract);
diff --git a/runtime/tests/vm/dart/dylib_utils.dart b/runtime/tests/vm/dart/dylib_utils.dart
new file mode 100644
index 0000000..75ba33b
--- /dev/null
+++ b/runtime/tests/vm/dart/dylib_utils.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, 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.
+
+import 'dart:ffi' as ffi;
+import 'dart:io' show Platform;
+
+String _platformPath(String name, {String path}) {
+ if (path == null) path = "";
+ if (Platform.isLinux || Platform.isAndroid)
+ return path + "lib" + name + ".so";
+ if (Platform.isMacOS) return path + "lib" + name + ".dylib";
+ if (Platform.isWindows) return path + name + ".dll";
+ throw Exception("Platform not implemented");
+}
+
+ffi.DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
+ String fullPath = _platformPath(name, path: path);
+ return ffi.DynamicLibrary.open(fullPath);
+}
+
+ffi.DynamicLibrary ffiTestFunctions =
+ dlopenPlatformSpecific("ffi_test_functions");
+
+final triggerGc = ffiTestFunctions
+ .lookupFunction<ffi.Void Function(), void Function()>("TriggerGC");
diff --git a/runtime/tests/vm/dart/regress_40754_test.dart b/runtime/tests/vm/dart/regress_40754_test.dart
index 82a2ce0..a532eb2 100644
--- a/runtime/tests/vm/dart/regress_40754_test.dart
+++ b/runtime/tests/vm/dart/regress_40754_test.dart
@@ -2,3247 +2,43 @@
// 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=--optimization_counter_threshold=1 --use-slow-path --old_gen_heap_size=128
+// VMOptions=--deterministic --optimization_counter_threshold=1
-// Regression test for https://dartbug.com/40754.
-// Generated using the Dart Project Fuzz Tester (1.88) as follows:
-// dart dartfuzz.dart --seed 1031911076 --no-fp --no-ffi --no-flat
+// A phi can have Smi type but non-Smi bounds if it is dominated by a smi check
+// which always deoptimizes. Test that bounds check generalizer guards against
+// such situations.
-import 'dart:async';
-import 'dart:cli';
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:core';
-import 'dart:io';
-import 'dart:isolate';
-import 'dart:math';
-import 'dart:typed_data';
+@pragma('vm:prefer-inline')
+int checkSmi(int a) => ~a;
-MapEntry<MapEntry<int, String>, String> var0 =
- MapEntry<MapEntry<int, String>, String>(
- MapEntry<int, String>(19, '+-SE#'), '');
-Map<Expando<bool>, Set<String>> var1 = {
- Expando<bool>('@'): {'O', 'qgLHC', 's\u{1f600}3', 'yiC-', 'q4Z'},
- new Expando<bool>(''): {'\u{1f600}'},
- Expando<bool>('DlE9'): {'-qYQYbD', 'y\u26659G\u2665T', '\u2665T9 ', 'od04C'},
- Expando<bool>('ogdgHz\u{1f600}'): {
- 'gxNA',
- 'c8@uUZJ',
- '\u{1f600}h)yo',
- 'Kactwvm'
- },
- Expando<bool>('wB+Y'): {'WtyR5#K', 'bz1'}
-};
-MapEntry<Set<int>, MapEntry<bool, int>> var2 =
- new MapEntry<Set<int>, MapEntry<bool, int>>({
- ...{-93, 49},
- -39,
- 4,
- 48,
- -87,
- 2147483647
-}, MapEntry<bool, int>(false, 16));
-Endian var3 = (Endian.host);
-ByteData var4 = ByteData(34);
-Int8List var5 = Int8List(26);
-Uint8List var6 =
- Uint8List.fromList([-9223372034707292161, if (true) 31, -47, -2147483647]);
-Uint8ClampedList var7 = Uint8ClampedList(39);
-Int16List var8 = Int16List.fromList(Int32List.fromList([-26, 31, -12, 28]));
-Uint16List var9 = Uint16List(40);
-Int32List var10 = Int32List.fromList(new Uint32List(45));
-Uint32List var11 = Uint32List.fromList(Int8List(9));
-Int64List var12 = Int64List(12);
-Uint64List var13 = Uint64List.fromList(new Uint64List(5));
-Int32x4List var14 = new Int32x4List(4);
-Int32x4 var15 = Int32x4(2, 32, 22, 12);
-Deprecated var16 = Deprecated('');
-Provisional var17 = Provisional();
-bool var18 = bool.fromEnvironment('4)eAkmb');
-Duration var19 = Duration();
-Error var20 = Error();
-AssertionError var21 = AssertionError(39);
-TypeError var22 = TypeError();
-CastError var23 = CastError();
-NullThrownError var24 = NullThrownError();
-ArgumentError var25 = ArgumentError.value(1, '', 3);
-RangeError var26 = RangeError.index(47, 25, '\u2665&69D', 'cE(L', 2);
-IndexError var27 = IndexError(3, 29, '', 'N7u', 27);
-FallThroughError var28 = FallThroughError();
-AbstractClassInstantiationError var29 =
- AbstractClassInstantiationError('2xjF8');
-UnsupportedError var30 = UnsupportedError('eH\u{1f600}');
-UnimplementedError var31 = UnimplementedError('k@\u{1f600}!\u{1f600}(');
-StateError var32 = StateError('8\u2665YK');
-ConcurrentModificationError var33 = ConcurrentModificationError(14);
-StackOverflowError var34 = StackOverflowError();
-CyclicInitializationError var35 = CyclicInitializationError('L37w3tb');
-Exception var36 = Exception(45);
-FormatException var37 = FormatException('7Xe@ ', 9, 34);
-IntegerDivisionByZeroException var38 = IntegerDivisionByZeroException();
-int var39 = 7;
-Null var40 = null;
-num var41 = 18;
-RegExp var42 = RegExp('Lz');
-String var43 = 'v';
-Runes var44 = new Runes('ax\u2665CO(l');
-RuneIterator var45 = RuneIterator(' u');
-StringBuffer var46 = StringBuffer(0);
-Symbol var47 = Symbol('z');
-Expando<bool> var48 = Expando<bool>('!)sO2');
-Expando<int> var49 = new Expando<int>('DUk');
-Expando<String> var50 = Expando<String>('Hj3!!');
-List<bool> var51 = [false, false, true];
-List<int> var52 = Uint8List(26);
-List<String> var53 = ['yPUIV\u{1f600}M', '1T'];
-Set<bool> var54 = {false, true, true, true, true};
-Set<int> var55 = {
- ...{26},
- 37,
- 16
-};
-Set<String> var56 = {'FZClYgD'};
-Map<bool, bool> var57 = {true: true, true: false, true: true};
-Map<bool, int> var58 = {
- true: -79,
- false: 38,
- false: -40,
- false: 12,
- false: 4,
- false: -18
-};
-Map<bool, String> var59 = {
- true: '',
- true: '5',
- false: 'JfkI',
- true: '\u{1f600}T\u26651',
- false: 'a'
-};
-Map<int, bool> var60 = {20: false, 11: true};
-Map<int, int> var61 = {
- -77: -9223372034707292161,
- -55: -65,
- 4294967296: 22,
- 19: -32,
- 13: -9223372032559808513,
- -89: -46
-};
-Map<int, String> var62 = {
- if (true) -51: 'IKA' else -88: 'L0TX',
- -74: '',
- -74: 'fnNp\u2665',
- -9223372030412324864: ''
-};
-Map<String, bool> var63 = {'V\u{1f600}hhZ': false, '1M#': false};
-Map<String, int> var64 = {
- 'J': 7,
- '': -19,
- 'z4\u2665ui': 0,
- '8mdYgX&': 49,
- '(VIc-': 0,
- '7w1O3AT': -19
-};
-Map<String, String> var65 = {
- 'D': 'WkN9WV@',
- 'Giujsb': '\u{1f600}',
- 'JBI': '\u{1f600}\u{1f600}',
- '3 2+EF': '',
- '': '',
- '6': 'hEQj'
-};
-MapEntry<bool, bool> var66 = MapEntry<bool, bool>(true, true);
-MapEntry<bool, int> var67 = new MapEntry<bool, int>(true, 19);
-MapEntry<bool, String> var68 = MapEntry<bool, String>(false, 'mLO8E');
-MapEntry<int, bool> var69 = MapEntry<int, bool>(46, true);
-MapEntry<int, int> var70 = new MapEntry<int, int>(18, 34);
-MapEntry<int, String> var71 = MapEntry<int, String>(31, '4W-');
-MapEntry<String, bool> var72 = MapEntry<String, bool>('8D\u2665jJiM', true);
-MapEntry<String, int> var73 = MapEntry<String, int>('w', 0);
-MapEntry<String, String> var74 = MapEntry<String, String>('zCHHK', '');
-Expando<Expando<bool>> var75 = Expando<Expando<bool>>('Q');
-Expando<Expando<int>> var76 = Expando<Expando<int>>('');
-Expando<Expando<String>> var77 = Expando<Expando<String>>('NR-n');
-Expando<List<bool>> var78 = Expando<List<bool>>('WYs\u2665');
-Expando<List<int>> var79 = Expando<List<int>>('yAg\u26659cO');
-Expando<List<String>> var80 = Expando<List<String>>('');
-Expando<Set<bool>> var81 = Expando<Set<bool>>('Y9!');
-Expando<Set<int>> var82 = Expando<Set<int>>('8!hTXx');
-Expando<Set<String>> var83 = Expando<Set<String>>('');
-Expando<Map<bool, bool>> var84 = Expando<Map<bool, bool>>('IDlgb!Y');
-Expando<Map<bool, int>> var85 = Expando<Map<bool, int>>('ybQ');
-Expando<Map<bool, String>> var86 = Expando<Map<bool, String>>('');
-Expando<Map<int, bool>> var87 = new Expando<Map<int, bool>>('ACW+SP');
-Expando<Map<int, int>> var88 = Expando<Map<int, int>>('d&N\u{1f600}L\u26652');
-Expando<Map<int, String>> var89 = Expando<Map<int, String>>('v\u2665\u2665');
-Expando<Map<String, bool>> var90 =
- Expando<Map<String, bool>>('i\u{1f600}\u2665i1');
-Expando<Map<String, int>> var91 = Expando<Map<String, int>>('@9');
-Expando<Map<String, String>> var92 = Expando<Map<String, String>>('MO');
-Expando<MapEntry<bool, bool>> var93 = new Expando<MapEntry<bool, bool>>('n');
-Expando<MapEntry<bool, int>> var94 = Expando<MapEntry<bool, int>>('X7J@');
-Expando<MapEntry<bool, String>> var95 = Expando<MapEntry<bool, String>>('@pN');
-Expando<MapEntry<int, bool>> var96 = Expando<MapEntry<int, bool>>('');
-Expando<MapEntry<int, int>> var97 = Expando<MapEntry<int, int>>('XYpFl');
-Expando<MapEntry<int, String>> var98 =
- new Expando<MapEntry<int, String>>('o+\u{1f600}i');
-Expando<MapEntry<String, bool>> var99 = Expando<MapEntry<String, bool>>('!2');
-Expando<MapEntry<String, int>> var100 = Expando<MapEntry<String, int>>('lv!x');
-Expando<MapEntry<String, String>> var101 =
- Expando<MapEntry<String, String>>('X+\u2665Vsi');
-List<Expando<bool>> var102 = [
- Expando<bool>('A\u{1f600}'),
- Expando<bool>('u\u{1f600}In'),
- Expando<bool>('(VN#zT\u2665')
-];
-List<Expando<int>> var103 = [
- Expando<int>('!oMzu!6'),
- new Expando<int>('n)NK6u'),
- Expando<int>('ZR'),
- Expando<int>('\u2665Acscbv')
-];
-List<Expando<String>> var104 = [
- new Expando<String>('A&'),
- Expando<String>('zqB'),
- Expando<String>('X'),
- new Expando<String>('q7')
-];
-List<List<bool>> var105 = [
- [false, false, false],
- [false, true, true],
- [false, true],
- [true],
- [false, false, false, false, true]
-];
-List<List<int>> var106 = [
- Uint8List(44),
- Uint16List.fromList(new Int16List(36)),
- Uint16List.fromList(Uint16List.fromList([-9223372032559808512])),
- Uint32List(39)
-];
-List<List<String>> var107 = [
- ['j45\u2665', 'S+wOIx!', 'bU4', 'AJnYc', '+zzgHB\u{1f600}']
-];
-List<Set<bool>> var108 = [
- {true, false, true, false},
- {true},
- {true, false, false, false}
-];
-List<Set<int>> var109 = [
- {9223372034707292159, -43},
- {5, 9223372032559808513, 21, 18},
- {32, -1, -99, 30}
-];
-List<Set<String>> var110 = [
- {'0g7'}
-];
-List<Map<bool, bool>> var111 = [
- {true: true, true: true, true: true, false: true, true: true},
- {false: true, true: false},
- {false: false, true: false, true: true, true: false, true: false}
-];
-List<Map<bool, int>> var112 = [
- {true: 38},
- {true: 13, true: -70, true: -95, false: -75},
- {false: 21, true: 6, true: 9223372032559808513, true: -49},
- {true: -20, true: -37, true: -81},
- {true: -38, false: -60}
-];
-List<Map<bool, String>> var113 = [
- {true: 'M@&hDh!', false: 'pLZ', false: '', true: 'p'},
- {false: '', true: 'A', false: 'bs', true: 'i', true: 'Sg'},
- {
- true: 'bt5c!\u{1f600}C',
- true: 'R\u{1f600}S',
- true: 'c)H\u{1f600}',
- false: '5',
- false: '9j\u{1f600}qKm'
- }
-];
-List<Map<int, bool>> var114 = [
- {-9223372030412324864: true, -50: true},
- {-54: true}
-];
-List<Map<int, int>> var115 = [
- {-78: 10, 40: -65, -73: 1, 33: 6},
- {-47: 0, -66: -97, -9223372036854775807: -2, -97: -42, -83: -50},
- {38: 10, 16: 40, -60: -9223372036854775808, -23: -35},
- {-15: 41, 12: -67, 5: -38},
- {9: -37, -78: -62, -19: 34, -79: -93, 36: 17}
-];
-List<Map<int, String>> var116 = [
- {
- -47: 'g\u26654NBt',
- -82: 'wN9UP7',
- 38: '6fg',
- -1: '!k)',
- -40: '!cug\u{1f600}'
- },
- {46: '7U)Wz+', -4294967296: 'CD0J', 24: ''},
- {16: '', 41: '#@4de#z'},
- {5: 'Q7', 21: 'k', 12: 'STLg9M\u2665'}
-];
-List<Map<String, bool>> var117 = [
- {'U#\u2665#V': true, '\u2665': true, 'r7\u2665T-Gr': false},
- {
- 'E)8EJ': true,
- 'DOsPU\u{1f600}\u2665': false,
- 'K\u2665': true,
- 'Yhl': true,
- 'D': false
- },
- {'FIH': true, 'fxPsEC': false, '': false},
- {
- 'TkVR': false,
- '1#\u2665L\u2665@q': false,
- 'rxmO-\u{1f600}i': true,
- 'fF5yl': false,
- 'ePZ': false
- },
- {
- 'gVFAQt&': false,
- '-7': true,
- '4t\u2665)uP': false,
- '\u{1f600}': false,
- 'p': true
- },
- {'OPH': true, '+8\u{1f600}': true, 'Tgn\u2665o': true}
-];
-List<Map<String, int>> var118 = [
- {'D)': 9223372036854775807, '': -63, '0-': -4}
-];
-List<Map<String, String>> var119 = [
- {'1': 'W9dogx ', 'UL1': '', '': 'R&', 'O)': 'l!\u2665r9'},
- {
- '\u{1f600}lE1(xL': '\u26656',
- 'kAm': '',
- 'y\u{1f600}\u2665Fd2': '\u{1f600}WLZtuP',
- 'qe2': '7nkDI'
- }
-];
-List<MapEntry<bool, bool>> var120 = [
- MapEntry<bool, bool>(true, false),
- MapEntry<bool, bool>(true, false),
- MapEntry<bool, bool>(false, true),
- MapEntry<bool, bool>(false, true)
-];
-List<MapEntry<bool, int>> var121 = [
- MapEntry<bool, int>(false, 27),
- MapEntry<bool, int>(true, 12),
- MapEntry<bool, int>(true, 47),
- MapEntry<bool, int>(true, 36),
- MapEntry<bool, int>(true, 11)
-];
-List<MapEntry<bool, String>> var122 = [
- MapEntry<bool, String>(false, 'goNsM3'),
- MapEntry<bool, String>(true, 'qWMG')
-];
-List<MapEntry<int, bool>> var123 = [
- MapEntry<int, bool>(28, false),
- MapEntry<int, bool>(15, true),
- MapEntry<int, bool>(40, false),
- MapEntry<int, bool>(40, true)
-];
-List<MapEntry<int, int>> var124 = [
- MapEntry<int, int>(40, 38),
- MapEntry<int, int>(0, 28),
- MapEntry<int, int>(37, 27),
- new MapEntry<int, int>(36, 24)
-];
-List<MapEntry<int, String>> var125 = [
- MapEntry<int, String>(12, 'Okr1o'),
- MapEntry<int, String>(47, ''),
- MapEntry<int, String>(38, '')
-];
-List<MapEntry<String, bool>> var126 = [
- MapEntry<String, bool>('j3A&J', true),
- MapEntry<String, bool>('', true),
- new MapEntry<String, bool>('', true),
- MapEntry<String, bool>('AO2n&\u2665a', true)
-];
-List<MapEntry<String, int>> var127 = [
- MapEntry<String, int>('ljJxBQ', 29),
- MapEntry<String, int>('', 24),
- MapEntry<String, int>('\u2665DH', 17),
- MapEntry<String, int>('', 10),
- MapEntry<String, int>('FI\u{1f600}a', 23)
-];
-List<MapEntry<String, String>> var128 = [
- MapEntry<String, String>('\u26656NjP\u{1f600}\u2665', ''),
- MapEntry<String, String>('+zt)ouN', '6e'),
- MapEntry<String, String>('y\u{1f600}r', '(HStKU'),
- MapEntry<String, String>('ZFRAix\u{1f600}', 'Z5Bla'),
- MapEntry<String, String>('OmP', 'YdU'),
- MapEntry<String, String>('yS\u{1f600}z!Op', 'DkIb\u2665ID')
-];
-Set<Expando<bool>> var129 = {
- Expando<bool>('f\u{1f600}79C0#'),
- Expando<bool>('c\u{1f600}m&'),
- Expando<bool>(''),
- Expando<bool>(''),
- Expando<bool>('32K(pJk'),
- Expando<bool>('l21ecJH')
-};
-Set<Expando<int>> var130 = {
- Expando<int>('QyX2'),
- Expando<int>('PN'),
- Expando<int>('i9'),
- Expando<int>('-'),
- Expando<int>('F')
-};
-Set<Expando<String>> var131 = {Expando<String>('-!\u{1f600}')};
-Set<List<bool>> var132 = {
- [true, true, false],
- [true, false, false, true, false],
- [true],
- [true, true, false, false, false],
- [true, false],
- [false, true, false, true]
-};
-Set<List<int>> var133 = {
- Int16List.fromList(Uint16List.fromList(Int8List(12))),
- Int8List(1),
- [18, 36, -2147483647]
-};
-Set<List<String>> var134 = {
- ['', 'j5EUr3', 'T', ')irWN'],
- ['2tNSf9', '@', ')ed'],
- ['jq)', 'O!Zd8', 'YX8P', 'lJ0'],
- ['aA!kqj9', 'J36M#8J', '\u2665a2i-)', 'S\u2665', 't1o ']
-};
-Set<Set<bool>> var135 = {
- {true, false},
- {true},
- {false}
-};
-Set<Set<int>> var136 = {
- {-36, -2147483647, -21, 2, 2},
- {-43, 34},
- {-18, 4294967295},
- {-63, -82}
-};
-Set<Set<String>> var137 = {
- {'O', '\u{1f600}fCb+', 'NC6FO', '7Si'}
-};
-Set<Map<bool, bool>> var138 = {
- {false: true, true: false, true: true, true: false}
-};
-Set<Map<bool, int>> var139 = {
- {false: -54, true: 4294967295, false: -49},
- {false: 6442450945},
- {
- false: 6442450945,
- false: 35,
- true: -32,
- true: -9223372036854775808,
- false: 49
- }
-};
-Set<Map<bool, String>> var140 = {
- {true: 'B(94 (', false: 'tvuL@S', true: 'Aue\u{1f600}#!', false: 'FeX'},
- {false: 'O\u2665a', false: 'W2kR', false: 'wP6\u{1f600}6R', true: 'py'},
- {false: '3tPk9t'},
- {false: 'Fi', true: 'IKO'},
- {false: '6'}
-};
-Set<Map<int, bool>> var141 = {
- {-26: true}
-};
-Set<Map<int, int>> var142 = {
- {-26: 48, -4: -48, -4294967295: -55},
- {-31: -0, 9: 9},
- {37: -71, 39: -15, 42: 41, 11: 31, 21: -59},
- {-77: -21, 47: 3},
- {-46: -49, -25: -70},
- {-1: 1, -29: -80, -77: -55, 30: 33}
-};
-Set<Map<int, String>> var143 = {
- {-99: 'Lj\u{1f600}PWm', 45: 'HK\u{1f600}u9F', -92: '+nv1\u2665#'}
-};
-Set<Map<String, bool>> var144 = {
- {'#4ADh\u2665i': true, 'z': false, '': true}
-};
-Set<Map<String, int>> var145 = {
- {'-\u2665nkOj': 9223372032559808513, 'rl': -58, 'R': 1, 'phO': 20}
-};
-Set<Map<String, String>> var146 = {
- {'&-o-M': '2afIi'},
- {'': 'fH@B', 'rHg': 'vla@UWl', 'y': 'tAy', 'b&z\u{1f600}': 'V0Lf'},
- {'a#zRRn\u2665': '-4 ', '\u{1f600}q&5': 'js'},
- {'f': ''},
- {'UnD4F': 'm', '': '', '5&7': 'hyKT'}
-};
-Set<MapEntry<bool, bool>> var147 = {MapEntry<bool, bool>(true, true)};
-Set<MapEntry<bool, int>> var148 = {
- MapEntry<bool, int>(false, 35),
- MapEntry<bool, int>(false, 19),
- MapEntry<bool, int>(true, 21)
-};
-Set<MapEntry<bool, String>> var149 = {
- MapEntry<bool, String>(false, '\u26652&'),
- MapEntry<bool, String>(true, 'j#+5G2'),
- new MapEntry<bool, String>(true, 'n\u2665-\u{1f600}'),
- MapEntry<bool, String>(true, 'e'),
- MapEntry<bool, String>(false, 'GC\u{1f600}D')
-};
-Set<MapEntry<int, bool>> var150 = {
- new MapEntry<int, bool>(8, true),
- MapEntry<int, bool>(39, false),
- MapEntry<int, bool>(21, false),
- MapEntry<int, bool>(33, false)
-};
-Set<MapEntry<int, int>> var151 = {
- new MapEntry<int, int>(18, 8),
- MapEntry<int, int>(33, 0),
- MapEntry<int, int>(26, 30)
-};
-Set<MapEntry<int, String>> var152 = {
- new MapEntry<int, String>(49, 'a(\u{1f600}Vfh'),
- new MapEntry<int, String>(38, '7Oh')
-};
-Set<MapEntry<String, bool>> var153 = {
- MapEntry<String, bool>('xD8P7', false),
- MapEntry<String, bool>('838', true),
- MapEntry<String, bool>('', true)
-};
-Set<MapEntry<String, int>> var154 = {MapEntry<String, int>('#nRvj', 18)};
-Set<MapEntry<String, String>> var155 = {
- MapEntry<String, String>('Y', 'T'),
- MapEntry<String, String>('\u{1f600}\u{1f600}XO8(d', 'k)h'),
- MapEntry<String, String>('', 'ke5D\u{1f600}6'),
- MapEntry<String, String>('', '@Z&1'),
- MapEntry<String, String>('pBF', 'A66')
-};
-Map<bool, Expando<bool>> var156 = {
- false: Expando<bool>('p@Pa'),
- false: Expando<bool>('Bhx5a\u{1f600}o'),
- true: Expando<bool>('\u2665Uxh8Gw'),
- true: Expando<bool>('j5'),
- false: Expando<bool>('CzxY'),
- false: Expando<bool>('cPL\u2665')
-};
-Map<bool, Expando<int>> var157 = {
- true: Expando<int>('MhPZ'),
- true: new Expando<int>('#\u{1f600}@yDZv'),
- true: new Expando<int>('7('),
- true: Expando<int>('83ns')
-};
-Map<bool, Expando<String>> var158 = {
- true: Expando<String>('Ns'),
- true: Expando<String>('JW'),
- false: Expando<String>('(y'),
- true: Expando<String>('\u2665j!'),
- false: Expando<String>('M')
-};
-Map<bool, List<bool>> var159 = {
- true: [false, false, true, true, false],
- false: [true, false, true]
-};
-Map<bool, List<int>> var160 = {
- false: [29],
- true: Int16List.fromList(Int32List(10))
-};
-Map<bool, List<String>> var161 = {
- true: ['y1H', '2&5', 'pNYYu', '', ''],
- false: ['8B', 'd4AJIL ', '\u26652u-T', 'in\u2665', ''],
- false: ['\u{1f600}Hv-y\u2665k', '\u{1f600}tn\u2665\u2665'],
- true: ['gKZ', '2IG\u2665IV', 'P(9Ky', ''],
- false: ['4', '', 'kKUG@']
-};
-Map<bool, Set<bool>> var162 = {
- false: {true}
-};
-Map<bool, Set<int>> var163 = {
- false: {6442450944, -56, -72}
-};
-Map<bool, Set<String>> var164 = {
- false: {'zleg', 'g', 'H\u{1f600}a()!6', '\u{1f600}0mTmy', 'Y'},
- false: {'g\u2665cOb', 'k28F', 'Q', '24XsZ\u2665'},
- false: {'ct\u2665\u2665#'},
- true: {'miy'}
-};
-Map<bool, Map<bool, bool>> var165 = {
- false: {true: false},
- true: {false: false, false: true, true: false, false: true},
- false: {false: false, false: false, true: true}
-};
-Map<bool, Map<bool, int>> var166 = {
- false: {true: 35, true: 42, false: -82, false: 45},
- true: {true: -23, false: -52, true: -81},
- true: {false: 45, true: -9223372030412324864, true: -60, true: 34, false: 0},
- false: {true: 17, true: -3},
- false: {true: -4294967296}
-};
-Map<bool, Map<bool, String>> var167 = {
- false: {false: 'jV\u2665l'},
- false: {true: 'FWaNQP', false: 'w'},
- false: {false: 'it'},
- false: {true: 'x', true: 'AU3e-v', true: 'Kh\u2665b47&', false: 'u#1\u2665'},
- true: {true: '1', true: 'WDi-X', true: 'vw+\u{1f600}&', true: '3vT'}
-};
-Map<bool, Map<int, bool>> var168 = {
- true: {15: true, 14: false, 4294967297: false, -53: false, 6442450944: true},
- false: {-9223372030412324863: true},
- false: {-8: true, -22: false, 49: true, -0: false, -17: true},
- false: {-60: false, 35: false, 21: false}
-};
-Map<bool, Map<int, int>> var169 = {
- false: {42: -51, -9223372034707292159: -14, -42: 6, 46: 21},
- false: {-9223372034707292160: -51, -91: -61, 23: -98, -27: 47},
- false: {-78: 38},
- true: {42: -0},
- true: {
- -9223372032559808512: -9,
- -13: -9223372028264841217,
- -43: -63,
- 15: -46,
- -4294967296: 47
- }
-};
-Map<bool, Map<int, String>> var170 = {
- false: {48: 'ScV', 38: '9IzTK9', 3: 'sNeS', -67: 'YSt3\u{1f600}#'},
- true: {1: 'iEaGC+', 40: 'YBb\u{1f600}Htx', -55: 'd\u{1f600}y9wk'},
- true: {-2147483647: '+c'},
- true: {-1: ''},
- true: {
- 9223372032559808512: '\u2665NgRZ3B',
- -94: 'J23',
- -33: '',
- -37: 'p(\u2665X\u{1f600}',
- 17: 'oN'
- },
- true: {
- -3: 'MJW1tbq',
- 34: '6\u{1f600}e@p-5',
- 2147483648: 'CVT\u{1f600}',
- 48: '9'
- }
-};
-Map<bool, Map<String, bool>> var171 = {
- false: {
- 'yoczgj(': false,
- '\u26659': false,
- 'bT-J35': false,
- '': false,
- 'rdg(DC': true
- },
- true: {
- 'c\u{1f600}': true,
- '-#V-e': true,
- 'mB0-#\u2665': true,
- 'S': true,
- '\u2665)-q': true
- },
- false: {'E2sIO3Z': true, 'wJ\u{1f600}Dy\u2665X': false}
-};
-Map<bool, Map<String, int>> var172 = {
- false: {
- 'G\u{1f600}B': 38,
- '!ROypT': 46,
- '\u2665oG': -9223372032559808511,
- 'CWqV\u2665': -25,
- '-e\u{1f600}f': -78
- },
- true: {'': 34, 'nPqlU\u2665': 31, '\u{1f600}J#': 9, 'ED9gj': 22}
-};
-Map<bool, Map<String, String>> var173 = {
- false: {'59HUX( ': 'sQZPA', '3': '3a'}
-};
-Map<bool, MapEntry<bool, bool>> var174 = {
- false: MapEntry<bool, bool>(true, false),
- true: MapEntry<bool, bool>(true, true)
-};
-Map<bool, MapEntry<bool, int>> var175 = {
- false: MapEntry<bool, int>(true, 21),
- false: MapEntry<bool, int>(false, 23),
- false: MapEntry<bool, int>(true, 35),
- false: MapEntry<bool, int>(false, 30),
- false: new MapEntry<bool, int>(false, 30)
-};
-Map<bool, MapEntry<bool, String>> var176 = {
- true: MapEntry<bool, String>(true, '0t7!-')
-};
-Map<bool, MapEntry<int, bool>> var177 = {
- false: MapEntry<int, bool>(47, true),
- true: MapEntry<int, bool>(16, false),
- false: MapEntry<int, bool>(18, true),
- false: MapEntry<int, bool>(12, true),
- true: MapEntry<int, bool>(41, false),
- true: MapEntry<int, bool>(4, false)
-};
-Map<bool, MapEntry<int, int>> var178 = {
- true: new MapEntry<int, int>(3, 37),
- false: MapEntry<int, int>(4, 37),
- false: MapEntry<int, int>(6, 36),
- false: MapEntry<int, int>(26, 31),
- true: MapEntry<int, int>(28, 7)
-};
-Map<bool, MapEntry<int, String>> var179 = {
- false: MapEntry<int, String>(45, 'H'),
- true: MapEntry<int, String>(47, 'B\u2665awZ(i'),
- true: MapEntry<int, String>(36, '\u{1f600}P'),
- false: MapEntry<int, String>(18, 'xzDll')
-};
-Map<bool, MapEntry<String, bool>> var180 = {
- false: MapEntry<String, bool>('11vn9O', false),
- true: MapEntry<String, bool>('x2i7@O', false),
- true: MapEntry<String, bool>('#5\u{1f600}khw', true),
- true: MapEntry<String, bool>('47W+F', true),
- false: MapEntry<String, bool>('(NpA', false),
- false: MapEntry<String, bool>('', true)
-};
-Map<bool, MapEntry<String, int>> var181 = {
- false: MapEntry<String, int>('JNX', 19),
- true: MapEntry<String, int>('\u2665jcOS', 8),
- false: MapEntry<String, int>('A', 44),
- false: MapEntry<String, int>('', 40),
- true: MapEntry<String, int>('', 5)
-};
-Map<bool, MapEntry<String, String>> var182 = {
- false: MapEntry<String, String>('V#L8)', 'F3JdH'),
- false: MapEntry<String, String>('', 'x&GJsnQ'),
- false: MapEntry<String, String>('N', '@(gV'),
- true: MapEntry<String, String>('', '+g2#nTA')
-};
-Map<int, Expando<bool>> var183 = {
- 44: Expando<bool>('fh'),
- 11: Expando<bool>('sUbgrs'),
- 14: Expando<bool>('1\u{1f600}\u2665'),
- -73: Expando<bool>('0ubwc'),
- -52: Expando<bool>('!\u{1f600}\u2665E&lS'),
- -0: Expando<bool>('\u26655')
-};
-Map<int, Expando<int>> var184 = {
- -33: Expando<int>('unFc'),
- -26: Expando<int>('rlmQe')
-};
-Map<int, Expando<String>> var185 = {
- 45: new Expando<String>('@'),
- 36: Expando<String>('!D\u2665&Jxy'),
- -44: Expando<String>('')
-};
-Map<int, List<bool>> var186 = {
- 35: [true, true, true, false],
- -79: [false, true, true],
- 19: [true, true],
- 14: [true]
-};
-Map<int, List<int>> var187 = {
- 38: Uint8ClampedList(40),
- 27: Uint8ClampedList(11),
- 12: Uint32List(40)
-};
-Map<int, List<String>> var188 = {
- 34: ['ub\u2665vBP', 'ZI', 'mVrRK\u{1f600}9', '9zz6D']
-};
-Map<int, Set<bool>> var189 = {
- 2147483649: {true, true, false}
-};
-Map<int, Set<int>> var190 = {
- -32: {-92}
-};
-Map<int, Set<String>> var191 = {
- -37: {'F7D', 'K10FvCj', 'zDD@a\u{1f600}-', ''},
- -21: {' CV1', '\u{1f600}C\u{1f600}', '', '49t es7', 'cS\u2665Pv\u2665'},
- 16: {'P3\u2665\u{1f600}XL', 'a@\u26654z', '\u{1f600}\u{1f600}TdU@', 'cPV'},
- 17: {'P1!', 'uA-CbQB'},
- 4: {'cECL', 'N10!V', '0LjZ0hA', 'U7'},
- 8: {'\u2665C', 'aKR'}
-};
-Map<int, Map<bool, bool>> var192 = {
- 42: {false: false},
- 1: {true: false, false: false, false: false, false: false},
- -91: {true: false, false: true, false: true, false: false, true: true},
- -66: {true: true, true: true, false: false},
- 10: {false: true, true: true, true: false}
-};
-Map<int, Map<bool, int>> var193 = {
- -65: {false: -0, false: 17, true: 9, true: 23, false: 6},
- 11: {false: -9223372032559808513, true: 0, true: -57, true: 24, true: 44}
-};
-Map<int, Map<bool, String>> var194 = {
- 38: {
- false: '\u2665I!2ro',
- true: 'NS',
- false: 'MLf\u2665 ',
- true: 'Jb',
- false: ''
- },
- 9223372034707292160: {true: 'b#Crcb'}
-};
-Map<int, Map<int, bool>> var195 = {
- 4: {-89: false, 36: true, 42: true, -9223372028264841217: false, -9: true},
- 42: {
- -9223372036854775807: true,
- -95: true,
- -59: false,
- -25: false,
- -93: false
- },
- 39: {-76: false, 39: true, -52: false, -69: false},
- -74: {-74: true, 11: false, -21: true, -63: false, -37: false},
- -40: {42: false, -9223372034707292159: true, -39: false, 9: false, 12: true},
- 38: {-9223372034707292160: false, -50: false, 28: false, -63: true}
-};
-Map<int, Map<int, int>> var196 = {
- -9223372032559808512: {48: 25, -87: -39},
- -60: {-5: 15, -94: -8},
- 9223372036854775807: {
- -54: -58,
- -91: -9223372036854775808,
- 9223372034707292161: -45,
- -30: 3
- },
- 9223372032559808512: {-21: 15, 30: 28, 1: -53, -4294967296: -78, 21: -52},
- -2: {9: -9223372032559808511, -9223372036854775808: 11}
-};
-Map<int, Map<int, String>> var197 = {
- 6: {-15: 'JH', -18: '\u2665P0nWY'},
- -2147483647: {11: 'eq', 37: '-\u{1f600}'},
- -24: {-49: 'Fox9', -9: ''},
- -25: {15: 'VXR2E'}
-};
-Map<int, Map<String, bool>> var198 = {
- 6442450944: {'\u{1f600}': false, 'S': true},
- -22: {'#0bj\u{1f600}': false, 'O\u2665O\u{1f600}n\u2665': false},
- -94: {'qiS&D\u{1f600}K': false}
-};
-Map<int, Map<String, int>> var199 = {
- -17: {'ybZg': -57, '(x\u{1f600}Tl': 6, '\u2665': -40, '3Xz6iOR': 32},
- 15: {'W\u2665rx': 2147483649, 'Q9Dn4Mf': 26, '7gV2i&c': -9223372032559808512},
- 36: {'7Nq5p': -65}
-};
-Map<int, Map<String, String>> var200 = {
- 15: {'VE&': '', 'xCki9Br': 'pR\u2665', 'j\u{1f600}': 'iV'}
-};
-Map<int, MapEntry<bool, bool>> var201 = {
- -9223372034707292160: MapEntry<bool, bool>(true, false)
-};
-Map<int, MapEntry<bool, int>> var202 = {
- -5: MapEntry<bool, int>(true, 11),
- -32: MapEntry<bool, int>(false, 39),
- -79: MapEntry<bool, int>(true, 49),
- -89: MapEntry<bool, int>(false, 43),
- 45: MapEntry<bool, int>(false, 22)
-};
-Map<int, MapEntry<bool, String>> var203 = {
- 33: MapEntry<bool, String>(true, 'zMmhEl#'),
- -72: MapEntry<bool, String>(true, 'o0a@Bv'),
- -76: MapEntry<bool, String>(false, '7 2d-'),
- 21: MapEntry<bool, String>(true, '+xtB!w'),
- -40: MapEntry<bool, String>(true, 'ac')
-};
-Map<int, MapEntry<int, bool>> var204 = {
- -14: MapEntry<int, bool>(14, true),
- -3: MapEntry<int, bool>(9, false),
- 33: MapEntry<int, bool>(43, true)
-};
-Map<int, MapEntry<int, int>> var205 = {-11: MapEntry<int, int>(46, 47)};
-Map<int, MapEntry<int, String>> var206 = {
- 25: MapEntry<int, String>(34, 'i'),
- 46: MapEntry<int, String>(24, '0\u26652'),
- 25: MapEntry<int, String>(31, '#g')
-};
-Map<int, MapEntry<String, bool>> var207 = {
- 9: MapEntry<String, bool>('q@P7', false),
- 28: MapEntry<String, bool>('v7BApvo', false),
- -4: MapEntry<String, bool>('&', true)
-};
-Map<int, MapEntry<String, int>> var208 = {
- 24: MapEntry<String, int>('', 29),
- 24: MapEntry<String, int>('GC', 14),
- 13: MapEntry<String, int>('iQ', 40),
- 42: MapEntry<String, int>('wS5nsdq', 39),
- 24: MapEntry<String, int>('e', 4),
- -97: MapEntry<String, int>('G\u2665', 49)
-};
-Map<int, MapEntry<String, String>> var209 = {
- -47: MapEntry<String, String>('ae#d!R', 'kI3g'),
- 48: MapEntry<String, String>('kp\u2665HmDw', ''),
- 34: MapEntry<String, String>('kf#', '\u2665'),
- 4294967297: MapEntry<String, String>('', '3WQ')
-};
-Map<String, Expando<bool>> var210 = {
- '6x\u{1f600}\u2665': Expando<bool>('t \u{1f600}#cuZ')
-};
-Map<String, Expando<int>> var211 = {
- '': new Expando<int>('9 iK7'),
- 'q\u2665V4v': Expando<int>('!WI'),
- '': Expando<int>('#Y'),
- '': Expando<int>('s\u{1f600}PQtMR'),
- 'xk': new Expando<int>('')
-};
-Map<String, Expando<String>> var212 = {
- '3bj': Expando<String>('(bBR\u{1f600}'),
- '+lvg\u{1f600}8': Expando<String>('HslP0fq'),
- 'rA11': Expando<String>('OIj7'),
- 'pOFk\u2665p\u2665': Expando<String>('')
-};
-Map<String, List<bool>> var213 = {
- 'Pp#': [false, true, true, false, true],
- 'kF\u{1f600}V\u{1f600}': [true, false, false, true]
-};
-Map<String, List<int>> var214 = {
- 'Mi1': [25, 10],
- 'E': Uint8List(12),
- 'a)\u26658dIb': Uint16List(26),
- 'RyfPfGs': Int64List(1),
- '\u{1f600}ro7Ld&': Int8List.fromList(Int16List.fromList(Uint8List(48))),
- '\u{1f600}+eIoZ@': Int16List.fromList(Uint32List.fromList(Int8List(7)))
-};
-Map<String, List<String>> var215 = {
- '&lVCT+(': ['AqlE\u2665', 'AM', 'k@NN\u2665'],
- 't': ['', '', 'm']
-};
-Map<String, Set<bool>> var216 = {
- 'M\u2665LS': {true, false, true},
- 'EY&-': {false, true},
- 'JL(&': {true, true, true},
- 'cbsKwv': {true, false},
- 'RxFq': {false, false, false, false, false}
-};
-Map<String, Set<int>> var217 = {
- '': {29, 4, -9223372030412324863},
- '': {-87, -29, -1},
- 'UKawkR': {-4, -49, -13, 48},
- '': {-88, 19},
- '': {-70, -57, -56, 41, 19}
-};
-Map<String, Set<String>> var218 = {
- '6L': {'8#On0\u2665', 'u8()Rs', 'D\u2665K', 'bl', 'c\u{1f600}('},
- '': {'w\u{1f600}RQr+', 'MOe', 'k OX2', '', 'RGP4d'},
- 'nndS6J': {'', 'C\u{1f600}(y9-6', 'lU\u{1f600}Y', '', '\u2665xulu)\u2665'},
- '\u{1f600}GiFU': {'', 'lHCkM', ''},
- '': {'6', '!(0S6'},
- '!\u2665': {'\u2665s\u{1f600}MSPe', '-3#XZ'}
-};
-Map<String, Map<bool, bool>> var219 = {
- 'yz539': {true: false},
- '\u2665cai\u2665lj': {false: false, true: true},
- 'qvZAFXL': {true: false, true: false, true: true, false: true},
- 'ss!G': {true: true, false: true},
- 'M': {false: false, false: true, true: true}
-};
-Map<String, Map<bool, int>> var220 = {
- 'vnaZiHB': {true: -13, false: 47, false: -11},
- 'I!#\u{1f600}i-': {true: 31, false: 34, false: 22, false: 27, false: -86},
- 'C': {false: -64, false: 4294967295},
- '': {true: -60, false: 40, true: 17},
- 'b': {true: 10, true: -11, false: 25}
-};
-Map<String, Map<bool, String>> var221 = {
- '5sr': {true: 'Bxl\u{1f600}nk\u2665'},
- 'DlxqF-s': {false: '+o9T'},
- '\u{1f600}lO!': {false: 'kdOB\u{1f600}9', false: '-cwUJ(1', false: 'Y+pX'},
- 'ljP': {false: 'mdcI', true: 'B7', false: 'in'},
- 'Me3': {
- true: 'uMS-',
- false: 'hQf5V7',
- false: 'tjj@d-',
- false: 'pw',
- true: 'n\u{1f600}'
- }
-};
-Map<String, Map<int, bool>> var222 = {
- 'G': {22: true, -51: true}
-};
-Map<String, Map<int, int>> var223 = {
- 'ooBph': {-73: 31, -50: -39, -2147483647: 3},
- '': {-73: 47},
- '3G@UXqo': {-73: -68, 24: -46},
- 'NasAQM)': {-13: 24, -36: 40}
-};
-Map<String, Map<int, String>> var224 = {
- '': {37: '(l+'},
- 'P7y!5Fp': {14: 'udi7l'},
- 'wx@y(': {-9223372030412324864: '\u{1f600}J', -84: ''},
- 'g': {16: 'P20(', -85: ''},
- 'T\u2665\u{1f600}!i': {-34: 'o', -88: 'l2fyoK'},
- 'y2l': {-77: '+qDu', -2147483647: 'P-f\u2665', -94: ''}
-};
-Map<String, Map<String, bool>> var225 = {
- 'TSvQ#g': {'7)': false, 'fUG': false, 'P@O#': true},
- 'GY\u2665CN1@': {
- '': false,
- '': true,
- '1&I\u{1f600}nCX': false,
- '\u2665G': true
- },
- '': {'G48al': false, 'k0i': false, 'Fy4': false},
- '': {
- 'Q#\u{1f600}': false,
- '8v': false,
- 'Cn': true,
- 'p@v#&Q': false,
- 's#Lsunk': true
- }
-};
-Map<String, Map<String, int>> var226 = {
- 'h4': {'bH@': -43, 'X': 6442450943},
- '\u{1f600}HYA)': {
- 'OyUyc': 11,
- '\u{1f600}pF\u{1f600}o': 1,
- '#VI': 39,
- '3DAIp\u2665i': 36
- },
- '#e yi\u{1f600}': {'vHpe': -96, '&8t': 27, 'z': -78, 'G03t': 8},
- 'B-nlX': {'\u{1f600}W': -3, 'gI': 36, 'ACX\u2665b': -54, 'JVQH': -94},
- 'G': {'smp': 17, 'v\u26654': -95, 'La': 48}
-};
-Map<String, Map<String, String>> var227 = {
- '\u{1f600}': {'jcRoE': '\u{1f600}2U\u{1f600}x', '18FqrQl': 'Qhh9', 'z': 'RY'},
- '77s': {'': 'kTdk6'},
- 'xF(': {'RC': 'h'},
- 'r': {'X': 'L\u2665\u26650', '2BH': ')F@', '2\u2665': '5'},
- 'GN': {'yI!!Sp': 'w9\u{1f600}p\u2665d', '&Uwf\u{1f600}G0': 'wVk'},
- 'Oi5M+': {'8nT\u26657f': 'hq', 'YD79\u2665': '\u2665yGpQi'}
-};
-Map<String, MapEntry<bool, bool>> var228 = {
- '\u{1f600}+0': MapEntry<bool, bool>(false, false),
- '\u{1f600}': MapEntry<bool, bool>(true, true),
- '': MapEntry<bool, bool>(true, false),
- 'P@': MapEntry<bool, bool>(false, false)
-};
-Map<String, MapEntry<bool, int>> var229 = {
- '\u{1f600}HDRH-': new MapEntry<bool, int>(false, 44),
- '\u2665F\u2665x': MapEntry<bool, int>(true, 25),
- '\u{1f600}': MapEntry<bool, int>(false, 36)
-};
-Map<String, MapEntry<bool, String>> var230 = {
- '': MapEntry<bool, String>(false, '\u{1f600}V')
-};
-Map<String, MapEntry<int, bool>> var231 = {
- 'QNiqVJ': MapEntry<int, bool>(9, false)
-};
-Map<String, MapEntry<int, int>> var232 = {
- 'BT5E4': new MapEntry<int, int>(36, 14),
- '\u2665 T89\u26659': MapEntry<int, int>(40, 3),
- '': MapEntry<int, int>(14, 13)
-};
-Map<String, MapEntry<int, String>> var233 = {
- '\u{1f600}P\u2665\u{1f600}i': MapEntry<int, String>(33, 'Z1Q\u{1f600}9M0'),
- '': MapEntry<int, String>(19, 'DcF4)'),
- 'OjM': MapEntry<int, String>(13, '\u2665PVgs'),
- '@+P': MapEntry<int, String>(2, '-O25'),
- '\u{1f600}\u2665M0V': MapEntry<int, String>(15, '\u{1f600}l\u266553'),
- ')8aC(G': MapEntry<int, String>(28, '')
-};
-Map<String, MapEntry<String, bool>> var234 = {
- '': MapEntry<String, bool>('', true),
- 'wuN': MapEntry<String, bool>('BYim@k', true),
- ' Af\u{1f600}SC': MapEntry<String, bool>('4V', true),
- 'x': MapEntry<String, bool>('W#C\u26652\u{1f600}', true)
-};
-Map<String, MapEntry<String, int>> var235 = {
- '0M\u266594L': MapEntry<String, int>('6CWY@N', 49),
- '6\u2665xy\u{1f600}': MapEntry<String, int>('2C', 41),
- '6w': MapEntry<String, int>('@7No', 33)
-};
-Map<String, MapEntry<String, String>> var236 = {
- '\u{1f600}l ': new MapEntry<String, String>('6KD', 'p1Q\u2665l08'),
- 'RBrvyj3': MapEntry<String, String>('t9M1qq', 'e\u{1f600}y!Esm'),
- '\u{1f600}Q3': MapEntry<String, String>('mQG)eT', 'L\u2665j'),
- 'gD': MapEntry<String, String>('bfwv', '0&47'),
- '@vD\u{1f600}': MapEntry<String, String>('2', 'x')
-};
-Map<Expando<bool>, bool> var237 = {
- Expando<bool>('6'): false,
- Expando<bool>('H&\u{1f600}Lc5'): false,
- Expando<bool>('I'): true
-};
-Map<Expando<bool>, int> var238 = {
- new Expando<bool>('('): 42,
- Expando<bool>('GbdYoW#'): -33,
- Expando<bool>(''): -71,
- new Expando<bool>(')zb'): -61
-};
-Map<Expando<bool>, String> var239 = {
- Expando<bool>('QiL8b'): '9',
- Expando<bool>(''): '3X'
-};
-Map<Expando<bool>, Expando<bool>> var240 = {
- Expando<bool>('gI2tZ'): Expando<bool>('EW)db8'),
- Expando<bool>('\u2665'): Expando<bool>('PaR'),
- Expando<bool>(''): new Expando<bool>('+HAws!N')
-};
-Map<Expando<bool>, Expando<int>> var241 = {
- Expando<bool>('u3'): Expando<int>('\u{1f600}'),
- Expando<bool>(''): Expando<int>('\u2665-AJG'),
- Expando<bool>('nZ'): Expando<int>('#7)@'),
- Expando<bool>('\u{1f600}I'): new Expando<int>('\u{1f600}m'),
- Expando<bool>('Ht'): Expando<int>('\u2665M')
-};
-Map<Expando<bool>, Expando<String>> var242 = {
- new Expando<bool>('s8 z2GH'): Expando<String>('\u2665r'),
- Expando<bool>('I'): Expando<String>('NI5\u2665'),
- Expando<bool>('\u2665N90\u{1f600}'): Expando<String>(''),
- Expando<bool>(')M00O'): Expando<String>('Osx'),
- Expando<bool>(''): Expando<String>('\u26659G'),
- Expando<bool>(' n9'): Expando<String>('fM')
-};
-Map<Expando<bool>, List<bool>> var243 = {
- Expando<bool>('cBQFP'): [false],
- Expando<bool>('\u{1f600}\u{1f600}P\u26655'): [true, true],
- Expando<bool>('V\u26657'): [true],
- Expando<bool>('L'): [true, true, true],
- new Expando<bool>('h@\u26659no'): [false, true]
-};
-Map<Expando<bool>, List<int>> var244 = {
- Expando<bool>('pY#bx'): Uint16List.fromList(Int8List.fromList([-11])),
- Expando<bool>('V8LZNv'): Int32List(41),
- Expando<bool>('kii'): Uint8List(4),
- Expando<bool>('gPCnM'): Uint32List.fromList(
- Int64List.fromList(Uint8List.fromList(Int16List(48)))),
- Expando<bool>(''): Int8List.fromList(Int8List(17))
-};
-Map<Expando<bool>, List<String>> var245 = {
- Expando<bool>('J!XE--p'): ['cI7A7R']
-};
-Map<Expando<bool>, Set<bool>> var246 = {
- Expando<bool>('f6EOenH'): {false, false, true, true, true},
- Expando<bool>('R'): {false, false, false, true},
- Expando<bool>('9o'): {false, true},
- Expando<bool>('d'): {false, false},
- Expando<bool>('L\u2665Ky'): {false}
-};
-Map<Expando<bool>, Set<int>> var247 = {
- Expando<bool>('1#9'): {11, 8, 32},
- new Expando<bool>('k4v7'): {-80, 26}
-};
-Map<Expando<bool>, Set<String>> var248 = {
- Expando<bool>('P\u{1f600}RYk'): {'2q', ''},
- Expando<bool>('mf7M8y9'): {'lXR51Q', '-4BCx6', ''},
- Expando<bool>('lVl'): {'V'},
- Expando<bool>('&9'): {'Gi2MU', 'TFc\u{1f600}', '7d2T\u{1f600}TO'},
- Expando<bool>('O\u{1f600}45\u2665'): {'\u{1f600}f8gx&y', 'O\u2665jn1A'}
-};
-Map<Expando<bool>, Map<bool, bool>> var249 = {
- Expando<bool>('d#qb\u{1f600}R'): {true: true},
- Expando<bool>('2'): {true: false},
- Expando<bool>('mUXc)F'): {
- true: false,
- true: false,
- false: false,
- false: false
- },
- Expando<bool>(''): {true: false, false: true, false: true, true: false},
- Expando<bool>('BF'): {true: false, true: false}
-};
-Map<Expando<bool>, Map<bool, int>> var250 = {
- Expando<bool>('x'): {true: 22, true: 18, false: -79, true: 29},
- Expando<bool>(''): {false: -1, true: -28, true: 4294967295, false: 48},
- Expando<bool>('kn'): {
- false: 0,
- false: -47,
- false: -17,
- false: -2147483647,
- true: 4294967297
- }
-};
-Map<Expando<bool>, Map<bool, String>> var251 = {
- Expando<bool>('Ox#4\u2665Uk'): {
- false: '\u26650VEl0',
- true: 'b',
- false: 'n2vLKn',
- false: 'jqB'
- },
- Expando<bool>('('): {
- true: 'K',
- false: '9\u{1f600}wY5fJ',
- true: 'W',
- true: 'aFkf',
- false: 'P'
- },
- Expando<bool>('zQJqbH'): {false: '&dp\u2665'},
- Expando<bool>('\u{1f600}\u{1f600}v(w'): {
- false: '8\u2665JYw1',
- false: '5NF',
- false: ''
- },
- Expando<bool>(''): {
- false: 'U7\u2665k8j',
- false: 'L',
- true: '',
- true: '#QU9beI'
- },
- Expando<bool>('1'): {false: 'IpqA\u{1f600}mK', false: 'Z6o', false: '!Xus'}
-};
-Map<Expando<bool>, Map<int, bool>> var252 = {
- Expando<bool>('t2ocMu'): {-2147483649: false, -50: true, -41: true}
-};
-Map<Expando<bool>, Map<int, int>> var253 = {
- Expando<bool>('x#6N\u2665'): {32: 42, 16: 16},
- Expando<bool>(''): {-3: -9223372032559808513, 9: 33, -97: -14, 37: 1},
- Expando<bool>('3Z@6'): {9223372034707292160: 15, -32: 2147483647, -38: 47},
- Expando<bool>('G'): {-7: -67, -9223372030412324863: -21, -69: 47, 42: 24}
-};
-Map<Expando<bool>, Map<int, String>> var254 = {
- Expando<bool>('+zuOBn'): {
- -19: 'n8',
- -77: '!T',
- -9223372034707292159: 'MV',
- -33: 'sd1Jim6'
- },
- Expando<bool>('4\u2665RNL'): {5: ')R'},
- Expando<bool>('cgE@ i'): {
- -9223372028264841217: 'an+bXm',
- 12: 'G-\u{1f600}',
- 4294967295: 'P8T'
- }
-};
-Map<Expando<bool>, Map<String, bool>> var255 = {
- Expando<bool>('&1\u2665('): {
- 'A\u{1f600}@': true,
- '3': true,
- 'Wm+q': true,
- '1T2Qzu5': true
- },
- Expando<bool>('t\u{1f600}F1'): {'hN': false},
- Expando<bool>('7sF\u{1f600}'): {'fbXP': false},
- new Expando<bool>('XdqyY\u{1f600}'): {
- '9': false,
- 'EQtm': true,
- '!16f(': false,
- '': false,
- 'Y8\u2665ZV': true
- },
- new Expando<bool>(''): {'': true, 't#bze4': true},
- Expando<bool>('oL)O\u2665'): {
- '0\u266517z': true,
- '@\u{1f600}@LSBL': true,
- 'oTzPe': false
- }
-};
-Map<Expando<bool>, Map<String, int>> var256 = {
- new Expando<bool>(''): {'99s': 32, 'hLsiuY!': 11, 'o\u2665Bh2': -83},
- Expando<bool>('kCg'): {'oE9!0M': -94, 'n&)QJ!k': -91},
- Expando<bool>(''): {
- 'Y\u{1f600}TE5\u{1f600}': -13,
- '': 24,
- '\u26652\u2665i\u{1f600}1': 0,
- 'nRj)PR': -9,
- 'l\u2665': 9
- },
- Expando<bool>('2nF2uuW'): {'6\u2665OOZ': 48, 'i': 47, '': 0}
-};
-Map<Expando<bool>, Map<String, String>> var257 = {
- Expando<bool>('CAw@Q'): {
- 'vCE\u2665j5': '',
- '\u{1f600}SWMUs': '',
- 'L\u{1f600}4J(': 'o&uCe',
- 'Gks@Gg\u{1f600}': 'HDWk-E',
- '': 'bB68L('
- },
- Expando<bool>('y2X5M\u2665'): {
- 'xhQ0ga8': 'iaKE\u{1f600}',
- 'f@': '-uX',
- '\u{1f600}U3\u2665x': '&N(7F',
- 'vF': 's#VUSTJ',
- '1M25d': 'Wy'
- },
- new Expando<bool>(''): {
- '1L': 'XCk\u{1f600}(#@',
- '0u': 'Ij',
- '&ga': '\u{1f600}3Y!',
- 'jw4': 'dPhwMu8'
- },
- Expando<bool>('\u2665Clpf#u'): {
- 'tkGRA\u2665&': 'iSsZh',
- 'cD\u2665': 'cp',
- 'l ': 'Rz',
- '7qnBOFC': 'qq\u2665'
- }
-};
-Map<Expando<bool>, MapEntry<bool, bool>> var258 = {
- Expando<bool>('9c'): MapEntry<bool, bool>(true, false),
- Expando<bool>(''): MapEntry<bool, bool>(true, false),
- new Expando<bool>('A&mY+ '): MapEntry<bool, bool>(false, false),
- Expando<bool>('Pi'): MapEntry<bool, bool>(false, false),
- Expando<bool>('30ZY\u2665W'): new MapEntry<bool, bool>(true, true)
-};
-Map<Expando<bool>, MapEntry<bool, int>> var259 = {
- Expando<bool>(''): new MapEntry<bool, int>(true, 9),
- Expando<bool>('6m\u{1f600}\u2665l'): MapEntry<bool, int>(true, 38),
- Expando<bool>('NP!'): MapEntry<bool, int>(false, 3),
- new Expando<bool>('JPhv(Xv'): MapEntry<bool, int>(true, 26)
-};
-Map<Expando<bool>, MapEntry<bool, String>> var260 = {
- Expando<bool>('T'): MapEntry<bool, String>(true, '!\u{1f600}x'),
- Expando<bool>('\u2665o'): MapEntry<bool, String>(false, 'sR'),
- new Expando<bool>('sm7umZ'): MapEntry<bool, String>(true, ''),
- Expando<bool>(''): MapEntry<bool, String>(true, 'FNU'),
- Expando<bool>('oh\u26658S9'): MapEntry<bool, String>(false, 'V ')
-};
-Map<Expando<bool>, MapEntry<int, bool>> var261 = {
- Expando<bool>('c\u{1f600}8d&PW'): MapEntry<int, bool>(34, false),
- Expando<bool>('b'): MapEntry<int, bool>(15, true),
- Expando<bool>('MxPZ-'): MapEntry<int, bool>(17, false),
- Expando<bool>('s7Pnm0k'): MapEntry<int, bool>(8, false)
-};
-Map<Expando<bool>, MapEntry<int, int>> var262 = {
- new Expando<bool>('gE@loMf'): MapEntry<int, int>(18, 44),
- Expando<bool>('bW\u{1f600}(5Y'): MapEntry<int, int>(26, 29),
- new Expando<bool>('&'): MapEntry<int, int>(33, 41),
- Expando<bool>('p1iZ2\u2665'): MapEntry<int, int>(15, 28),
- Expando<bool>('bFwdO'): MapEntry<int, int>(49, 24)
-};
-Map<Expando<bool>, MapEntry<int, String>> var263 = {
- Expando<bool>('P'): MapEntry<int, String>(31, '\u2665\u2665'),
- new Expando<bool>('jWi\u26650'): MapEntry<int, String>(3, 'en'),
- Expando<bool>('a'): MapEntry<int, String>(21, 'U8#H')
-};
-Map<Expando<bool>, MapEntry<String, bool>> var264 = {
- Expando<bool>('(Eq5 YW'): MapEntry<String, bool>('', true),
- new Expando<bool>('4!PVW9)'): MapEntry<String, bool>('5G', true),
- new Expando<bool>('\u{1f600}gZRjD'): MapEntry<String, bool>('T', false),
- Expando<bool>('vu1r(zF'): MapEntry<String, bool>('A7O4\u{1f600}0', false)
-};
-Map<Expando<bool>, MapEntry<String, int>> var265 = {
- Expando<bool>(''): MapEntry<String, int>('r\u2665p\u{1f600}w', 18),
- Expando<bool>('ey-F'): MapEntry<String, int>('I&', 0),
- Expando<bool>('!6cZ'): MapEntry<String, int>('B6A!yF', 1),
- Expando<bool>('RMzgo&'): MapEntry<String, int>('\u2665Puj', 13)
-};
-Map<Expando<bool>, MapEntry<String, String>> var266 = {
- Expando<bool>('0'): new MapEntry<String, String>('', 'U\u{1f600}pc')
-};
-Map<Expando<int>, bool> var267 = {
- Expando<int>('VOagX'): false,
- Expando<int>('Q m2f'): true,
- Expando<int>('0xpI7FY'): false
-};
-Map<Expando<int>, int> var268 = {
- new Expando<int>('q5lFA'): -51,
- Expando<int>('N\u{1f600}HO(\u26654'): -11
-};
-Map<Expando<int>, String> var269 = {
- new Expando<int>('EM'): '',
- Expando<int>('Em'): 'msFOdv'
-};
-Map<Expando<int>, Expando<bool>> var270 = {
- Expando<int>('x\u2665bRp3u'): Expando<bool>('Ac7L4')
-};
-Map<Expando<int>, Expando<int>> var271 = {
- Expando<int>('nY7re3'): Expando<int>('w\u2665vb'),
- Expando<int>('YF72B\u{1f600}7'): Expando<int>('F1bw\u{1f600}m'),
- new Expando<int>(''): Expando<int>('im\u{1f600}0+6'),
- Expando<int>('pBf'): Expando<int>('U97VKl')
-};
-Map<Expando<int>, Expando<String>> var272 = {
- Expando<int>('zoeD(XH'): Expando<String>('aj'),
- Expando<int>('!3nI1'): Expando<String>('q3BW')
-};
-Map<Expando<int>, List<bool>> var273 = {
- Expando<int>('3bOR\u2665h'): [true, true, false, true],
- Expando<int>('E'): [true],
- Expando<int>('a\u2665I6'): [true, false, true, false]
-};
-Map<Expando<int>, List<int>> var274 = {
- Expando<int>('k\u2665a'): Int8List(39),
- new Expando<int>('z6H+'): Int32List(29),
- Expando<int>('@\u2665f\u2665Clu'):
- Int8List.fromList(Uint32List.fromList(Int32List(7))),
- Expando<int>(''): Int32List.fromList(Uint8ClampedList(44))
-};
-Map<Expando<int>, List<String>> var275 = {
- Expando<int>('rot'): ['sYkag', '\u2665Thw\u{1f600}h#', '\u2665T'],
- new Expando<int>('g1X'): ['\u2665@#d\u2665wc', 'DJG6', 'f', 'sQ!', 'Q-X2Q'],
- Expando<int>('oc&g\u{1f600}'): ['', 'GqtHGR', '\u{1f600}'],
- Expando<int>('\u2665F)W'): ['Nvc\u2665GkW'],
- Expando<int>(')+J'): ['ae588'],
- Expando<int>('Rq\u266526b'): ['4Zt0', 'mB', '', 'ZW', 'lg23vG']
-};
-Map<Expando<int>, Set<bool>> var276 = {
- Expando<int>('3!fxt'): {true, false, true},
- Expando<int>(''): {false, false, true, false}
-};
-Map<Expando<int>, Set<int>> var277 = {
- Expando<int>('vAxC'): {-81, 28},
- Expando<int>('yA\u2665VIue'): {-19},
- Expando<int>('o'): {28, 9223372034707292161, 45, 40, -91},
- Expando<int>('ZiYVP'): {22},
- Expando<int>('0IBG'): {1, 15, 20, 22, -93},
- Expando<int>('TE3mIt '): {-43, -70, -31, -83, -55}
-};
-Map<Expando<int>, Set<String>> var278 = {
- Expando<int>('4j\u2665tN'): {
- '634@',
- '\u{1f600}aVQxt3',
- 'K7\u{1f600}s',
- '-2b',
- 'hirU'
- },
- Expando<int>('3t'): {'pR\u2665', 'n!H-Wm'},
- Expando<int>(''): {'', 'r'},
- Expando<int>('\u{1f600}!83F-'): {'Lnm2W'},
- Expando<int>('v2Ct2q'): {'AxUFNZ', 'z', 'XCN4U\u{1f600}-', '\u2665JP'},
- Expando<int>(''): {'S-', '4(\u{1f600}BOlO'}
-};
-Map<Expando<int>, Map<bool, bool>> var279 = {
- Expando<int>('cx9I'): {
- false: true,
- true: false,
- false: false,
- false: true,
- true: true
- },
- Expando<int>('\u2665N7On'): {true: false, true: true}
-};
-Map<Expando<int>, Map<bool, int>> var280 = {
- Expando<int>('Hvv'): {true: 4, true: -78, true: -9223372034707292160},
- Expando<int>('4dZ9sbZ'): {true: 32, true: 37, true: -29, true: -41},
- Expando<int>('kE\u2665bg'): {
- true: -1,
- true: 9223372036854775807,
- false: 10,
- true: -75
- },
- Expando<int>(')B\u2665s '): {true: 2, true: 19, true: -27, true: 31}
-};
-Map<Expando<int>, Map<bool, String>> var281 = {
- Expando<int>(''): {
- true: 'ccZ',
- true: 'UQ20S',
- true: 'b\u{1f600}FWSv',
- true: ' -Vj\u26656x',
- true: '@S\u{1f600}(K'
- },
- Expando<int>('5J'): {true: ')nz&', false: 'L&M\u{1f600}d', false: 'H P'}
-};
-Map<Expando<int>, Map<int, bool>> var282 = {
- Expando<int>('MUD '): {-9223372034707292160: false},
- Expando<int>('3J'): {7: true, 23: false, 0: false, -71: false, -14: false},
- Expando<int>('n'): {
- -9223372034707292159: true,
- -2147483649: true,
- -16: true,
- 42: false
- }
-};
-Map<Expando<int>, Map<int, int>> var283 = {
- Expando<int>('ldfJ'): {
- -13: 48,
- 0: -61,
- -9223372036854775808: 19,
- 9223372032559808513: 4294967295
- },
- Expando<int>('PnV\u{1f600}'): {46: -48},
- Expando<int>('qk0'): {-56: -32}
-};
-Map<Expando<int>, Map<int, String>> var284 = {
- Expando<int>('tz Cn'): {7: 'bnwz\u2665yy', 43: '1TEDPk', 4: 'Lxd'}
-};
-Map<Expando<int>, Map<String, bool>> var285 = {
- Expando<int>('9g4fB'): {'': true},
- new Expando<int>('&'): {'@': false},
- Expando<int>('FK!g)UY'): {'\u2665': true},
- Expando<int>('n8'): {'Q#dp02': true},
- Expando<int>('lI#'): {
- '4avZeg': true,
- 'X': false,
- 'N\u{1f600}Rw\u2665w!': true
- }
-};
-Map<Expando<int>, Map<String, int>> var286 = {
- Expando<int>('Wuvk'): {
- 'D@rqA': 30,
- 'Co5': -98,
- 'j': 41,
- '\u26655d': -9223372032559808513
- }
-};
-Map<Expando<int>, Map<String, String>> var287 = {
- new Expando<int>('Uakek5m'): {
- 'Uvp\u{1f600}': '1@',
- 'z Tm\u{1f600}\u{1f600}': '-34n\u26656V',
- 'gG': ''
- },
- Expando<int>(''): {'mjY@s': '0\u2665\u{1f600}X', '5m(hR': '', '': 'SnT'},
- Expando<int>('R\u2665IQ7a'): {'dMY': 'R\u2665v', '!\u{1f600}': 'x&V(LU'},
- Expando<int>('iB0'): {'tN)': 'zFOk\u2665rn'},
- Expando<int>('6Zu5S'): {'\u{1f600}T r\u2665-': 'Vb'}
-};
-Map<Expando<int>, MapEntry<bool, bool>> var288 = {
- Expando<int>('7'): MapEntry<bool, bool>(true, false),
- Expando<int>('\u2665nx'): MapEntry<bool, bool>(false, false),
- Expando<int>('\u2665Q2KP\u2665'): MapEntry<bool, bool>(false, true),
- Expando<int>('hrc6\u2665Ts'): MapEntry<bool, bool>(true, false),
- Expando<int>('tDFwT'): MapEntry<bool, bool>(false, false)
-};
-Map<Expando<int>, MapEntry<bool, int>> var289 = {
- Expando<int>('IUcO 16'): MapEntry<bool, int>(true, 11)
-};
-Map<Expando<int>, MapEntry<bool, String>> var290 = {
- Expando<int>(')'): MapEntry<bool, String>(false, 'o&a'),
- Expando<int>('KCFkBPC'): MapEntry<bool, String>(false, ''),
- Expando<int>('OC\u2665GSo9'): MapEntry<bool, String>(false, 'g9\u{1f600}@r('),
- new Expando<int>('bX'): MapEntry<bool, String>(false, 'r('),
- Expando<int>('NV'): MapEntry<bool, String>(false, ''),
- Expando<int>('\u{1f600}4y'): MapEntry<bool, String>(true, 'YTb\u{1f600}')
-};
-Map<Expando<int>, MapEntry<int, bool>> var291 = {
- Expando<int>('k\u2665SXw'): MapEntry<int, bool>(32, false)
-};
-Map<Expando<int>, MapEntry<int, int>> var292 = {
- Expando<int>('\u{1f600}h'): MapEntry<int, int>(0, 18),
- Expando<int>(''): MapEntry<int, int>(18, 15),
- Expando<int>('H\u{1f600}'): MapEntry<int, int>(10, 29),
- Expando<int>('&x'): MapEntry<int, int>(36, 0),
- Expando<int>('J'): MapEntry<int, int>(47, 43)
-};
-Map<Expando<int>, MapEntry<int, String>> var293 = {
- Expando<int>(''): MapEntry<int, String>(19, 'gCDV1'),
- Expando<int>('&lQLHS'): MapEntry<int, String>(37, '\u2665'),
- Expando<int>('d'): MapEntry<int, String>(29, '9Ps'),
- Expando<int>('e'): MapEntry<int, String>(45, 'mkF')
-};
-Map<Expando<int>, MapEntry<String, bool>> var294 = {
- Expando<int>('\u2665b6ml4'): MapEntry<String, bool>('z8\u2665', false),
- Expando<int>('3iA'): MapEntry<String, bool>('JE@v', false),
- Expando<int>('DA'): MapEntry<String, bool>('cA\u2665', false),
- Expando<int>('\u2665\u2665jwNR'): new MapEntry<String, bool>('', true)
-};
-Map<Expando<int>, MapEntry<String, int>> var295 = {
- new Expando<int>('pYU'): MapEntry<String, int>('', 26)
-};
-Map<Expando<int>, MapEntry<String, String>> var296 = {
- Expando<int>('X8\u2665\u{1f600}'):
- new MapEntry<String, String>('Fc', 'ze\u2665'),
- Expando<int>('B3gz'): MapEntry<String, String>('BiG#', 'g')
-};
-Map<Expando<String>, bool> var297 = {
- Expando<String>('62KtgN'): true,
- new Expando<String>('ob'): false
-};
-Map<Expando<String>, int> var298 = {
- Expando<String>(''): 0,
- Expando<String>(''): 7,
- Expando<String>('FN1ut'): -63
-};
-Map<Expando<String>, String> var299 = {
- Expando<String>('!Hnw!1F'): '\u{1f600}',
- Expando<String>('8XtB'): 'Q',
- Expando<String>('JTs'): 'kYXwZ!',
- Expando<String>('cu\u{1f600}P1D)'): 'nl',
- Expando<String>('q Vy'): 'a',
- Expando<String>('0'): 'hy'
-};
-Map<Expando<String>, Expando<bool>> var300 = {
- Expando<String>('n'): new Expando<bool>('#v7'),
- Expando<String>('I\u{1f600}DU+bp'): Expando<bool>('f&'),
- Expando<String>('\u{1f600}+RV'): Expando<bool>('ZOayLo'),
- Expando<String>(')\u2665\u2665p\u{1f600}cf'): new Expando<bool>('Xm'),
- Expando<String>('X(nV+nY'): Expando<bool>('1b'),
- Expando<String>('ti\u2665'): Expando<bool>(' ')
-};
-Map<Expando<String>, Expando<int>> var301 = {
- Expando<String>('wa@r-wY'): Expando<int>('Q'),
- Expando<String>('+8YcLq'): Expando<int>(''),
- Expando<String>('bMC\u2665'): Expando<int>('urG2w'),
- Expando<String>('Se\u2665#e\u{1f600}'): Expando<int>('@F\u2665V B')
-};
-Map<Expando<String>, Expando<String>> var302 = {
- Expando<String>(''): Expando<String>('A&'),
- Expando<String>('Z)#K'): Expando<String>('H(UiG'),
- Expando<String>('D1ONM+'): new Expando<String>('Z'),
- Expando<String>('5+&aO9#'): Expando<String>('\u{1f600}V'),
- Expando<String>('0l&Nbvs'): Expando<String>(')N(C2'),
- Expando<String>('vfM'): Expando<String>('')
-};
-Map<Expando<String>, List<bool>> var303 = {
- Expando<String>('r88'): [true, false, false],
- Expando<String>('gj'): [true, true, true, true, true],
- Expando<String>('FX'): [true, true, false, true],
- Expando<String>('I3F'): [true, false],
- Expando<String>(''): [false, true, true, true, true]
-};
-Map<Expando<String>, List<int>> var304 = {
- Expando<String>('aS'): [-9223372034707292159, 11, 15, 9223372034707292160],
- Expando<String>('u'): Uint64List.fromList(
- Uint32List.fromList(Uint8ClampedList.fromList(Int16List(10))))
-};
-Map<Expando<String>, List<String>> var305 = {
- Expando<String>('M+\u{1f600}\u{1f600}re'): ['ylMIq(\u2665', ''],
- Expando<String>('X'): ['j4fRH', 'q\u2665', '3d\u2665Cy\u{1f600}k']
-};
-Map<Expando<String>, Set<bool>> var306 = {
- Expando<String>('+rNw'): {true, false},
- Expando<String>('zp1nkT'): {false},
- Expando<String>(''): {false}
-};
-Map<Expando<String>, Set<int>> var307 = {
- Expando<String>('KnRY'): {44, 4294967296, 4294967296, -36, -75},
- Expando<String>(''): {26, -43},
- new Expando<String>('M@Tco'): {-21},
- Expando<String>('qe)f'): {29, -82, 35, -30}
-};
-Map<Expando<String>, Set<String>> var308 = {
- new Expando<String>('HnVl'): {'\u{1f600}5z5'},
- Expando<String>(''): {'\u{1f600}', '9ugafm', '7e\u{1f600}', 'W9', 'f\u2665'}
-};
-Map<Expando<String>, Map<bool, bool>> var309 = {
- Expando<String>('t2\u{1f600}m15p'): {
- true: true,
- false: false,
- true: true,
- true: false,
- true: false
- }
-};
-Map<Expando<String>, Map<bool, int>> var310 = {
- Expando<String>('cG@\u2665\u2665W'): {
- true: -28,
- false: -2147483649,
- false: -73,
- true: -65
- },
- Expando<String>('gL\u2665'): {false: -46, true: 46, false: -11},
- Expando<String>('E1'): {true: -96}
-};
-Map<Expando<String>, Map<bool, String>> var311 = {
- Expando<String>('&+@+pDj'): {true: '\u2665a\u26650W', true: 'xVzZ', true: '7'}
-};
-Map<Expando<String>, Map<int, bool>> var312 = {
- Expando<String>('TxM(O&#'): {-13: false, -75: false, -46: false},
- Expando<String>('PVASZn\u2665'): {33: true, -68: false, 15: false},
- new Expando<String>('c'): {-3: true}
-};
-Map<Expando<String>, Map<int, int>> var313 = {
- Expando<String>('\u26650DstdF'): {
- 42: -91,
- -9223372030412324865: 46,
- 23: -1,
- -70: 18
- },
- Expando<String>(''): {-72: 31, -84: 34, -85: 19, -12: 43},
- Expando<String>('T0Y'): {5: -11},
- Expando<String>('\u{1f600}Z!O'): {
- 48: 9223372032559808512,
- 6442450945: -28,
- 22: -79,
- -59: -67,
- -58: 8589934591
- },
- Expando<String>(''): {32: 43, 25: 47, -73: -5, -0: 16},
- Expando<String>('\u2665qFIcms'): {-87: 9223372034707292161}
-};
-Map<Expando<String>, Map<int, String>> var314 = {
- Expando<String>('PPM'): {-92: 'L9Bl'},
- Expando<String>('bX'): {-69: '7\u{1f600}\u{1f600}'},
- Expando<String>('\u{1f600}'): {37: '-sRbe'},
- Expando<String>('eW&S'): {
- -90: 'Ji)0\u2665Kx',
- -9223372032559808511: 'YWh\u2665x@',
- -78: 'ZZ-p4',
- -84: 'GOeNvs'
- }
-};
-Map<Expando<String>, Map<String, bool>> var315 = {
- Expando<String>('6&'): {
- 'gkm\u2665Q': true,
- '!ka': false,
- 'nd': false,
- '8': true,
- '': true
- },
- Expando<String>('Zs\u26656cL'): {
- '2r4mm': false,
- 'KO74': false,
- 'aK2Q': false,
- 'EVma-7': true,
- 'qHAifN': true
- },
- Expando<String>('AZI'): {
- '': false,
- 'gs': true,
- '': true,
- '': true,
- '7\u{1f600}73': false
- },
- Expando<String>('z5K\u2665Q1s'): {
- 'ma': false,
- '\u{1f600}': false,
- 'X)\u2665&0': true
- },
- Expando<String>('\u26659\u2665b@aA'): {'s89F+@': true, 'KTci': false},
- Expando<String>('WN\u{1f600} \u2665'): {
- 'RGtehh': false,
- 'JjY\u{1f600}': false,
- 'LgM-': false,
- 'YJlako': true
- }
-};
-Map<Expando<String>, Map<String, int>> var316 = {
- Expando<String>('\u{1f600}hOK@l'): {
- 'J9SG#0y': -47,
- '\u2665': -31,
- '\u26651\u{1f600}b&\u2665': -35,
- '-vWorUT': 17,
- '6': 5
- },
- Expando<String>('\u{1f600}Vl'): {'\u{1f600}': 34, 'GK7vI8r': 23, '': 4},
- Expando<String>('Ez!'): {
- 'u': 45,
- 'd2\u{1f600}HZg': 9223372032559808512,
- 'czAE 1I': 37,
- 'H\u26656': -72,
- '': 9223372034707292160
- }
-};
-Map<Expando<String>, Map<String, String>> var317 = {
- Expando<String>('(mh'): {'yt\u2665TIh': '\u{1f600}U'},
- Expando<String>('edV'): {
- 'Rl3GQy': 'OI',
- 'D\u{1f600}8W': 'HboKy@P',
- 'a': 'I9\u2665!B',
- '': ')'
- }
-};
-Map<Expando<String>, MapEntry<bool, bool>> var318 = {
- Expando<String>('y-azeFH'): MapEntry<bool, bool>(true, true),
- new Expando<String>('0RB'): MapEntry<bool, bool>(false, true),
- new Expando<String>('\u{1f600}+8'): MapEntry<bool, bool>(false, true),
- Expando<String>('KJ)45t'): MapEntry<bool, bool>(true, false)
-};
-Map<Expando<String>, MapEntry<bool, int>> var319 = {
- Expando<String>('s3'): MapEntry<bool, int>(true, 18),
- Expando<String>('g\u2665c'): MapEntry<bool, int>(false, 20)
-};
-Map<Expando<String>, MapEntry<bool, String>> var320 = {
- Expando<String>('!0eCTrN'): MapEntry<bool, String>(true, ''),
- Expando<String>('MP\u{1f600}\u{1f600}'):
- new MapEntry<bool, String>(false, 'iHk\u{1f600}B'),
- Expando<String>('@\u{1f600}'): MapEntry<bool, String>(true, ' o'),
- Expando<String>('cC!OWT'): MapEntry<bool, String>(true, ''),
- Expando<String>('Im\u{1f600}@1\u26655'): MapEntry<bool, String>(true, '04'),
- new Expando<String>(''): MapEntry<bool, String>(true, '&QHf9')
-};
-Map<Expando<String>, MapEntry<int, bool>> var321 = {
- Expando<String>('j'): MapEntry<int, bool>(3, false)
-};
-Map<Expando<String>, MapEntry<int, int>> var322 = {
- Expando<String>('cxH1x5x'): new MapEntry<int, int>(24, 45)
-};
-Map<Expando<String>, MapEntry<int, String>> var323 = {
- new Expando<String>('D'): MapEntry<int, String>(26, '3pM'),
- Expando<String>('\u2665UZU'): MapEntry<int, String>(22, '&pLKM-\u{1f600}'),
- Expando<String>('9g'): MapEntry<int, String>(40, '\u2665xw+mD')
-};
-Map<Expando<String>, MapEntry<String, bool>> var324 = {
- Expando<String>('\u2665\u2665'): MapEntry<String, bool>('', true),
- Expando<String>('f#keD\u2665!'):
- MapEntry<String, bool>('6&\u{1f600}3CI', false),
- Expando<String>('\u2665\u{1f600}Z6EZ'): MapEntry<String, bool>('X27', true),
- Expando<String>('GFz67r'): MapEntry<String, bool>('D \u{1f600}e', false),
- Expando<String>('AU I'): new MapEntry<String, bool>('P', false)
-};
-Map<Expando<String>, MapEntry<String, int>> var325 = {
- Expando<String>('wW&+xMm'): MapEntry<String, int>('#CXm\u2665\u2665v', 2),
- Expando<String>('qE\u2665Ro '): new MapEntry<String, int>('vl))#T', 4)
-};
-Map<Expando<String>, MapEntry<String, String>> var326 = {
- Expando<String>('Pj'):
- new MapEntry<String, String>('6\u266513A7', 'rz\u2665qxs'),
- new Expando<String>('AqZ!q'): MapEntry<String, String>('AT', 'hyk'),
- Expando<String>(''): MapEntry<String, String>('', 'kRuj'),
- Expando<String>('@a-P'): MapEntry<String, String>('3qxy4', 'M8pKtYU'),
- Expando<String>('\u2665n'): MapEntry<String, String>('CXT&uR', 't#T'),
- Expando<String>('E4\u{1f600}Z@'): MapEntry<String, String>('m', 'Qh\u{1f600}')
-};
-Map<List<bool>, bool> var327 = {
- [false, false]: false,
- [false, true, true]: false,
- [false]: true,
- [false]: true,
- [true, true, false]: true,
- [true, false]: false
-};
-Map<List<bool>, int> var328 = {
- [true, true, true, true]: -54
-};
-Map<List<bool>, String> var329 = {
- [true, true]: 'r'
-};
-Map<List<bool>, Expando<bool>> var330 = {
- [true, true, true]: Expando<bool>('!jj\u{1f600}0Am'),
- [true, false, true]: Expando<bool>(''),
- [false, true, false, true]: Expando<bool>('-H'),
- [false]: Expando<bool>('K6q')
-};
-Map<List<bool>, Expando<int>> var331 = {
- [false, false, true]: Expando<int>('uH-Vc\u{1f600}'),
- [true, true, false, true, false]: Expando<int>('P'),
- [false, false, false, false]: Expando<int>('lM')
-};
-Map<List<bool>, Expando<String>> var332 = {
- [true]: Expando<String>('i75veY'),
- [false, true]: Expando<String>('oM!'),
- [false, true, false]: Expando<String>(''),
- [true, true, true]: Expando<String>('8aeOcF\u{1f600}'),
- [false, false, true]: Expando<String>('U+s'),
- [false, true, true]: Expando<String>('qg@\u2665O')
-};
-Map<List<bool>, List<bool>> var333 = {
- [false, true, false, true, false]: [true],
- [true, true, false]: [true, false, true],
- [true, true, false, true, false]: [false, true]
-};
-Map<List<bool>, List<int>> var334 = {
- [true, true]: new Int32List(43),
- [true]: Uint8List.fromList(Uint32List.fromList(Int64List(12)))
-};
-Map<List<bool>, List<String>> var335 = {
- [false]: ['7bY9@']
-};
-Map<List<bool>, Set<bool>> var336 = {
- [true, true, true, true, false]: {true, true, false},
- [false, true, true, true]: {true, false, false, false},
- [false, true, false, false, true]: {false},
- [true, false, true, true]: {true, false},
- [false, true, false, false, false]: {true, true, true},
- [false]: {true, false, true, false}
-};
-Map<List<bool>, Set<int>> var337 = {
- [true, false, true]: {20, -51, 6442450943, 27, 41},
- [true, true]: {-14, 40, 26, -41}
-};
-Map<List<bool>, Set<String>> var338 = {
- [false]: {'o&+KL', 'eP', '', 'tDxa'},
- [true, false, true, false, false]: {'DMjCmq'}
-};
-Map<List<bool>, Map<bool, bool>> var339 = {
- [false, true]: {false: true, false: true},
- [false, false]: {
- true: true,
- true: false,
- false: false,
- false: true,
- true: true
- },
- [true, false]: {true: true},
- [false, false, true, true, false]: {false: true, false: false, false: false},
- [true, false, true, false, false]: {
- false: false,
- true: false,
- false: false,
- true: true,
- false: false
- }
-};
-Map<List<bool>, Map<bool, int>> var340 = {
- [true]: {true: -74, false: 6442450943, false: 26, true: -44}
-};
-Map<List<bool>, Map<bool, String>> var341 = {
- [true, true]: {
- true: '\u2665()\u{1f600}',
- false: '+',
- true: 'p4\u{1f600}3',
- false: 'i',
- true: 'D'
- },
- [false, false]: {false: '', true: '7b'},
- [false, true]: {
- true: 's',
- true: 'O\u2665r',
- false: 'W',
- false: ' H499i',
- true: 'U\u2665Z-Md'
- },
- [true, false, true]: {true: 'LU'},
- [true, false, false]: {
- false: 'T&c',
- true: 'Z0 6\u{1f600}dA',
- false: 's(Jt38q'
- }
-};
-Map<List<bool>, Map<int, bool>> var342 = {
- [true, true, true, true, true]: {21: true},
- [true, true, true]: {-38: false, 33: false}
-};
-Map<List<bool>, Map<int, int>> var343 = {
- [true, false]: {38: 36, 46: 32, -88: -10, -9223372030412324863: -15},
- [true, false, true, true, true]: {14: -22, 9: 21, 45: 39},
- [true, false, true, false]: {9223372034707292161: -1, 0: 34, 4294967296: -32}
-};
-Map<List<bool>, Map<int, String>> var344 = {
- [false, true]: {36: 'hPH'},
- [false, true, true, true, false]: {
- 3: 'Cz\u2665)Q1',
- 44: '\u{1f600}t\u{1f600}',
- -24: 'Sb',
- 27: 'mZi'
- },
- [false, true]: {
- -54: '\u266520\u{1f600}b',
- 19: '7UJf',
- 1: 'ZPkJgl',
- -74: 'Sf1xxUN',
- 25: 'N'
- },
- [true, true, true, true]: {7: 'a\u266589w', -59: 'vg', -91: 'zvFq'}
-};
-Map<List<bool>, Map<String, bool>> var345 = {
- [false]: {'A)!8bIp': true},
- [true, true, true, false, true]: {'OP': true}
-};
-Map<List<bool>, Map<String, int>> var346 = {
- [false, false]: {
- '7KGnR2Y': -96,
- 'n\u2665A\u{1f600}': 40,
- '\u{1f600}': -9223372034707292161
- },
- [true, true, false, true]: {'K': 37, '': 38, '!m-#': -49},
- [true, false]: {'zsO6Sk\u{1f600}': 8},
- [true]: {'Q': 2147483649, 'RE8': 43, 'tM24b6y': -50, '2\u2665P\u2665WL': -43},
- [true, true]: {'m': 15, '': 11}
-};
-Map<List<bool>, Map<String, String>> var347 = {
- [true]: {'6&oz-T': 'vh!A', 'tb\u2665': '9q'},
- [true, false, false, false]: {'o': 'jA\u{1f600}', '6#S 0e': 'TA'},
- [true, true, true]: {
- '4abo': '',
- 'f': 'G19z',
- 't5As': 'LoMBQ',
- 'X\u{1f600}O': 'N5'
- },
- [false, false]: {
- '&6qzt': '2w',
- 'ylk ': 'z8o',
- 'KM!#br': 'Er\u{1f600}pw5M',
- 'J(I\u{1f600}': '\u{1f600}RX9\u2665c'
- },
- [false, true, false]: {
- 'uX': 'i9\u{1f600}6XU',
- 'z6R': '#WQ(W',
- 'Wy2': 'g(',
- 'Qr': '+'
- },
- [true, false, true, true, false]: {
- 'NhX\u{1f600}': '5rQt\u26650w',
- ')nFFr': 'tTzqg',
- '1': '&EPc1V',
- 'IU4U p': '-W\u{1f600}7I',
- 'P6': '5'
- }
-};
-Map<List<bool>, MapEntry<bool, bool>> var348 = {
- [false, false]: new MapEntry<bool, bool>(false, false),
- [true, true]: MapEntry<bool, bool>(false, false),
- [true, true, false, false, true]: MapEntry<bool, bool>(true, true),
- [true, true, true, true]: MapEntry<bool, bool>(false, true)
-};
-Map<List<bool>, MapEntry<bool, int>> var349 = {
- [false, false, true, false, false]: MapEntry<bool, int>(false, 11),
- [false, true, true, false, true]: MapEntry<bool, int>(false, 5),
- [true, true, true]: MapEntry<bool, int>(false, 9),
- [true, false]: MapEntry<bool, int>(false, 3)
-};
-Map<List<bool>, MapEntry<bool, String>> var350 = {
- [true, true, true]: MapEntry<bool, String>(true, '\u2665up'),
- [false, true, false]: MapEntry<bool, String>(true, '&x5m')
-};
-Map<List<bool>, MapEntry<int, bool>> var351 = {
- [false, true, false]: new MapEntry<int, bool>(38, false),
- [false, false, false, true, false]: MapEntry<int, bool>(10, false),
- [false, true, false, true]: MapEntry<int, bool>(11, false),
- [true]: MapEntry<int, bool>(12, true)
-};
-Map<List<bool>, MapEntry<int, int>> var352 = {
- [true, false, true]: MapEntry<int, int>(8, 39),
- [true, false]: new MapEntry<int, int>(49, 22)
-};
-Map<List<bool>, MapEntry<int, String>> var353 = {
- [false, false, true, false, true]: MapEntry<int, String>(21, 'xFRNS)'),
- [true, false]: MapEntry<int, String>(10, 'QI6EIS'),
- [true, false, false, true]: MapEntry<int, String>(17, 'Bg\u{1f600}'),
- [false, true, false]: MapEntry<int, String>(9, '#t\u{1f600}\u2665 ')
-};
-Map<List<bool>, MapEntry<String, bool>> var354 = {
- [false]: MapEntry<String, bool>('keI', true),
- [false, true, false]: new MapEntry<String, bool>('b', true),
- [true]: new MapEntry<String, bool>('Sc', false)
-};
-Map<List<bool>, MapEntry<String, int>> var355 = {
- [true, true, true]: new MapEntry<String, int>('K8i', 48),
- [true]: MapEntry<String, int>('7W', 4),
- [false, false]: MapEntry<String, int>('2S)V#6', 21),
- [true, false, false, false]: MapEntry<String, int>('', 9)
-};
-Map<List<bool>, MapEntry<String, String>> var356 = {
- [false, true, false, false]: MapEntry<String, String>('', '&i8Kd\u{1f600}'),
- [false, false, true, true]: MapEntry<String, String>('BDT0u2y', 'bu'),
- [true, false, false, false]: MapEntry<String, String>('', 'Fpe1am'),
- [false, false, false]: MapEntry<String, String>('0-t', ''),
- [false, true, true]: MapEntry<String, String>('m!(00', '5W(HW')
-};
-Map<List<int>, bool> var357 = {
- Uint8List.fromList(Uint64List.fromList(Int16List.fromList(Int8List(24)))):
- true,
- Int16List.fromList(Int8List(39)): false,
- Uint64List.fromList(Int16List(5)): true,
- Uint32List(21): false,
- [-43, -9223372034707292161]: true
-};
-Map<List<int>, int> var358 = {
- Uint16List(0): 23,
- Uint64List.fromList(Int32List.fromList(Int8List(42))): 31,
- Uint64List.fromList(Uint8ClampedList.fromList(Uint8ClampedList(30))): -8
-};
-Map<List<int>, String> var359 = {
- Int16List.fromList([13, -53, 12]): '2Hkp',
- Int64List.fromList(Int32List(48)): 'pE 0&Kb',
- [-42, -49, 2147483649]: '34dma'
-};
-Map<List<int>, Expando<bool>> var360 = {
- new Uint32List(39): new Expando<bool>('rA)\u2665b'),
- [-3, 4, -61, -89, -51]: Expando<bool>('RLx)WgD'),
- [-69, -50]: Expando<bool>(''),
- Uint16List.fromList(Int64List.fromList(Uint8ClampedList(7))):
- Expando<bool>('U'),
- [1, 47]: Expando<bool>('EvNqpv')
-};
-Map<List<int>, Expando<int>> var361 = {
- [40, -97, 47, 17]: Expando<int>(''),
- [-9223372030412324863, -91, -9]: new Expando<int>('SjfAOV0')
-};
-Map<List<int>, Expando<String>> var362 = {
- Uint64List.fromList(
- Uint8ClampedList.fromList(Int8List.fromList(Uint16List(47)))):
- new Expando<String>('rS(YMW')
-};
-Map<List<int>, List<bool>> var363 = {
- Int64List.fromList([-68, 2]): [false, false, true, true],
- Uint8ClampedList(7): [false, false, true, true, true],
- Uint32List(11): [false, false, false],
- Uint8ClampedList(39): [false, true, true, false, false],
- Uint32List(32): [false, false]
-};
-Map<List<int>, List<int>> var364 = {
- Uint16List.fromList(Int32List(30)): Int16List.fromList(Uint64List(41)),
- Uint64List(5): Uint8ClampedList(15),
- Uint8List.fromList(
- Uint16List.fromList(Uint8ClampedList.fromList(Int8List(29)))):
- Int8List(7),
- Uint64List(16): Uint8List.fromList(
- Uint8ClampedList.fromList(Int8List.fromList(new Uint32List(14)))),
- [22, 49, 7, -22, 16]:
- Int32List.fromList(Int64List.fromList(Uint8ClampedList(18)))
-};
-Map<List<int>, List<String>> var365 = {
- Uint8ClampedList(35): ['', '!', '!', '5N9\u{1f600}', 'H'],
- Uint64List.fromList(
- Uint16List.fromList(Uint8ClampedList.fromList(Uint8List(5)))): [
- 'pe\u2665'
- ],
- [-55]: [')RLj']
-};
-Map<List<int>, Set<bool>> var366 = {
- Uint16List.fromList(Int32List(15)): {false, true},
- Uint16List(14): {true},
- Int64List.fromList(new Uint32List(28)): {false},
- Int16List.fromList(Int32List(8)): {true},
- [-82]: {true, false, true},
- [-30]: {false, false, false}
-};
-Map<List<int>, Set<int>> var367 = {
- Uint16List.fromList(Int64List.fromList(Uint32List(4))): {-97, -37},
- Uint8ClampedList.fromList(
- Int32List.fromList(Uint32List.fromList(Int8List.fromList([16])))): {
- -9223372032559808511,
- -24,
- 45,
- -58,
- 26
- },
- [-45, -48, -36, 25]: {24},
- Uint32List(34): {6442450943, 5, -49, -14, 8589934591}
-};
-Map<List<int>, Set<String>> var368 = {
- [5, -41, 4294967296, -65, -60]: {'uYO&&', '', 'diE#\u2665z'},
- Uint32List(38): {'iO'}
-};
-Map<List<int>, Map<bool, bool>> var369 = {
- Uint32List.fromList(Int8List.fromList(Uint16List(11))): {
- false: false,
- false: false,
- false: false,
- false: true
- },
- Int64List.fromList(Uint8ClampedList.fromList(Uint64List(36))): {false: true},
- Int8List(0): {false: false, true: true, false: false},
- Uint16List.fromList(Int64List.fromList(Int8List(28))): {
- true: false,
- false: true,
- false: true
- }
-};
-Map<List<int>, Map<bool, int>> var370 = {
- Int8List(5): {true: 18, true: 4, false: 8589934591, false: 5, true: 19}
-};
-Map<List<int>, Map<bool, String>> var371 = {
- Uint16List(25): {
- true: 'xl\u{1f600}',
- false: 'H3E',
- true: 'NdHmw',
- false: '0JtCw#t',
- false: 'GX'
- },
- Uint32List(14): {false: 'W8', true: 'rGEg@2'},
- Uint16List(12): {true: '\u{1f600}ga'},
- Int16List.fromList(Uint16List.fromList(Int32List.fromList([34]))): {
- true: 'p@sT7sZ',
- true: '',
- true: 'u\u{1f600}u',
- false: '38',
- true: '\u{1f600}&&Fg'
- },
- Int16List(36): {
- false: 'dhOC2',
- false: 'y\u2665@9',
- false: 'HJIkR#',
- true: '\u2665',
- true: 't!Ab)'
- }
-};
-Map<List<int>, Map<int, bool>> var372 = {
- Int64List(3): {-88: false, 44: true},
- [21, -15, 20, -6]: {-9223372030412324863: true, 29: false},
- Int8List.fromList(Uint8List.fromList(
- Int64List.fromList(Int8List.fromList(Uint16List(46))))): {
- 12: false,
- 31: false,
- -55: false,
- -34: true,
- 47: true
- }
-};
-Map<List<int>, Map<int, int>> var373 = {
- [24, -46, -51]: {-45: -0},
- [-19, -26, 29, 6442450944, 38]: {-52: 7, -97: 8, -4294967296: 10, -74: -8},
- Uint64List(34): {-9223372036854775808: 23, 4: -70}
-};
-Map<List<int>, Map<int, String>> var374 = {
- Uint64List.fromList(Int64List.fromList([5])): {-70: '3dNyxO('},
- Uint32List(30): {10: '6Y&R\u2665', 44: 'j', -26: 'Pd!V'},
- new Uint8List(18): {16: '4&dmj', 45: 'J I&q', -64: '(z'},
- [-56]: {-66: 'Ng\u{1f600}'},
- Int64List(31): {-23: '0NtH 4c', -52: 'KLv\u2665', -99: '@n\u2665!'}
-};
-Map<List<int>, Map<String, bool>> var375 = {
- Int64List.fromList(Int32List.fromList([-12])): {
- 'e': false,
- '': true,
- 'JSA@': true
- },
- [33, 4, 10, -9223372034707292160, 19]: {
- '8wi@': true,
- 'YFDjF': true,
- 'e)E5': false,
- 'I1j)&': false
- }
-};
-Map<List<int>, Map<String, int>> var376 = {
- [-2147483647, 32]: {'CIFeJNR': 42},
- Int8List.fromList(Int32List.fromList(Uint8ClampedList.fromList([-4]))): {
- '5': -4294967295
- },
- Uint16List(7): {'!b': -26}
-};
-Map<List<int>, Map<String, String>> var377 = {
- Int32List(4): {
- 'DVp(eJ': 'fK9fvnK',
- 'jj6mCe': '\u2665',
- '1\u{1f600}A3O\u{1f600}T': 'W!rZSWi',
- '': ''
- },
- Int64List.fromList(Uint32List.fromList(Uint32List.fromList(Uint8List(25)))): {
- 'f5cA\u2665u': 'I4g',
- 'W\u2665kF&rC': 'HYP)V',
- 'vQ!r1': '(#iE\u2665gW'
- }
-};
-Map<List<int>, MapEntry<bool, bool>> var378 = {
- Int32List.fromList(Int64List(18)): MapEntry<bool, bool>(false, true),
- new Uint8ClampedList(22): new MapEntry<bool, bool>(false, true),
- Int64List.fromList(Int16List(2)): MapEntry<bool, bool>(false, true)
-};
-Map<List<int>, MapEntry<bool, int>> var379 = {
- Uint64List.fromList(Uint8ClampedList(16)): MapEntry<bool, int>(false, 14)
-};
-Map<List<int>, MapEntry<bool, String>> var380 = {
- Uint8ClampedList.fromList(Uint16List(12)): MapEntry<bool, String>(true, 'TH'),
- Uint8ClampedList(26): MapEntry<bool, String>(false, ''),
- Uint8List.fromList(Int8List(42)): MapEntry<bool, String>(false, 'U9oyRh'),
- [37, -36, 6]: MapEntry<bool, String>(true, 'Ksb'),
- Int8List.fromList(Uint64List.fromList(Uint16List(34))):
- MapEntry<bool, String>(true, 'yzSMbLS'),
- Uint8List(19): MapEntry<bool, String>(true, 'k\u2665zos@g')
-};
-Map<List<int>, MapEntry<int, bool>> var381 = {
- Int32List(38): MapEntry<int, bool>(35, false),
- Uint8List.fromList(new Uint8ClampedList(41)): MapEntry<int, bool>(20, true)
-};
-Map<List<int>, MapEntry<int, int>> var382 = {
- Int32List.fromList([40, 37]): MapEntry<int, int>(20, 21)
-};
-Map<List<int>, MapEntry<int, String>> var383 = {
- Uint32List.fromList(new Uint8ClampedList(31)):
- MapEntry<int, String>(16, 'zylth')
-};
-Map<List<int>, MapEntry<String, bool>> var384 = {
- Uint8List.fromList(Uint16List(43)): MapEntry<String, bool>('\u2665d', true),
- [-28, -9223372032559808512, -64]: MapEntry<String, bool>('@jw', false),
- Uint16List.fromList([-3, 27, -15]): MapEntry<String, bool>('', false),
- Uint32List.fromList(Int64List(13)): MapEntry<String, bool>('', true)
-};
-Map<List<int>, MapEntry<String, int>> var385 = {
- Uint8List.fromList(Int16List(14)):
- MapEntry<String, int>('9MFlDq\u{1f600}', 14),
- Uint64List(21): MapEntry<String, int>('', 22),
- Uint16List(47): MapEntry<String, int>('iX', 15),
- Int32List.fromList(Uint8List(27)): MapEntry<String, int>(' R2vo', 37),
- Uint8ClampedList.fromList(Uint32List(39)): MapEntry<String, int>('PsTRg7', 42)
-};
-Map<List<int>, MapEntry<String, String>> var386 = {
- Uint16List(19): MapEntry<String, String>('H71c\u2665', ''),
- Uint32List.fromList(Uint64List(4)): MapEntry<String, String>('', 'qr7'),
- Int64List.fromList(Uint16List(34)):
- MapEntry<String, String>('', 'BHR\u2665RSU'),
- Uint8List.fromList(Uint64List(16)): MapEntry<String, String>('-', 'Bft'),
- Int64List.fromList(Uint32List(21)):
- MapEntry<String, String>('o', '\u{1f600}S')
-};
-Map<List<String>, bool> var387 = {
- ['', '\u26659 @o', '(C9F', 'Jg', '']: false,
- ['qg-Ck']: true,
- ['', '7Ix9(T', 'lx', 'K(e0F)2']: true,
- [' n&9vb', '\u{1f600}C', '\u2665x']: true
-};
-Map<List<String>, int> var388 = {
- ['Qul1', '3Od7W@\u{1f600}', 'q7TH\u26654', '\u2665YTm\u2665', ' !7']: 23,
- ['sv (', '5#VQ!h']: -14,
- ['iBp', 'Ma\u26651A']: 46,
- ['\u2665e7', '', 'cyw']: -87,
- ['0 \u{1f600}v', 'N6 7', '3@@X)', 'W']: 7,
- ['0', '6qv6']: 30
-};
-Map<List<String>, String> var389 = {
- ['Gc3']: ''
-};
-Map<List<String>, Expando<bool>> var390 = {
- ['\u{1f600}GO', 'K(bo', 'yAl']: Expando<bool>('f'),
- ['ZYUB2', 'nA+P47', 'RUF)\u{1f600}rN']: Expando<bool>('px)h+\u2665 '),
- ['']: Expando<bool>('9il'),
- ['\u2665\u{1f600}K7H', 'IRwUlEp', 'U+\u2665']: new Expando<bool>('@TLIaC'),
- ['A#', 'S6au\u{1f600}Y', 's', 'FOQo', '98arJ']: Expando<bool>('d')
-};
-Map<List<String>, Expando<int>> var391 = {
- ['EX', 'a6PG', 'm']: Expando<int>(''),
- ['PX', '@Dv', 'I5DP']: Expando<int>('4YK+Vu')
-};
-Map<List<String>, Expando<String>> var392 = {
- ['P)w', '', 'qT5kxy']: Expando<String>('VA6gy\u2665k'),
- ['+jw kW']: Expando<String>('rE'),
- ['7', '+', 'bU9']: Expando<String>('ss\u{1f600})-+K'),
- ['\u{1f600}\u{1f600}', '@iHXM2p', 'V', 'dwkpb']: new Expando<String>('g0T')
-};
-Map<List<String>, List<bool>> var393 = {
- ['L3V7K7n', 'tqlHZ', 'pi', '&']: [false, false, true]
-};
-Map<List<String>, List<int>> var394 = {
- ['j0', '']: Int32List.fromList(Uint32List(31)),
- ['tl', 'v(CSK4\u{1f600}', 'FtI6K']: [4294967297, 17, 7, 2147483649],
- ['\u2665d4\u2665LH', '3vgT(', 'mXPPZg6', '']: Uint16List(16),
- ['', '']: Uint8ClampedList(40)
-};
-Map<List<String>, List<String>> var395 = {
- ['']: ['hPAmx\u2665', 'ae+ n(', 'PJFm', 'IzE', 'L@'],
- ['rChDXur', 'Z8(rO\u{1f600}']: ['ouTu+Fx'],
- ['']: ['gYn', 'E(UwcT1', 'fQEd', 'GO'],
- ['O\u{1f600}PA', 's\u2665p', 'M', 'BqQjkL\u2665']: ['c', '', ''],
- ['N', '!7P+']: ['2P4v&n', 'LE\u{1f600}', ')a3']
-};
-Map<List<String>, Set<bool>> var396 = {
- ['CCl2\u{1f600}r']: {true, false, true, true},
- ['\u2665tFs', 'yv\u2665']: {true, true, true, false, false}
-};
-Map<List<String>, Set<int>> var397 = {
- ['CUM9TQB', '', '-@7(p', 'wWp\u{1f600}e\u{1f600}F']: {32, -90, -66, -88, -16},
- ['', 'Fn#JFM', 'L', 'KK', 'U']: {-42}
-};
-Map<List<String>, Set<String>> var398 = {
- ['8oW6&', '\u{1f600}p']: {'LMq', '4arxN', ' \u{1f600}H2PpL'},
- ['vC\u{1f600}B@', '-IgWaA', 'fgu', 'Fok', '2OE']: {'tFSTv', 'Fbs#c'},
- ['( ']: {'+P', '@7', '\u2665m'}
-};
-Map<List<String>, Map<bool, bool>> var399 = {
- ['&siYeL', '\u2665VdU+', 'VI+j0XW', '', 'd!Bw8F']: {false: true},
- ['', '8jGF6@S']: {false: true},
- ['!', 'z-87wVu']: {
- true: true,
- false: false,
- true: false,
- true: true,
- true: false
- },
- ['ot', '', 'nsob\u{1f600}']: {
- false: true,
- true: true,
- true: true,
- true: false
- }
-};
-Map<List<String>, Map<bool, int>> var400 = {
- ['r0D75D', 'kyT ', 'pS\u2665X', 'WT', '1 Yqopl']: {false: -1},
- ['RSNeAr', 'D2JK', '!Mcs4&Z', 'oto']: {
- false: 9,
- false: 0,
- false: 18,
- false: 4294967296,
- true: -73
- },
- ['T', ' b', '', '9Njt']: {
- false: -44,
- false: -2,
- false: -13,
- true: -0,
- false: -86
- },
- ['SON)', 'url96nh', '']: {true: 34, true: -54, false: -38, true: -43}
-};
-Map<List<String>, Map<bool, String>> var401 = {
- ['qa']: {
- false: '1c\u2665G+H',
- true: 'jh',
- false: 'DwdlPZE',
- false: 'nGM4 U!'
- },
- ['8)QU!Bh']: {
- false: '',
- false: 'Wpv',
- true: '8g',
- false: '9IwQ',
- true: 'aSBf2'
- },
- ['bR84E\u2665', '#3Jxk1', 'b ', '+aJSA!', '']: {
- false: 'J\u{1f600}Iz1',
- false: 'GqDyu',
- true: ' wrEDJ'
- },
- ['', '5\u2665jaB', 'uX\u2665', 'zHZxxxw', 'UU\u{1f600}GL']: {true: '+'},
- ['Ot6(b', 'd#N2-', 'a\u2665zZ6', 'iJgQvH']: {
- false: '\u2665R',
- true: 'O\u{1f600}b',
- true: 's5',
- false: ')'
- }
-};
-Map<List<String>, Map<int, bool>> var402 = {
- ['!M3 Z3g', 'kwi', '\u2665']: {-28: false, -91: true, -1: true},
- ['Oh\u{1f600}', '']: {23: true},
- ['\u{1f600}r)', '9@mO\u{1f600}\u2665', '', '']: {
- -93: true,
- 16: true,
- -7: false,
- -40: true,
- -9223372032559808513: false
- },
- ['A\u2665k', '\u2665Dn\u{1f600}', 'ZXj!', '', '']: {
- 4: false,
- -21: true,
- 46: false
- }
-};
-Map<List<String>, Map<int, int>> var403 = {
- ['n\u2665\u2665K5E\u2665', '6&qMMK', '', 'x1R', '2#ch']: {
- -75: 5,
- 45: 49,
- 13: 19,
- 0: 34,
- -79: 10
- }
-};
-Map<List<String>, Map<int, String>> var404 = {
- ['&H1', 'U+#\u2665Yy', 'L2', '8a', 'F3V']: {-77: 'ic\u{1f600}k'}
-};
-Map<List<String>, Map<String, bool>> var405 = {
- ['aCY', 'V9!Mx', 'iUPBi']: {'S9Q\u{1f600}FA1': true}
-};
-Map<List<String>, Map<String, int>> var406 = {
- ['octfe', 'h\u2665', 'hXHQw1z']: {'1uYV': 41, '\u{1f600}\u{1f600}M': -37},
- ['BHkU']: {'': -17},
- ['0uSL']: {'ik\u{1f600}cv5': -45},
- ['', '#9sX', 'Da', '', '80a+r']: {'!ds\u{1f600}': 6, '\u26654': 44},
- ['DM\u2665', '\u{1f600}!ElAe', 'x7MU', 'I#\u26653', '@']: {
- 'H+p\u{1f600}': -45,
- 'DV40kpv': -69,
- 'ctAG': 2,
- 'G7': 0
- }
-};
-Map<List<String>, Map<String, String>> var407 = {
- ['t+Nypn', '']: {
- '\u{1f600}llH': 'y',
- 'U3p4wh': '',
- 'pcnF': 'q\u2665 \u2665-W',
- 'NBt\u{1f600}': 'f+TJ',
- 'B1': 'JhGGc'
- },
- ['H', 'x\u2665s6sp']: {'DCZo': '', 'zc': 'f9Y', 'bM@A': '8hIff '},
- ['', '6P@', 'xrd&4']: {
- '&\u{1f600}RhWb': '',
- 'h\u2665\u{1f600}': '',
- 'w': '6iDTx\u{1f600}\u2665',
- 'ygLBC': 'h4uv+ko'
- },
- ['+V', 'ITX', 'W5', 'ZIp\u2665c', 'rW']: {
- 'IOJ': 'NNycdJ0',
- 'sqX(': '\u{1f600}',
- 'G': 'R'
- },
- ['s', 'kjg', 'kKMYx']: {
- 'b': 'qjN3',
- 'kg\u{1f600})g\u2665e': '\u266563\u{1f600}\u{1f600}k',
- '': 'q\u{1f600}A3'
- },
- ['B', '', '+-Dv', 'Kli', '']: {
- '\u{1f600}f-e\u2665': '1Nq3\u{1f600}n',
- 'A': '-'
- }
-};
-Map<List<String>, MapEntry<bool, bool>> var408 = {
- ['\u2665\u2665f', 'L&ELGj', 'Y#j', '3h', 'sdy\u26652']:
- MapEntry<bool, bool>(true, true),
- ['RYnkDU', 'P\u{1f600}JC\u2665', '']: MapEntry<bool, bool>(true, true),
- ['S\u{1f600}z2\u2665y-', 'Cw']: MapEntry<bool, bool>(true, false),
- ['0E(UY', 'xKtf\u2665', 'n0s6@D', 'pRm', '76FP']:
- MapEntry<bool, bool>(true, false),
- ['', '']: MapEntry<bool, bool>(true, false),
- ['gzC3X', 'BIM']: MapEntry<bool, bool>(false, true)
-};
-Map<List<String>, MapEntry<bool, int>> var409 = {
- ['1gt8f@7', '#Elli', '2r\u266554N8', 'Hno', '#P']:
- MapEntry<bool, int>(true, 25),
- ['\u{1f600}', '', '(A)k', 'O']: new MapEntry<bool, int>(false, 47),
- ['1\u{1f600}EXakE', '2IMGfHh', 'h\u26655Uz S', '4']:
- MapEntry<bool, int>(false, 25),
- ['W\u{1f600}#Wnl', '\u{1f600}(-', 'v']: MapEntry<bool, int>(true, 21)
-};
-Map<List<String>, MapEntry<bool, String>> var410 = {
- ['OU', '', '\u{1f600}o', '-D\u{1f600}7g', '']:
- MapEntry<bool, String>(true, 't-s\u2665vm2'),
- ['iaOWvBp', '\u{1f600}7cBY', 'zz\u{1f600}\u2665E', '', 'ic']:
- MapEntry<bool, String>(true, 'gY'),
- ['o', '04PLMK', 'EMVABxg', 'L']: MapEntry<bool, String>(false, '#'),
- ['8yii pG']: MapEntry<bool, String>(true, ''),
- ['Sj', 'W']: MapEntry<bool, String>(true, '')
-};
-Map<List<String>, MapEntry<int, bool>> var411 = {
- ['z', '\u{1f600}pI6v']: MapEntry<int, bool>(46, true),
- ['@xY\u2665', '\u{1f600}V']: new MapEntry<int, bool>(48, false),
- ['g\u2665HbXp', '9qQb1V', 'J\u2665gX', 'A0Iv']: MapEntry<int, bool>(27, true),
- ['SzF)HW', 'gMU', 'KmpP', '\u{1f600}ANrFnc', 'y\u2665']:
- MapEntry<int, bool>(9, true),
- ['BCb', 'ISGNZ4', '\u{1f600}i', '87\u266506']: MapEntry<int, bool>(46, false)
-};
-Map<List<String>, MapEntry<int, int>> var412 = {
- ['dgu\u2665\u2665W-', '3p\u{1f600}Q', 'vWi', '7qg&', 'S']:
- MapEntry<int, int>(43, 24)
-};
-Map<List<String>, MapEntry<int, String>> var413 = {
- ['Q']: MapEntry<int, String>(10, '2b')
-};
-Map<List<String>, MapEntry<String, bool>> var414 = {
- ['Gxf', 'wa', '']: MapEntry<String, bool>('wg9fUY+', false),
- ['\u2665', 'Jc', 'RlR', 'hc\u2665P', 'DTDjB']:
- MapEntry<String, bool>('T)(8', false),
- ['9t']: MapEntry<String, bool>('Yd', true),
- ['!JMe', '5R7N!', 'YPZa']: MapEntry<String, bool>('KP!y)A', true),
- ['a@D9']: MapEntry<String, bool>('V', false)
-};
-Map<List<String>, MapEntry<String, int>> var415 = {
- ['']: MapEntry<String, int>('', 27),
- ['V@\u{1f600}1', 'AMaa', 'N@4N', '']: MapEntry<String, int>('Kl', 46),
- ['I&', '5GH', 'h\u{1f600}', '!H7\u2665#']: MapEntry<String, int>('!BzB', 9),
- ['']: MapEntry<String, int>('6\u{1f600}q', 13),
- ['sad', ')\u{1f600}FrZh', 'hziw', 'BD)S)lu']:
- MapEntry<String, int>(')\u{1f600})zt', 20),
- ['S@B', '8ip1+G']: MapEntry<String, int>('mFLWz', 7)
-};
-Map<List<String>, MapEntry<String, String>> var416 = {
- ['YchLPjp', '', 'aVqd', 'T\u{1f600}G']:
- new MapEntry<String, String>('7Tu\u{1f600}', ''),
- [' wZ)(im', 'fMQMT', '@mnmAPv']: MapEntry<String, String>('DiQkn-#', 's7B'),
- ['', 'W0', 'Xu&69Yg', 'zl', 'w Tg t']:
- MapEntry<String, String>('ExO', 'Gs1&\u2665e\u{1f600}'),
- ['@LBWnOw', '4']: MapEntry<String, String>('E\u26659\u{1f600}d', 'grJ'),
- ['RM', 'y3d#', '!']: MapEntry<String, String>('i7v1', 'i'),
- ['ri4#f', '\u{1f600}CRFM ', '31T1X']: MapEntry<String, String>('2', 'xB#UJu')
-};
-Map<Set<bool>, bool> var417 = {
- {true}: true
-};
-Map<Set<bool>, int> var418 = {
- {true}: -26,
- {true, false, true, true}: 21,
- {true, true, true}: 6,
- {true}: 45
-};
-Map<Set<bool>, String> var419 = {
- {true, false, false, false, true}: '!fe9\u2665',
- {false}: 'UDU',
- {true, false, false, true, false}: 'iU',
- {true, false, false, true, false}: 'qE'
-};
-Map<Set<bool>, Expando<bool>> var420 = {
- {true, true, false, true}: Expando<bool>('S0V\u2665'),
- {true, false, false}: Expando<bool>('oP@&5'),
- {true, true, true, false}: Expando<bool>('n\u26658b3Y3'),
- {true, false, false, false, false}: Expando<bool>('8 '),
- {true, true, true, false, true}: Expando<bool>('NXHSv'),
- {true, false, false}: Expando<bool>('3Y')
-};
-Map<Set<bool>, Expando<int>> var421 = {
- {true}: Expando<int>('cX')
-};
-Map<Set<bool>, Expando<String>> var422 = {
- {true, true}: Expando<String>('0EJ5-j'),
- {true, false, true, true}: Expando<String>('svh\u2665'),
- {false, true, true}: new Expando<String>('KoMNXn')
-};
-Map<Set<bool>, List<bool>> var423 = {
- {true, false}: [true, true, true],
- {true}: [true, false, false, true],
- {false, false, false, false}: [true, false, false, false, true],
- {true, true, false, false}: [true, false, true],
- {false, false}: [false],
- {false}: [true, true]
-};
-Map<Set<bool>, List<int>> var424 = {
- {true, true, true}: Uint64List.fromList(Uint32List.fromList(
- Uint32List.fromList(Uint8List.fromList(
- Uint8List.fromList(Uint8List.fromList(Uint16List(26))))))),
- {false}: new Int16List(30)
-};
-Map<Set<bool>, List<String>> var425 = {
- {true, true}: ['sT', ' suhSy'],
- {true, false, true, true, true}: ['dT', 'r\u2665\u{1f600}+W', '0@', '764@'],
- {true, true}: ['Y', '))5gG', 'j', '7Kq+'],
- {false, true, false}: ['\u2665J'],
- {false, true, false}: ['b']
-};
-Map<Set<bool>, Set<bool>> var426 = {
- {false, false, false, true}: {false, true, false}
-};
-Map<Set<bool>, Set<int>> var427 = {
- {false, true, false}: {9223372034707292161, 8},
- {true, false, true}: {14, 36, -87, 16, -3},
- {true, false, false, false, false}: {-56, 43, -41, 4294967297, 21}
-};
-Map<Set<bool>, Set<String>> var428 = {
- {true}: {'d\u2665MBnT', '', 'm6'},
- {true, true, true, true, false}: {'-t)LStU', 'R\u26659o', 'pjWu'},
- {false, true, false, true}: {'3\u2665X ', ''},
- {false, true, false, true, false}: {'HiF', 'Q6MHc2m', 'SQat\u{1f600}', 'kl'},
- {true, false, true, false}: {'(Y', 'wO', '', 'P9XqTUy', ''}
-};
-Map<Set<bool>, Map<bool, bool>> var429 = {
- {false, false}: {false: true, false: true, false: false, true: true},
- {true, true, false, true}: {
- true: false,
- false: true,
- true: true,
- false: false
- },
- {true}: {true: false, false: true, false: false, true: true, true: false},
- {true}: {false: true, false: false, true: true},
- {false, true}: {true: false, true: false, false: true},
- {false}: {false: false, false: true, true: false, false: true, true: false}
-};
-Map<Set<bool>, Map<bool, int>> var430 = {
- {false, false, false, true, false}: {
- false: 13,
- true: -16,
- true: -10,
- false: -44
- },
- {true, true}: {false: -63, false: -67},
- {true, false, true}: {true: -39, true: 41, true: -65, false: -33, true: -76},
- {false, false, false, true, false}: {
- true: -9223372030412324863,
- true: -9223372034707292159,
- false: -8,
- false: 33,
- false: 48
- }
-};
-Map<Set<bool>, Map<bool, String>> var431 = {
- {false, true}: {false: 'zO', false: 'QJ', false: 'Nt', true: 'MWVebDw'}
-};
-Map<Set<bool>, Map<int, bool>> var432 = {
- {false, false, true, true}: {28: false, 10: true, 32: false, 12: false},
- {false, false, true}: {-50: true, -70: true, 7: false, 40: true, -50: false},
- {true, true, false, true, false}: {
- -12: true,
- 14: true,
- -70: false,
- -88: false
- },
- {true, false, false, true, false}: {
- 24: false,
- 44: false,
- -31: false,
- -0: true,
- -29: true
- },
- {true, false, true}: {40: false, 8: false}
-};
-Map<Set<bool>, Map<int, int>> var433 = {
- {false, true, false, false, true}: {39: 6442450945},
- {true, true, true, true, false}: {
- 28: -22,
- -43: 9223372032559808512,
- -57: 22,
- 26: 14
- },
- {true, false, true}: {-67: 43, 14: 18},
- {true}: {9: 16},
- {false}: {-45: 26, -31: 5, -78: 18}
-};
-Map<Set<bool>, Map<int, String>> var434 = {
- {true}: {40: '0yQ9a1', -69: ' i5l+P', 29: 'pK-q\u{1f600}h', -7: 'i!7'},
- {true, false, false, false}: {
- 1: '&&kg\u2665Oz',
- 40: 'Sv-ukw',
- 40: 'LW7k+)',
- -97: ''
- },
- {true, false, false, false, false}: {
- -92: 'Rj',
- -14: '',
- -9223372028264841217: 'byJTu\u{1f600}l',
- 18: 'f\u2665iG0c',
- -52: 'F\u{1f600}\u2665k\u2665'
- },
- {false, true, true, true, true}: {27: 'O(Lvs', -99: '4BGa', 47: 'FjQ'},
- {false}: {27: 'X5xY', 25: 'BSX\u2665l', 1: 'HPYzh!', 19: ''}
-};
-Map<Set<bool>, Map<String, bool>> var435 = {
- {false, true, false, true, false}: {
- 'eU4gRZe': true,
- '3QIYghR': true,
- 'Fhzio\u{1f600}c': true,
- 'UKT)!Bo': true
- },
- {true, false}: {'&': true},
- {true, true, true}: {'IUoOoP': false, 'W': true}
-};
-Map<Set<bool>, Map<String, int>> var436 = {
- {false, false, false, true}: {
- '\u{1f600}QaB': -55,
- 'L3\u2665vUo': -9223372034707292161,
- '!bbEb': -24,
- 'T\u{1f600}6U': 20,
- 'HVHo@vH': -26
- },
- {true, true, false}: {'xtz X': 18}
-};
-Map<Set<bool>, Map<String, String>> var437 = {
- {true, false, true}: {
- 'L-gB': '',
- '4a': '\u{1f600}6QAQsT',
- ')S': 'i-d',
- 'Nl\u2665MoO': 'a\u{1f600})a'
- },
- {true, true, false, true, true}: {
- '#z5': '\u{1f600}K\u2665QAU\u{1f600}',
- 'KKg-\u{1f600}\u{1f600}a': 'yjBmNA\u2665',
- 'u!qP9k': '\u2665!W5K-',
- 'Iw\u{1f600}!V': '',
- 'f': 'nXOgaXC'
- },
- {false, true, true, false, true}: {
- 'j&f\u2665qp': 'sY8aa!G',
- '': 'gkx',
- 'A2\u{1f600}IeRy': '7@B',
- 'nloh': '!aPuj\u2665I',
- '\u{1f600})eLM8': 'P(6jm2'
- }
-};
-Map<Set<bool>, MapEntry<bool, bool>> var438 = {
- {false}: MapEntry<bool, bool>(true, true),
- {false, false, false, false, true}: new MapEntry<bool, bool>(true, true),
- {false, true}: new MapEntry<bool, bool>(false, false),
- {true, true, true, false}: MapEntry<bool, bool>(true, false),
- {false}: MapEntry<bool, bool>(false, true),
- {false, false, true}: MapEntry<bool, bool>(true, true)
-};
-Map<Set<bool>, MapEntry<bool, int>> var439 = {
- {true, false}: MapEntry<bool, int>(false, 5),
- {false, true, true}: MapEntry<bool, int>(true, 11),
- {true}: MapEntry<bool, int>(false, 25),
- {false, false, true, false, false}: MapEntry<bool, int>(false, 19),
- {true}: new MapEntry<bool, int>(true, 28),
- {false, false, false}: MapEntry<bool, int>(true, 5)
-};
-Map<Set<bool>, MapEntry<bool, String>> var440 = {
- {true, true, false, true}: MapEntry<bool, String>(false, 'T6DP1k)'),
- {true, false, true, false}: MapEntry<bool, String>(false, 'ssg')
-};
-Map<Set<bool>, MapEntry<int, bool>> var441 = {
- {false, false, true, true}: MapEntry<int, bool>(47, true)
-};
-Map<Set<bool>, MapEntry<int, int>> var442 = {
- {true, true, true, false}: MapEntry<int, int>(9, 16),
- {true, true, true, true}: MapEntry<int, int>(4, 25)
-};
-Map<Set<bool>, MapEntry<int, String>> var443 = {
- {false, true, false, false, false}: MapEntry<int, String>(20, 'F'),
- {false, true, true}: MapEntry<int, String>(16, 'nNZB'),
- {true, false, true, true}: MapEntry<int, String>(46, 'O'),
- {true}: MapEntry<int, String>(12, '7EdNa6g'),
- {false, true, false, true}: MapEntry<int, String>(6, '-B\u{1f600}\u26654'),
- {false, true}: new MapEntry<int, String>(0, 'f2x&W')
-};
-Map<Set<bool>, MapEntry<String, bool>> var444 = {
- {true, true}: MapEntry<String, bool>('eIu+r', false)
-};
-Map<Set<bool>, MapEntry<String, int>> var445 = {
- {false, true, true}: MapEntry<String, int>('IvBj0', 14),
- {true, false}: MapEntry<String, int>('E\u2665J', 37),
- {false, true}: MapEntry<String, int>('lZBF', 43),
- {true, false, true, true}: MapEntry<String, int>('Y', 42),
- {true, true, true, false, false}: MapEntry<String, int>('&yyiY', 14),
- {false, true, false, true, true}: MapEntry<String, int>('9W', 16)
-};
-Map<Set<bool>, MapEntry<String, String>> var446 = {
- {true}: MapEntry<String, String>('w', '\u2665'),
- {true, true}: MapEntry<String, String>('bmoE\u{1f600}d\u2665', 'CO\u{1f600}')
-};
-Map<Set<int>, bool> var447 = {
- {-9223372030412324865, -83, -58}: false,
- {-47, -39, -95, 6442450943}: false,
- {-9223372028264841217, 34}: false,
- {-34}: true,
- {-59}: false,
- {2, -54, 11}: false
-};
-Map<Set<int>, int> var448 = {
- {3, 37}: 33,
- {16, -20, -83, -10}: -25
-};
-Map<Set<int>, String> var449 = {
- {9223372032559808513, -51}: ' \u{1f600}',
- {-66, -55, -9223372034707292161, -85}: '(PZNMHl',
- {-32}: '',
- {-33, -88, 35, 9223372032559808512}: 'lFnI927',
- {2147483649, 16, -4294967295}: 'VVvfZ\u2665'
-};
-Map<Set<int>, Expando<bool>> var450 = {
- {6442450945, 33}: Expando<bool>('')
-};
-Map<Set<int>, Expando<int>> var451 = {
- {-33}: Expando<int>('cDG '),
- {32, 32, -55}: Expando<int>('h'),
- {-0, -70, -9, 36, 15}: new Expando<int>('S\u2665(9S')
-};
-Map<Set<int>, Expando<String>> var452 = {
- {-9223372034707292161, -84, -15, 15}: Expando<String>('uSPXU\u2665'),
- {8, 4294967297, -29, 33, -39}: new Expando<String>('ap'),
- {-99, -13, 15}: Expando<String>('kAH'),
- {-89, -9223372036854775807, 22, -19, -99}: Expando<String>('fJ\u26652')
-};
-Map<Set<int>, List<bool>> var453 = {
- {-57, -11, -9223372036854775808}: [true, false, false],
- {39}: [false, true, false],
- {8, -14, -16, -50}: [false, false, true],
- {42, 44}: [false, false]
-};
-Map<Set<int>, List<int>> var454 = {
- {42, 48, -80, 12, -41}: Int32List.fromList([5, 40, 35]),
- {9, 9223372036854775807, 37, -53}:
- Int8List.fromList(Uint8List.fromList(Uint32List.fromList(Int8List(12)))),
- {3, -86, -9223372036854775808, 41, -69}: new Uint8ClampedList(42),
- {2147483648, -41, -25, -14, -71}: Uint8ClampedList(6),
- {13, 6, -26, 17}: new Int32List(17),
- {-59}: Int64List.fromList([3, -23])
-};
-Map<Set<int>, List<String>> var455 = {
- {-9223372034707292161, -27, -20, -9223372032559808513}: [
- 'QPJp-e',
- 'eCAyFHS',
- '\u{1f600}rMUp\u2665',
- '',
- 'e!b'
- ],
- {-11, -11, 7, 43, 6442450945}: ['ELc', '2Cp(\u{1f600}e'],
- {1, -9223372034707292159, -38}: ['6e', 'GotL', '', 'Wb)-&'],
- {9223372034707292161, 26}: ['6NO', '\u2665h\u2665k'],
- {-71}: ['#&\u{1f600}', '', 'BbNz3\u2665', '1pc'],
- {-38, -58, 23, -81, 5}: ['Jw']
-};
-Map<Set<int>, Set<bool>> var456 = {
- {-13, 48, 5}: {true, false, true, true},
- {-97, 2, -20, 14, 27}: {true, true, false}
-};
-Map<Set<int>, Set<int>> var457 = {
- {-4294967295, -70, -9}: {9223372034707292159, 30, 25, -32, -48}
-};
-Map<Set<int>, Set<String>> var458 = {
- {7}: {'Q\u2665Lw', '', '1', '+TIXV\u2665'},
- {7}: {'w', '&sw+U', 'cN\u{1f600}', '&iB\u{1f600}\u{1f600}vQ', 'g'}
-};
-Map<Set<int>, Map<bool, bool>> var459 = {
- {-34, 24, 40, -32}: {false: false},
- {20, 17, -74}: {false: true, false: false},
- {-84, 6442450945}: {
- true: true,
- true: false,
- true: true,
- true: false,
- true: true
- },
- {-52, -16, -90, 7, 24}: {false: true, true: false, true: true},
- {-9223372036854775808, -29, 20}: {
- true: false,
- false: false,
- false: false,
- false: true,
- true: true
- },
- {-84, -97, 2147483647}: {
- true: false,
- false: false,
- true: true,
- false: true,
- false: false
- }
-};
-Map<Set<int>, Map<bool, int>> var460 = {
- {1, 6, -43}: {false: -4294967296, true: 22}
-};
-Map<Set<int>, Map<bool, String>> var461 = {
- {11, 19}: {
- true: '7IEzi',
- false: 'G',
- false: 'rT',
- true: '(l8aYj',
- false: 'nH\u2665\u2665'
- },
- {19, -93, -3, 39}: {
- false: 'N)aI',
- true: 'XW',
- false: 'vQ\u2665O#',
- false: '',
- false: 'Mk'
- },
- {-68, -34, 47, 2147483649, -13}: {
- true: '\u{1f600}7pSK ',
- false: '\u{1f600}O\u2665',
- false: 'N\u2665',
- false: 'EYxbUE',
- false: '\u{1f600}t'
- },
- {46, 29, -9223372036854775808, -90}: {
- false: '9K',
- false: '8G\u{1f600}3c#2',
- false: 'X\u2665e'
- },
- {-12, 4}: {true: ''},
- {-68, 14}: {true: 'un\u{1f600}9UN', true: '3', false: 'kxu-Db'}
-};
-Map<Set<int>, Map<int, bool>> var462 = {
- {9223372034707292160, -97, 49, 0}: {-56: false, 27: true},
- {30, 17, 4}: {-90: true}
-};
-Map<Set<int>, Map<int, int>> var463 = {
- {27, -16, 9223372034707292159, -21}: {-55: -9223372030412324864},
- {-83}: {-42: 47, 33: 7},
- {-25, -92, 25, 42, -40}: {30: 9223372034707292161, 16: 31},
- {17}: {31: 4294967296, 37: -4294967295, -66: -1, 9223372034707292161: 37}
-};
-Map<Set<int>, Map<int, String>> var464 = {
- {15}: {48: 'fHJFZ', -99: 'lB\u2665Q-', -1: '8xF&1'},
- {-76}: {23: ')G', -90: 'W\u{1f600}io\u2665@f', 20: 'Iwpd\u2665g'},
- {-76, 9223372034707292161}: {-22: '\u{1f600}8D', 28: 'zIhgB', -58: ''},
- {23}: {9223372032559808512: 'zhg', 1: 'J0'}
-};
-Map<Set<int>, Map<String, bool>> var465 = {
- {-5, 9223372034707292161, 4294967295, 45, 45}: {
- 'gZ(\u{1f600}lcx': true,
- 'OE26!': true,
- '': false,
- '\u{1f600}g06Ds-': false
- },
- {44, 45}: {'VDF2': true},
- {38, 15, 9223372034707292159}: {'3sUF': true},
- {9, 13, -21, -19}: {'#': false},
- {-8, 1, -5, 23, -36}: {'xU': false, '': false},
- {45, -80}: {
- 'mVpNA': false,
- 'kdhkBX': false,
- 'O75cV': true,
- '@mb\u2665DI': false
- }
-};
-Map<Set<int>, Map<String, int>> var466 = {
- {-9223372030412324865, 0, 37}: {
- 'Oea2bv': -52,
- 'A2NwG': -58,
- 'n': 25,
- 'bE': 38,
- 'xuYo': -22
- },
- {-26, 16}: {'31n&24&': -1, '5jQtv': -9223372034707292160, '': -45},
- {-18, 22}: {
- 'v\u2665!aO': -46,
- '2h(': -76,
- 'hakD0Vq': -9223372030412324863,
- '': 28,
- 'Q+Xe\u{1f600}P': -79
- },
- {-18}: {'D!V&cI!': 35},
- {26, 19, -14, -11, 9223372034707292159}: {'!': -33, 'm': 47}
-};
-Map<Set<int>, Map<String, String>> var467 = {
- {-17, -40, 24, -23, 3}: {
- '6': 'M8',
- 'wR': '\u{1f600}lWL\u{1f600}',
- 'v': '\u{1f600}\u2665',
- 'EuIH': '3\u{1f600}mFOz\u{1f600}',
- '-XNBR\u26650': 'e&Oh'
- },
- {11}: {'ppB!': ' PUC+)D', 'Md': 'hiz', '92Yfv': 'e#8Qf', 'K': 'U', '': 'p'},
- {-13, 48, 34, -69, -2147483647}: {'ym': 'JG)7t', 'IUPko': '', 'eH': ''},
- {-68, -9223372032559808513}: {
- 'HqBu)ht': 'r\u2665c-\u2665m',
- 'w2\u{1f600}maJ': 'Tt',
- 'E': ''
- },
- {-9223372030412324864, 40, 2, -58, 41}: {
- '': 'cL75OnB',
- '': '1xOoPB\u2665',
- '@i6p-': '2ebn'
- },
- {-69, 32}: {
- 'Pp': '5 &',
- '\u2665\u2665': 'Weh',
- '\u266558xdEv': 'Tj b',
- 'J8s': 'K '
- }
-};
-Map<Set<int>, MapEntry<bool, bool>> var468 = {
- {8}: MapEntry<bool, bool>(false, false)
-};
-Map<Set<int>, MapEntry<bool, int>> var469 = {
- {-9223372032559808512, 15, 6}: MapEntry<bool, int>(true, 19),
- {-94}: MapEntry<bool, int>(false, 8),
- {45}: MapEntry<bool, int>(false, 49),
- {-90}: MapEntry<bool, int>(true, 2),
- {24, -10, 33}: MapEntry<bool, int>(false, 19)
-};
-Map<Set<int>, MapEntry<bool, String>> var470 = {
- {-2147483649}: MapEntry<bool, String>(false, 'vgA '),
- {15}: MapEntry<bool, String>(true, 'i\u2665(I')
-};
-Map<Set<int>, MapEntry<int, bool>> var471 = {
- {-64, 9, 18, 9, -28}: MapEntry<int, bool>(3, false),
- {-38, 4}: MapEntry<int, bool>(16, false),
- {3, 11, 5}: MapEntry<int, bool>(5, false),
- {11, -54, -86, 22}: MapEntry<int, bool>(9, true),
- {9223372036854775807, -61, -80, 45}: MapEntry<int, bool>(47, false)
-};
-Map<Set<int>, MapEntry<int, int>> var472 = {
- {-94, -57, -67, -87, 14}: MapEntry<int, int>(27, 11)
-};
-Map<Set<int>, MapEntry<int, String>> var473 = {
- {30, -78, -75, -35, 4294967296}: MapEntry<int, String>(26, 'I\u2665!ZIF')
-};
-Map<Set<int>, MapEntry<String, bool>> var474 = {
- {-67}: MapEntry<String, bool>('nX', false),
- {4, -57, -21}: MapEntry<String, bool>('\u{1f600}w8l', false),
- {-42, -83}: MapEntry<String, bool>('', true),
- {-23, -93}: MapEntry<String, bool>('tZ', true),
- {2147483649, 22}: MapEntry<String, bool>('FV3', true)
-};
-Map<Set<int>, MapEntry<String, int>> var475 = {
- {33, 15, 0, -9223372036854775808}: MapEntry<String, int>('y', 19),
- {24}: MapEntry<String, int>('j-G', 23),
- {7, -9223372036854775808, 28}:
- MapEntry<String, int>('D\u{1f600}55\u{1f600}x7', 6),
- {39, -17, -43, -79}: MapEntry<String, int>('7', 4)
-};
-Map<Set<int>, MapEntry<String, String>> var476 = {
- {9223372034707292161, 17, -90, 47}: MapEntry<String, String>('S!e', '6-v0g'),
- {6442450943, 11, -73}: MapEntry<String, String>('s\u2665AWr', ''),
- {-9223372036854775807, 22, 38, 4294967296, -51}:
- MapEntry<String, String>('', ' d\u2665\u{1f600}FT\u2665'),
- {-93, -44, 15, -52}: MapEntry<String, String>('6y', 's'),
- {-97, -4294967295, -80, -86}: MapEntry<String, String>('\u{1f600}JFHNIQ', ''),
- {-78, 9223372034707292161, -63, 30, -47}: MapEntry<String, String>('+', 'BJ+')
-};
-Map<Set<String>, bool> var477 = {
- {'Edtt', '0', 'MX', 'Ax', 'Tf6V'}: false,
- {'', 'V3tKVCc', '&', '&x1s'}: true,
- {'', '1xTMi7'}: false
-};
-Map<Set<String>, int> var478 = {
- {'7o\u{1f600}', '&AZ79G+', '', '\u2665W)I'}: 29
-};
-Map<Set<String>, String> var479 = {
- {'i'}: '\u2665t1M@',
- {'WpI ', '', '\u{1f600}wt5I', 'LKz0+@'}: '',
- {'o#1\u{1f600}', '', '3', ''}: '&n9',
- {'V4)', '\u{1f600}yQb', '', 'c\u2665kiV', 'c\u2665mrmc'}: '6XGKK',
- {'', 'u'}: '\u2665(tE0'
-};
-Map<Set<String>, Expando<bool>> var480 = {
- {'\u2665&-UOV'}: Expando<bool>('jlf0'),
- {'VFnw', '3UXzVA', '', 'y', '('}: Expando<bool>('8hxqz'),
- {'', 'O\u2665IF5'}: Expando<bool>('3C\u{1f600}\u{1f600}EA')
-};
-Map<Set<String>, Expando<int>> var481 = {
- {'5'}: Expando<int>('B'),
- {'R&K\u{1f600}mh', '-TQCjW', '-', 'j', 'B'}: Expando<int>(')V7\u2665NR')
-};
-Map<Set<String>, Expando<String>> var482 = {
- {'b', 'm(BR\u{1f600}', '3l', '8#\u266509x', ''}:
- Expando<String>('\u2665\u2665X\u2665f'),
- {'gcp\u{1f600}j(l'}: Expando<String>('!\u{1f600}-sr'),
- {'yiABp\u{1f600}', 'Eh\u2665#c\u{1f600}', 'FO\u2665qb5'}:
- Expando<String>('Hc'),
- {'V7yIx!', 'ST+)', ''}: Expando<String>('8NX4o\u{1f600}+'),
- {'mVp6Qv)'}: Expando<String>('iJf5'),
- {'', 'oP'}: Expando<String>('BM-\u2665')
-};
-Map<Set<String>, List<bool>> var483 = {
- {'JKm\u26656'}: [false, false, true],
- {'\u{1f600}DN'}: [true, true, true],
- {'\u{1f600}I\u2665', 'vQkU!', 'B\u2665\u{1f600}l', 'y', '5XgcNC9'}: [
- true,
- false,
- false,
- false
- ],
- {'xh7!CE\u{1f600}'}: [false, true]
-};
-Map<Set<String>, List<int>> var484 = {
- {'', '#)5Caw0', 'Or'}: Int64List(32),
- {'!q\u26652fm', 'X'}: Int8List.fromList([14, 1, -9223372034707292160]),
- {'q', 'VT3j', 'S1K', ''}: Int64List(40),
- {'2twYk0', '&1', '5D', ')eSl'}: Int32List(49),
- {'1ct0', '', 'joDmh', 'C)\u{1f600}U', 'H'}: Uint32List(36),
- {'l', 'rwW\u{1f600}', 'o', 'Q\u26659D', 'ZoVc\u{1f600}'}:
- Int64List.fromList(Uint16List(11))
-};
-Map<Set<String>, List<String>> var485 = {
- {'F\u{1f600}F', 'ZR', 'uv2U'}: ['V@4i \u2665']
-};
-Map<Set<String>, Set<bool>> var486 = {
- {'B9V', 'Ikg0\u2665RM', '(T4', '', ''}: {false, true},
- {'iQh1', '7', '6o', 'nzVT'}: {false, false, false}
-};
-Map<Set<String>, Set<int>> var487 = {
- {'G-', '-oE', ''}: {44, -97, 18, 8589934591},
- {'Yry'}: {5},
- {'\u26654\u2665x', 'G\u2665zGA3r', ''}: {-49, -51, -80, -72, -75},
- {'W R7iN'}: {-29, -21},
- {'o\u{1f600}', '', '\u{1f600}', 'R)0HOB'}: {
- 4294967295,
- 48,
- 40,
- 2147483649,
- -76
- },
- {'dnQO', '\u{1f600}-xFcXs', 'DRD', '', '1-(jo9I'}: {
- -91,
- -3,
- -41,
- 9223372034707292159,
- -32
- }
-};
-Map<Set<String>, Set<String>> var488 = {
- {'Q', 'gyKurL\u{1f600}', '4ujk99'}: {'', 'p', '\u2665'},
- {'A'}: {'LlrTj9', 'ehKmEUZ'},
- {'-F\u2665tcXA', '!uc', 'GZETwM'}: {'Ek', 'p0', 'w\u{1f600}uOv'},
- {'', 'nU-g', '9', 'bS', '\u2665(hs8q\u{1f600}'}: {'c0SC'},
- {')b\u{1f600}&F4M', 'XM', 'uO', '@SYwAwx', 'kkxwsT'}: {'ixC'}
-};
-Map<Set<String>, Map<bool, bool>> var489 = {
- {'OP0rJ22', 'Miycjk\u2665', 'u', 'XMC)'}: {false: false},
- {'H\u{1f600}hO9 ', 'G+)\u2665\u2665U', '\u{1f600}a2R', 'ZW)'}: {
- false: true,
- true: false
- },
- {'a', 'bX0C', '8gp5 5', 'G', '3Xt0Ml'}: {true: true},
- {'P3\u{1f600}', 'H', 'vlY'}: {
- true: true,
- true: true,
- true: false,
- true: false
- },
- {')k', '', 'N', 'Z(p4c'}: {
- true: false,
- false: true,
- false: false,
- false: true,
- true: false
- }
-};
-Map<Set<String>, Map<bool, int>> var490 = {
- {'\u{1f600}g 8xOJ', ''}: {true: -27, false: 17},
- {'F'}: {false: -90, true: -45, false: 13, false: -30},
- {'H1FV\u2665', 'aV', '\u2665\u{1f600}j', 'oZib-mS', 'a6H'}: {
- false: -1,
- true: -59,
- false: -19,
- true: -6
- },
- {'', 'pdT1v', 'EtW5d', 'ff'}: {
- true: 43,
- true: -92,
- false: -97,
- true: -18,
- false: 19
- },
- {'Mw\u{1f600}4Ib', '', '4W \u2665B', 'Qll', '+W&\u{1f600}Gc3'}: {
- false: -9223372032559808511,
- true: -97,
- false: 14,
- false: 6442450945,
- true: 14
- },
- {'3-OYHTC'}: {true: -28, true: -11, true: 4294967297, false: 22}
-};
-Map<Set<String>, Map<bool, String>> var491 = {
- {'\u2665', 'sy\u{1f600}', 'QZ6iw', ''}: {true: 'o', true: '0'},
- {'O2))q-', '', '', 'sI', '+f'}: {
- true: 'YA',
- false: '1eZnR',
- false: '\u2665ycv3',
- false: 'ZS8y1'
- }
-};
-Map<Set<String>, Map<int, bool>> var492 = {
- {'e\u{1f600}2dIWT', '', 'JP8\u{1f600}7zI', '', 'bF1rA(\u2665'}: {43: true},
- {'Xx\u2665F', 'MH3uf', 'gQ8', '5'}: {
- 32: true,
- 6442450943: true,
- 9223372034707292159: false,
- -69: false,
- 11: true
- },
- {'oU\u{1f600}aj', ''}: {
- -29: true,
- -26: false,
- 49: false,
- -9223372030412324863: true
- },
- {'hwo&0', 'D9jJL', 'R', ')Nr\u2665si\u2665'}: {9223372032559808513: true},
- {'VSYI', '+ovoyrV', 'tq\u{1f600}', '\u2665\u2665XGZ'}: {-61: false}
-};
-Map<Set<String>, Map<int, int>> var493 = {
- {'HoA\u26654ir', 'a5Wt', 'FD', ''}: {-59: -17},
- {'p', 'dfZ', 'r'}: {44: -45, 43: -72, -80: -54},
- {'+CW', 'YZcEA', 'l+K#\u{1f600}', 'Az', 'j84u'}: {44: 44},
- {'pNpn\u2665\u2665', 'swWBQII', 'v\u26655yMm9', 'u3o'}: {38: 18}
-};
-Map<Set<String>, Map<int, String>> var494 = {
- {'\u{1f600}un', 'Qi', 'R'}: {-4: 'cL3B#\u{1f600}'},
- {'Fi+8o5M', 'C', 'E', 'F4T19IA'}: {
- -77: '',
- 35: '\u{1f600}\u2665Y',
- 4: 'H4',
- 11: 'oYr6'
- },
- {'', 'u\u2665yx7'}: {43: '4\u2665zLTI', -47: '\u2665\u{1f600}Zp1H'}
-};
-Map<Set<String>, Map<String, bool>> var495 = {
- {'EMY\u{1f600}bm'}: {
- '\u{1f600}xE\u{1f600}Z': false,
- '': false,
- '': false,
- 'h&a': false
- },
- {'Sq', 'h', '', 'RkAh)#E'}: {'6E1Xp': true, '0S': false},
- {'Erl\u{1f600}'}: {
- 'I#j': false,
- '!AnQn': false,
- 'kM#': false,
- '': true,
- '\u{1f600}\u2665': true
- }
-};
-Map<Set<String>, Map<String, int>> var496 = {
- {'\u{1f600}tk', ''}: {'': -85, '': 48, 'sq+N': -46},
- {'', 'S\u{1f600}\u{1f600}5&h', '0CDc\u{1f600}Lt', 'SXX#', '\u{1f600}'}: {
- 'hSI2Kt2': 37,
- 'v\u2665LdqET': 2147483648,
- '\u2665': -40,
- 'RfjRMgP': 19
- },
- {'', 'F(', '2', 'ZnZ4y&', 'rA'}: {'': -44},
- {'y0kM\u{1f600}p', 'S8jM!', 'Mv', '\u26657A@x', '\u2665QKB\u{1f600}'}: {
- 'wd\u{1f600}Lr\u{1f600}7': -14
- },
- {'IVbFum', 'aL\u{1f600}a', 'F\u{1f600}Frco', 'I3'}: {
- 'jsQd': 12,
- '7hwW': -83,
- 'LTB\u2665Z': -31
- },
- {'FPEVB#S', 'u'}: {'!EtZ\u2665': -71}
-};
-Map<Set<String>, Map<String, String>> var497 = {
- {'', 'O'}: {'z 80-G': 'ksEMLjw', 'e\u2665@ol': 'LjHz2', 'Rbl)U6B': 'y##G'},
- {'15', 'sF', '\u266597y', 'px(RU'}: {
- 'OEq': 'ebie!',
- '@fbrIu': 'g',
- 'WTv': 'bm\u{1f600}\u2665U',
- 'U': 'Qu2',
- 'w+0\u2665FM': '2'
- },
- {'&N'}: {
- '': '+',
- '': 'M#u))S!',
- 'CY\u{1f600}U': '\u2665Jne6P',
- 'Imn\u{1f600}10\u{1f600}': '1N\u2665V'
- }
-};
-Map<Set<String>, MapEntry<bool, bool>> var498 = {
- {'D4L', 'nd'}: new MapEntry<bool, bool>(true, false),
- {'BPeS'}: MapEntry<bool, bool>(false, false)
-};
-Map<Set<String>, MapEntry<bool, int>> var499 = {
- {'e0fLZ', 'Xg'}: MapEntry<bool, int>(true, 38),
- {'\u2665', '-MPkh\u2665y', 'fwp7', 'dekk'}: MapEntry<bool, int>(false, 15),
- {'', 'JC7byk&', '5@q\u{1f600}', '2Y1t@Z'}: MapEntry<bool, int>(true, 13),
- {'\u2665!K\u2665 vw'}: MapEntry<bool, int>(true, 38),
- {'nk(duko', '1iMo', '6#L', 'dxB\u2665 H'}: MapEntry<bool, int>(false, 25)
-};
-Map<Set<String>, MapEntry<bool, String>> var500 = {
- {'p\u2665c4', 'HIunA'}: MapEntry<bool, String>(true, 'S\u2665hiuG'),
- {'O4j\u26655', 'pnl'}: new MapEntry<bool, String>(false, '#oyGV7M'),
- {'xS', '', 's\u{1f600}xn\u{1f600}#'}: MapEntry<bool, String>(true, 'DW'),
- {'mWntxmj', 'tF8(\u2665d'}: MapEntry<bool, String>(true, 'X\u2665s&JF'),
- {' Oj', '#5ioq'}: new MapEntry<bool, String>(false, 'L\u{1f600}E6'),
- {'\u2665z@#', '2', 'OA0kWi', 'iX&\u{1f600}', 'I4-u'}:
- MapEntry<bool, String>(false, 'GX7')
-};
+@pragma('vm:prefer-inline')
+bool lessThan(int x, int y) => x < y;
-void foo0_0() {
- [-63].removeRange(30, 9223372034707292161);
+@pragma('vm:prefer-inline')
+int accessArray(List<int> arr, int i) => arr[i];
+
+void problem(List<int> arr, int n, bool f) {
+ final C = 0x7000000000000000;
+ for (var i = C, j = 0; lessThan(i, n); i++, j++) {
+ if (f) {
+ // Produce CheckSmi against C. This CheckSmi will be
+ // hoisted out of the loop turning phi for j into a Smi
+ // Phi.
+ checkSmi(C);
+ accessArray(arr, j); // Produce array access with bounds check for arr.
+ }
+ }
}
-main() {
- try {
- foo0_0();
- } catch (e, st) {
- print('foo0_0 throws');
- }
- try {
- print(
- '$var0\n$var1\n$var2\n$var3\n$var4\n$var5\n$var6\n$var7\n$var8\n$var9\n$var10\n$var11\n$var12\n$var13\n$var14\n$var15\n$var16\n$var17\n$var18\n$var19\n$var20\n$var21\n$var22\n$var23\n$var24\n$var25\n$var26\n$var27\n$var28\n$var29\n$var30\n$var31\n$var32\n$var33\n$var34\n$var35\n$var36\n$var37\n$var38\n$var39\n$var40\n$var41\n$var42\n$var43\n$var44\n$var45\n$var46\n$var47\n$var48\n$var49\n$var50\n$var51\n$var52\n$var53\n$var54\n$var55\n$var56\n$var57\n$var58\n$var59\n$var60\n$var61\n$var62\n$var63\n$var64\n$var65\n$var66\n$var67\n$var68\n$var69\n$var70\n$var71\n$var72\n$var73\n$var74\n$var75\n$var76\n$var77\n$var78\n$var79\n$var80\n$var81\n$var82\n$var83\n$var84\n$var85\n$var86\n$var87\n$var88\n$var89\n$var90\n$var91\n$var92\n$var93\n$var94\n$var95\n$var96\n$var97\n$var98\n$var99\n$var100\n$var101\n$var102\n$var103\n$var104\n$var105\n$var106\n$var107\n$var108\n$var109\n$var110\n$var111\n$var112\n$var113\n$var114\n$var115\n$var116\n$var117\n$var118\n$var119\n$var120\n$var121\n$var122\n$var123\n$var124\n$var125\n$var126\n$var127\n$var128\n$var129\n$var130\n$var131\n$var132\n$var133\n$var134\n$var135\n$var136\n$var137\n$var138\n$var139\n$var140\n$var141\n$var142\n$var143\n$var144\n$var145\n$var146\n$var147\n$var148\n$var149\n$var150\n$var151\n$var152\n$var153\n$var154\n$var155\n$var156\n$var157\n$var158\n$var159\n$var160\n$var161\n$var162\n$var163\n$var164\n$var165\n$var166\n$var167\n$var168\n$var169\n$var170\n$var171\n$var172\n$var173\n$var174\n$var175\n$var176\n$var177\n$var178\n$var179\n$var180\n$var181\n$var182\n$var183\n$var184\n$var185\n$var186\n$var187\n$var188\n$var189\n$var190\n$var191\n$var192\n$var193\n$var194\n$var195\n$var196\n$var197\n$var198\n$var199\n$var200\n$var201\n$var202\n$var203\n$var204\n$var205\n$var206\n$var207\n$var208\n$var209\n$var210\n$var211\n$var212\n$var213\n$var214\n$var215\n$var216\n$var217\n$var218\n$var219\n$var220\n$var221\n$var222\n$var223\n$var224\n$var225\n$var226\n$var227\n$var228\n$var229\n$var230\n$var231\n$var232\n$var233\n$var234\n$var235\n$var236\n$var237\n$var238\n$var239\n$var240\n$var241\n$var242\n$var243\n$var244\n$var245\n$var246\n$var247\n$var248\n$var249\n$var250\n$var251\n$var252\n$var253\n$var254\n$var255\n$var256\n$var257\n$var258\n$var259\n$var260\n$var261\n$var262\n$var263\n$var264\n$var265\n$var266\n$var267\n$var268\n$var269\n$var270\n$var271\n$var272\n$var273\n$var274\n$var275\n$var276\n$var277\n$var278\n$var279\n$var280\n$var281\n$var282\n$var283\n$var284\n$var285\n$var286\n$var287\n$var288\n$var289\n$var290\n$var291\n$var292\n$var293\n$var294\n$var295\n$var296\n$var297\n$var298\n$var299\n$var300\n$var301\n$var302\n$var303\n$var304\n$var305\n$var306\n$var307\n$var308\n$var309\n$var310\n$var311\n$var312\n$var313\n$var314\n$var315\n$var316\n$var317\n$var318\n$var319\n$var320\n$var321\n$var322\n$var323\n$var324\n$var325\n$var326\n$var327\n$var328\n$var329\n$var330\n$var331\n$var332\n$var333\n$var334\n$var335\n$var336\n$var337\n$var338\n$var339\n$var340\n$var341\n$var342\n$var343\n$var344\n$var345\n$var346\n$var347\n$var348\n$var349\n$var350\n$var351\n$var352\n$var353\n$var354\n$var355\n$var356\n$var357\n$var358\n$var359\n$var360\n$var361\n$var362\n$var363\n$var364\n$var365\n$var366\n$var367\n$var368\n$var369\n$var370\n$var371\n$var372\n$var373\n$var374\n$var375\n$var376\n$var377\n$var378\n$var379\n$var380\n$var381\n$var382\n$var383\n$var384\n$var385\n$var386\n$var387\n$var388\n$var389\n$var390\n$var391\n$var392\n$var393\n$var394\n$var395\n$var396\n$var397\n$var398\n$var399\n$var400\n$var401\n$var402\n$var403\n$var404\n$var405\n$var406\n$var407\n$var408\n$var409\n$var410\n$var411\n$var412\n$var413\n$var414\n$var415\n$var416\n$var417\n$var418\n$var419\n$var420\n$var421\n$var422\n$var423\n$var424\n$var425\n$var426\n$var427\n$var428\n$var429\n$var430\n$var431\n$var432\n$var433\n$var434\n$var435\n$var436\n$var437\n$var438\n$var439\n$var440\n$var441\n$var442\n$var443\n$var444\n$var445\n$var446\n$var447\n$var448\n$var449\n$var450\n$var451\n$var452\n$var453\n$var454\n$var455\n$var456\n$var457\n$var458\n$var459\n$var460\n$var461\n$var462\n$var463\n$var464\n$var465\n$var466\n$var467\n$var468\n$var469\n$var470\n$var471\n$var472\n$var473\n$var474\n$var475\n$var476\n$var477\n$var478\n$var479\n$var480\n$var481\n$var482\n$var483\n$var484\n$var485\n$var486\n$var487\n$var488\n$var489\n$var490\n$var491\n$var492\n$var493\n$var494\n$var495\n$var496\n$var497\n$var498\n$var499\n$var500\n');
- } catch (e, st) {
- print('print() throws');
- }
+void main() {
+ // Prime type feedback in checkSmi and accessArray helpers.
+ // Note: we need these to be in separate helpers because we need
+ // problematic code to appear on a never executed code path.
+ // (It would trigger throw/deopt if it is ever executed).
+ checkSmi(0);
+ accessArray([1], 0);
+ lessThan(1, 1);
+
+ // Trigger the issue.
+ problem([], 1, false);
}
diff --git a/runtime/tests/vm/dart/unboxed_param_args_descriptor_test.dart b/runtime/tests/vm/dart/unboxed_param_args_descriptor_test.dart
new file mode 100644
index 0000000..6606fc4
--- /dev/null
+++ b/runtime/tests/vm/dart/unboxed_param_args_descriptor_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, 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.
+//
+// SharedObjects=ffi_test_functions
+
+import 'package:expect/expect.dart';
+
+import 'dylib_utils.dart';
+
+@pragma('vm:never-inline')
+int foo<T>(int i, T j, Type t) {
+ triggerGc();
+ Expect.equals(T, t);
+ return i + 2;
+}
+
+main() {
+ final x = foo(1, 0.0, double);
+ final y = foo(2, 0, int);
+ Expect.equals(3, x);
+ Expect.equals(4, y);
+}
diff --git a/runtime/tests/vm/dart/unboxed_param_tear_off_test.dart b/runtime/tests/vm/dart/unboxed_param_tear_off_test.dart
new file mode 100644
index 0000000..4ef1f7f
--- /dev/null
+++ b/runtime/tests/vm/dart/unboxed_param_tear_off_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2020, 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.
+//
+// SharedObjects=ffi_test_functions
+
+import 'package:expect/expect.dart';
+
+import 'dylib_utils.dart';
+import 'unboxed_parameter_helper.dart';
+
+class Foo {
+ int val;
+ Foo(this.val);
+}
+
+var globalFoo;
+
+@pragma('vm:never-inline')
+int bar(int i, Foo foo, double j) {
+ triggerGc();
+ globalFoo.val = 0;
+ return i + 2 + j.toInt() - j.toInt() + foo.val;
+}
+
+@pragma('vm:never-inline')
+createFoo() {
+ globalFoo = Foo(1);
+}
+
+final bool kTrue = int.parse('1') == 1;
+
+@pragma('vm:never-inline')
+testExecution(func, double param) {
+ Expect.equals(3, func(kTrue ? 1 : 2, globalFoo, kTrue ? param : 1.0));
+}
+
+main() {
+ createFoo();
+ final dbl = getDoubleWithHeapObjectTag();
+ testExecution(bar, dbl);
+}
diff --git a/runtime/tests/vm/dart/unboxed_param_test.dart b/runtime/tests/vm/dart/unboxed_param_test.dart
new file mode 100644
index 0000000..0ce12da
--- /dev/null
+++ b/runtime/tests/vm/dart/unboxed_param_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, 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.
+//
+// SharedObjects=ffi_test_functions
+
+import 'package:expect/expect.dart';
+
+import 'dylib_utils.dart';
+import 'unboxed_parameter_helper.dart';
+
+class Foo {
+ int val;
+ Foo(this.val);
+}
+
+var globalFoo;
+
+final dbl2 = getDoubleWithHeapObjectTag();
+
+@pragma('vm:never-inline')
+double bar(int i, double k, Foo foo, double j, [int optional = 1]) {
+ triggerGc();
+ globalFoo.val = 0;
+ return (i + 2 + j.toInt() - j.toInt() + globalFoo.val + optional).toDouble();
+}
+
+@pragma('vm:never-inline')
+createFoo() {
+ globalFoo = Foo(1);
+}
+
+final bool kTrue = int.parse('1') == 1;
+
+main() {
+ createFoo();
+ final dbl = getDoubleWithHeapObjectTag();
+ Expect.equals(4.0,
+ bar(kTrue ? 1 : 2, kTrue ? 2 * dbl : 0.0, globalFoo, kTrue ? dbl : 1.0));
+ Expect.equals(
+ 3.0,
+ bar(kTrue ? 1 : 2, kTrue ? 2 * dbl : 0.0, globalFoo, kTrue ? dbl : 1.0,
+ 0));
+}
diff --git a/runtime/tests/vm/dart/unboxed_parameter_helper.dart b/runtime/tests/vm/dart/unboxed_parameter_helper.dart
new file mode 100644
index 0000000..b0ee815
--- /dev/null
+++ b/runtime/tests/vm/dart/unboxed_parameter_helper.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, 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.
+
+import 'dart:typed_data';
+
+@pragma('vm:never-inline')
+double getDoubleWithHeapObjectTag() {
+ final bd = ByteData(8);
+ bd.setUint64(0, 0x8000000180000001, Endian.host);
+ final double v = bd.getFloat64(0, Endian.host);
+ return v;
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index bb2029b..a464e6b 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -238,6 +238,11 @@
[ $compiler == dart2analyzer || $compiler == dart2js ]
dart/data_uri*test: Skip # Data uri's not supported by dart2js or the analyzer.
+[ $arch == simarm || $arch == simarm64 ]
+dart/unboxed_param_args_descriptor_test: SkipByDesign # FFI helper not supported on simulator
+dart/unboxed_param_tear_off_test: SkipByDesign # FFI helper not supported on simulator
+dart/unboxed_param_test: SkipByDesign # FFI helper not supported on simulator
+
[ $compiler == dartk || $compiler == dartkb ]
cc/DartAPI_New: Fail # Issue #33041
cc/DartGeneratedArrayLiteralMessages: Crash # Issue 32190
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 0fc808c..b6a759f 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -642,6 +642,7 @@
func->ptr()->end_token_pos_ = d->ReadTokenPosition();
func->ptr()->binary_declaration_ = d->Read<uint32_t>();
}
+ func->ptr()->unboxed_parameters_info_.Reset();
#endif
func->ptr()->packed_fields_ = d->Read<uint32_t>();
func->ptr()->kind_tag_ = d->Read<uint32_t>();
diff --git a/runtime/vm/code_patcher_arm64_test.cc b/runtime/vm/code_patcher_arm64_test.cc
index 051a503..de240e2 100644
--- a/runtime/vm/code_patcher_arm64_test.cc
+++ b/runtime/vm/code_patcher_arm64_test.cc
@@ -35,8 +35,8 @@
const String& target_name = String::Handle(String::New("targetFunction"));
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 1;
- const Array& args_descriptor = Array::Handle(
- ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs, Object::null_array()));
+ const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
+ kTypeArgsLen, kNumArgs, Object::null_array()));
const ICData& ic_data = ICData::ZoneHandle(ICData::New(
function, target_name, args_descriptor, 15, 1, ICData::kInstance));
const Code& stub = StubCode::OneArgCheckInlineCache();
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index 9463dae..2e31dc8 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -35,8 +35,8 @@
const String& target_name = String::Handle(String::New("targetFunction"));
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 1;
- const Array& args_descriptor = Array::Handle(
- ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs, Object::null_array()));
+ const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
+ kTypeArgsLen, kNumArgs, Object::null_array()));
const ICData& ic_data = ICData::ZoneHandle(ICData::New(
function, target_name, args_descriptor, 15, 1, ICData::kInstance));
diff --git a/runtime/vm/code_patcher_ia32_test.cc b/runtime/vm/code_patcher_ia32_test.cc
index 19e4563..8aa1cd6 100644
--- a/runtime/vm/code_patcher_ia32_test.cc
+++ b/runtime/vm/code_patcher_ia32_test.cc
@@ -35,8 +35,8 @@
const String& target_name = String::Handle(String::New("targetFunction"));
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 1;
- const Array& args_descriptor = Array::Handle(
- ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs, Object::null_array()));
+ const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
+ kTypeArgsLen, kNumArgs, Object::null_array()));
const ICData& ic_data = ICData::ZoneHandle(ICData::New(
function, target_name, args_descriptor, 15, 1, ICData::kInstance));
diff --git a/runtime/vm/code_patcher_x64_test.cc b/runtime/vm/code_patcher_x64_test.cc
index d6ac021..e838880 100644
--- a/runtime/vm/code_patcher_x64_test.cc
+++ b/runtime/vm/code_patcher_x64_test.cc
@@ -35,8 +35,8 @@
const String& target_name = String::Handle(String::New("targetFunction"));
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 1;
- const Array& args_descriptor = Array::Handle(
- ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs, Object::null_array()));
+ const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
+ kTypeArgsLen, kNumArgs, Object::null_array()));
const ICData& ic_data = ICData::ZoneHandle(ICData::New(
function, target_name, args_descriptor, 15, 1, ICData::kInstance));
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc
index 8a61638..28ad54a 100644
--- a/runtime/vm/compilation_trace.cc
+++ b/runtime/vm/compilation_trace.cc
@@ -119,7 +119,10 @@
Function& dispatcher = Function::Handle(zone_);
for (intptr_t argc = 1; argc <= 4; argc++) {
const intptr_t kTypeArgsLen = 0;
- arguments_descriptor = ArgumentsDescriptor::New(kTypeArgsLen, argc);
+
+ // TODO(dartbug.com/33549): Update this code to use the size of the
+ // parameters when supporting calls to closures with unboxed parameters.
+ arguments_descriptor = ArgumentsDescriptor::NewBoxed(kTypeArgsLen, argc);
dispatcher = closure_class.GetInvocationDispatcher(
Symbols::Call(), arguments_descriptor,
RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */);
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index c175f3d..78e6edd 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -124,6 +124,9 @@
RedefinitionInstr* redefinition = new (Z)
RedefinitionInstr(new (Z) Value(call->ArgumentAt(receiver_index)));
redefinition->set_ssa_temp_index(flow_graph()->alloc_ssa_temp_index());
+ if (FlowGraph::NeedsPairLocation(redefinition->representation())) {
+ flow_graph()->alloc_ssa_temp_index();
+ }
redefinition->InsertAfter(call);
// Replace all uses of the receiver dominated by this call.
FlowGraph::RenameDominatedUses(call->ArgumentAt(receiver_index),
@@ -220,6 +223,13 @@
static bool HasLikelySmiOperand(InstanceCallInstr* instr) {
ASSERT(instr->type_args_len() == 0);
+
+ // If Smi is not assignable to the interface target of the call, the receiver
+ // is definitely not a Smi.
+ if (instr->HasNonSmiAssignableInterface(Thread::Current()->zone())) {
+ return false;
+ }
+
// Phis with at least one known smi are // guessed to be likely smi as well.
for (intptr_t i = 0; i < instr->ArgumentCount(); ++i) {
PhiInstr* phi = instr->ArgumentAt(i)->AsPhi();
@@ -472,9 +482,15 @@
CompileType* right_type = right_value->Type();
const bool is_equality_op = Token::IsEqualityOperator(op_kind);
- const bool has_nullable_int_args =
+ bool has_nullable_int_args =
left_type->IsNullableInt() && right_type->IsNullableInt();
+ if (auto* call = instr->AsInstanceCall()) {
+ if (call->HasNonSmiAssignableInterface(zone())) {
+ has_nullable_int_args = false;
+ }
+ }
+
// NOTE: We cannot use strict comparisons if the receiver has an overridden
// == operator or if either side can be a double, since 1.0 == 1.
const bool can_use_strict_compare =
@@ -1103,7 +1119,8 @@
}
const Array& args_desc_array = Array::Handle(
- Z, ArgumentsDescriptor::New(/*type_args_len=*/0, /*num_arguments=*/1));
+ Z,
+ ArgumentsDescriptor::NewBoxed(/*type_args_len=*/0, /*num_arguments=*/1));
ArgumentsDescriptor args_desc(args_desc_array);
target = Resolver::ResolveDynamicForReceiverClass(
receiver_class, getter_name, args_desc, /*allow_add=*/false);
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index f0cbab4..ae17d44 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -614,8 +614,13 @@
if (FLAG_trace_precompiler) {
THR_Print("Found callback field %s\n", field_name.ToCString());
}
- args_desc = ArgumentsDescriptor::New(0, // No type argument vector.
- function.num_fixed_parameters());
+
+ // TODO(dartbug.com/33549): Update this code to use the size of the
+ // parameters when supporting calls to non-static methods with
+ // unboxed parameters.
+ args_desc =
+ ArgumentsDescriptor::NewBoxed(0, // No type argument vector.
+ function.num_fixed_parameters());
cids.Clear();
if (CHA::ConcreteSubclasses(cls, &cids)) {
for (intptr_t j = 0; j < cids.length(); ++j) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index b19f66b..a6ba5bd 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -3679,10 +3679,12 @@
bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index) {
- // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
- const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
+ // If unboxed, index is expected smi-tagged, (i.e, LSL 1) for all arrays.
+ const intptr_t boxing_shift = index_unboxed ? 0 : -kSmiTagShift;
+ const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) + boxing_shift;
int32_t offset =
is_external ? 0 : (target::Instance::DataOffsetFor(cid) - kHeapObjectTag);
const OperandSize size = Address::OperandSizeFor(cid);
@@ -3720,10 +3722,12 @@
bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index) {
- // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
- const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
+ // If unboxed, index is expected smi-tagged, (i.e, LSL 1) for all arrays.
+ const intptr_t boxing_shift = index_unboxed ? 0 : -kSmiTagShift;
+ const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) + boxing_shift;
int32_t offset =
is_external ? 0 : (target::Instance::DataOffsetFor(cid) - kHeapObjectTag);
if (shift < 0) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 83784e2..94ec07e 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -1145,6 +1145,7 @@
bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index);
@@ -1153,6 +1154,7 @@
bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index e369909..ddfa229 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1762,23 +1762,26 @@
Address Assembler::ElementAddressForRegIndex(bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index,
Register temp) {
- return ElementAddressForRegIndexWithSize(is_external, cid,
- Address::OperandSizeFor(cid),
- index_scale, array, index, temp);
+ return ElementAddressForRegIndexWithSize(
+ is_external, cid, Address::OperandSizeFor(cid), index_scale,
+ index_unboxed, array, index, temp);
}
Address Assembler::ElementAddressForRegIndexWithSize(bool is_external,
intptr_t cid,
OperandSize size,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index,
Register temp) {
- // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
- const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
+ // If unboxed, index is expected smi-tagged, (i.e, LSL 1) for all arrays.
+ const intptr_t boxing_shift = index_unboxed ? 0 : -kSmiTagShift;
+ const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) + boxing_shift;
const int32_t offset = HeapDataOffset(is_external, cid);
ASSERT(array != temp);
ASSERT(index != temp);
@@ -1798,10 +1801,12 @@
bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index) {
- // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
- const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
+ // If unboxed, index is expected smi-tagged, (i.e, LSL 1) for all arrays.
+ const intptr_t boxing_shift = index_unboxed ? 0 : -kSmiTagShift;
+ const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) + boxing_shift;
const int32_t offset = HeapDataOffset(is_external, cid);
if (shift == 0) {
add(address, array, Operand(index));
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 4322594..985f77a 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1676,6 +1676,7 @@
Address ElementAddressForRegIndex(bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index,
Register temp);
@@ -1687,6 +1688,7 @@
intptr_t cid,
OperandSize size,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index,
Register temp);
@@ -1695,6 +1697,7 @@
bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index);
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 3424ea1..335494b 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -2735,38 +2735,58 @@
}
}
-static ScaleFactor ToScaleFactor(intptr_t index_scale) {
- // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with
- // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is
- // expected to be untagged before accessing.
- ASSERT(kSmiTagShift == 1);
- switch (index_scale) {
- case 1:
- return TIMES_1;
- case 2:
- return TIMES_1;
- case 4:
- return TIMES_2;
- case 8:
- return TIMES_4;
- case 16:
- return TIMES_8;
- default:
- UNREACHABLE();
- return TIMES_1;
+static ScaleFactor ToScaleFactor(intptr_t index_scale, bool index_unboxed) {
+ if (index_unboxed) {
+ switch (index_scale) {
+ case 1:
+ return TIMES_1;
+ case 2:
+ return TIMES_2;
+ case 4:
+ return TIMES_4;
+ case 8:
+ return TIMES_8;
+ case 16:
+ return TIMES_16;
+ default:
+ UNREACHABLE();
+ return TIMES_1;
+ }
+ } else {
+ // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
+ // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
+ // index is expected to be untagged before accessing.
+ ASSERT(kSmiTagShift == 1);
+ switch (index_scale) {
+ case 1:
+ return TIMES_1;
+ case 2:
+ return TIMES_1;
+ case 4:
+ return TIMES_2;
+ case 8:
+ return TIMES_4;
+ case 16:
+ return TIMES_8;
+ default:
+ UNREACHABLE();
+ return TIMES_1;
+ }
}
}
Address Assembler::ElementAddressForRegIndex(bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index,
intptr_t extra_disp) {
if (is_external) {
- return Address(array, index, ToScaleFactor(index_scale), extra_disp);
+ return Address(array, index, ToScaleFactor(index_scale, index_unboxed),
+ extra_disp);
} else {
- return FieldAddress(array, index, ToScaleFactor(index_scale),
+ return FieldAddress(array, index, ToScaleFactor(index_scale, index_unboxed),
target::Instance::DataOffsetFor(cid) + extra_disp);
}
}
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index da01d67..3ed40e3 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -153,6 +153,7 @@
Address(Register index, ScaleFactor scale, int32_t disp) {
ASSERT(index != ESP); // Illegal addressing mode.
+ ASSERT(scale != TIMES_16); // Unsupported scale factor.
SetModRM(0, ESP);
SetSIB(scale, index, EBP);
SetDisp32(disp);
@@ -163,6 +164,7 @@
Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
ASSERT(index != ESP); // Illegal addressing mode.
+ ASSERT(scale != TIMES_16); // Unsupported scale factor.
if (disp == 0 && base != EBP) {
SetModRM(0, ESP);
SetSIB(scale, index, base);
@@ -732,6 +734,7 @@
static Address ElementAddressForRegIndex(bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index,
intptr_t extra_disp = 0);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index c8732bf..604fcc3 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -2229,37 +2229,56 @@
}
}
-static ScaleFactor ToScaleFactor(intptr_t index_scale) {
- // Note that index is expected smi-tagged, (i.e, times 2) for all arrays with
- // index scale factor > 1. E.g., for Uint8Array and OneByteString the index is
- // expected to be untagged before accessing.
- ASSERT(kSmiTagShift == 1);
- switch (index_scale) {
- case 1:
- return TIMES_1;
- case 2:
- return TIMES_1;
- case 4:
- return TIMES_2;
- case 8:
- return TIMES_4;
- case 16:
- return TIMES_8;
- default:
- UNREACHABLE();
- return TIMES_1;
+static ScaleFactor ToScaleFactor(intptr_t index_scale, bool index_unboxed) {
+ if (index_unboxed) {
+ switch (index_scale) {
+ case 1:
+ return TIMES_1;
+ case 2:
+ return TIMES_2;
+ case 4:
+ return TIMES_4;
+ case 8:
+ return TIMES_8;
+ case 16:
+ return TIMES_16;
+ default:
+ UNREACHABLE();
+ return TIMES_1;
+ }
+ } else {
+ // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
+ // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
+ // index is expected to be untagged before accessing.
+ ASSERT(kSmiTagShift == 1);
+ switch (index_scale) {
+ case 1:
+ return TIMES_1;
+ case 2:
+ return TIMES_1;
+ case 4:
+ return TIMES_2;
+ case 8:
+ return TIMES_4;
+ case 16:
+ return TIMES_8;
+ default:
+ UNREACHABLE();
+ return TIMES_1;
+ }
}
}
Address Assembler::ElementAddressForRegIndex(bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index) {
if (is_external) {
- return Address(array, index, ToScaleFactor(index_scale), 0);
+ return Address(array, index, ToScaleFactor(index_scale, index_unboxed), 0);
} else {
- return FieldAddress(array, index, ToScaleFactor(index_scale),
+ return FieldAddress(array, index, ToScaleFactor(index_scale, index_unboxed),
target::Instance::DataOffsetFor(cid));
}
}
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 6253c48..7960806 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -192,6 +192,7 @@
Address(Register index, ScaleFactor scale, int32_t disp) {
ASSERT(index != RSP); // Illegal addressing mode.
+ ASSERT(scale != TIMES_16); // Unsupported scale factor.
SetModRM(0, RSP);
SetSIB(scale, index, RBP);
SetDisp32(disp);
@@ -202,6 +203,7 @@
Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
ASSERT(index != RSP); // Illegal addressing mode.
+ ASSERT(scale != TIMES_16); // Unsupported scale factor.
if ((disp == 0) && ((base & 7) != RBP)) {
SetModRM(0, RSP);
SetSIB(scale, index, base);
@@ -962,6 +964,7 @@
static Address ElementAddressForRegIndex(bool is_external,
intptr_t cid,
intptr_t index_scale,
+ bool index_unboxed,
Register array,
Register index);
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index 28c5d1e..afca0e8 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -23,6 +23,9 @@
Definition* AddToInitialDefinitions(Definition* def) {
def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+ if (FlowGraph::NeedsPairLocation(def->representation())) {
+ flow_graph_->alloc_ssa_temp_index();
+ }
auto normal_entry = flow_graph_->graph_entry()->normal_entry();
flow_graph_->AddToInitialDefinitions(normal_entry, def);
return def;
@@ -46,17 +49,35 @@
return instr;
}
+ const Function& function() const { return flow_graph_->function(); }
+
void AddReturn(Value* value) {
+ const auto& function = flow_graph_->function();
+ const auto representation = FlowGraph::ReturnRepresentationOf(function);
+
ReturnInstr* instr = new ReturnInstr(
- TokenPos(), value, CompilerState::Current().GetNextDeoptId());
+ TokenPos(), value, CompilerState::Current().GetNextDeoptId(),
+ RawPcDescriptors::kInvalidYieldIndex, representation);
AddInstruction(instr);
entry_->set_last_instruction(instr);
}
Definition* AddParameter(intptr_t index, bool with_frame) {
+ const auto& function = flow_graph_->function();
+ const intptr_t param_offset = FlowGraph::ParameterOffsetAt(function, index);
+ const auto representation =
+ FlowGraph::ParameterRepresentationAt(function, index);
+ return AddParameter(index, param_offset, with_frame, representation);
+ }
+
+ Definition* AddParameter(intptr_t index,
+ intptr_t param_offset,
+ bool with_frame,
+ Representation representation) {
auto normal_entry = flow_graph_->graph_entry()->normal_entry();
return AddToInitialDefinitions(
- new ParameterInstr(index, normal_entry, with_frame ? FPREG : SPREG));
+ new ParameterInstr(index, param_offset, normal_entry, representation,
+ with_frame ? FPREG : SPREG));
}
TokenPosition TokenPos() { return flow_graph_->function().token_pos(); }
@@ -100,6 +121,9 @@
void AddPhi(PhiInstr* phi) {
phi->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+ if (FlowGraph::NeedsPairLocation(phi->representation())) {
+ flow_graph_->alloc_ssa_temp_index();
+ }
phi->mark_alive();
entry_->AsJoinEntry()->InsertPhi(phi);
}
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 6d11d0c..084a67d 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -43,6 +43,7 @@
num_direct_parameters_(parsed_function.function().HasOptionalParameters()
? 0
: parsed_function.function().NumParameters()),
+ direct_parameters_size_(0),
graph_entry_(graph_entry),
preorder_(),
postorder_(),
@@ -57,6 +58,8 @@
captured_parameters_(new (zone()) BitVector(zone(), variable_count())),
inlining_id_(-1),
should_print_(FlowGraphPrinter::ShouldPrint(parsed_function.function())) {
+ direct_parameters_size_ = ParameterOffsetAt(
+ function(), num_direct_parameters_, /*last_slot*/ false);
DiscoverBlocks();
}
@@ -66,6 +69,67 @@
}
}
+intptr_t FlowGraph::ParameterOffsetAt(const Function& function,
+ intptr_t index,
+ bool last_slot /*=true*/) {
+ ASSERT(index <= function.NumParameters());
+ intptr_t param_offset = 0;
+ for (intptr_t i = 0; i < index; i++) {
+ if (function.is_unboxed_integer_parameter_at(i)) {
+ param_offset += compiler::target::kIntSpillFactor;
+ } else if (function.is_unboxed_double_parameter_at(i)) {
+ param_offset += compiler::target::kDoubleSpillFactor;
+ } else {
+ ASSERT(!function.is_unboxed_parameter_at(i));
+ // Unboxed parameters always occupy one word
+ param_offset++;
+ }
+ }
+ if (last_slot) {
+ ASSERT(index < function.NumParameters());
+ if (function.is_unboxed_double_parameter_at(index) &&
+ compiler::target::kDoubleSpillFactor > 1) {
+ ASSERT(compiler::target::kDoubleSpillFactor == 2);
+ param_offset++;
+ } else if (function.is_unboxed_integer_parameter_at(index) &&
+ compiler::target::kIntSpillFactor > 1) {
+ ASSERT(compiler::target::kIntSpillFactor == 2);
+ param_offset++;
+ }
+ }
+ return param_offset;
+}
+
+Representation FlowGraph::ParameterRepresentationAt(const Function& function,
+ intptr_t index) {
+ if (function.IsNull()) {
+ return kTagged;
+ }
+ ASSERT(index < function.NumParameters());
+ if (function.is_unboxed_integer_parameter_at(index)) {
+ return kUnboxedInt64;
+ } else if (function.is_unboxed_double_parameter_at(index)) {
+ return kUnboxedDouble;
+ } else {
+ ASSERT(!function.is_unboxed_parameter_at(index));
+ return kTagged;
+ }
+}
+
+Representation FlowGraph::ReturnRepresentationOf(const Function& function) {
+ if (function.IsNull()) {
+ return kTagged;
+ }
+ if (function.has_unboxed_integer_return()) {
+ return kUnboxedInt64;
+ } else if (function.has_unboxed_double_return()) {
+ return kUnboxedDouble;
+ } else {
+ ASSERT(!function.has_unboxed_return());
+ return kTagged;
+ }
+}
+
void FlowGraph::ReplaceCurrentInstruction(ForwardInstructionIterator* iterator,
Instruction* current,
Instruction* replacement) {
@@ -118,6 +182,9 @@
constant =
new (zone()) ConstantInstr(Object::ZoneHandle(zone(), object.raw()));
constant->set_ssa_temp_index(alloc_ssa_temp_index());
+ if (NeedsPairLocation(constant->representation())) {
+ alloc_ssa_temp_index();
+ }
AddToGraphInitialDefinitions(constant);
constant_instr_pool_.Insert(constant);
}
@@ -1038,9 +1105,31 @@
ASSERT(variable_count() == env->length());
ASSERT(direct_parameter_count <= env->length());
+ intptr_t param_offset = 0;
for (intptr_t i = 0; i < direct_parameter_count; i++) {
- ParameterInstr* param = new (zone()) ParameterInstr(i, function_entry);
+ ASSERT(FLAG_precompiled_mode || !function().is_unboxed_parameter_at(i));
+ ParameterInstr* param;
+
+ const intptr_t index = (function().IsFactory() ? (i - 1) : i);
+
+ if (index >= 0 && function().is_unboxed_integer_parameter_at(index)) {
+ constexpr intptr_t kCorrection = compiler::target::kIntSpillFactor - 1;
+ param = new (zone()) ParameterInstr(i, param_offset + kCorrection,
+ function_entry, kUnboxedInt64);
+ param_offset += compiler::target::kIntSpillFactor;
+ } else if (index >= 0 && function().is_unboxed_double_parameter_at(index)) {
+ constexpr intptr_t kCorrection = compiler::target::kDoubleSpillFactor - 1;
+ param = new (zone()) ParameterInstr(i, param_offset + kCorrection,
+ function_entry, kUnboxedDouble);
+ param_offset += compiler::target::kDoubleSpillFactor;
+ } else {
+ ASSERT(index < 0 || !function().is_unboxed_parameter_at(index));
+ param =
+ new (zone()) ParameterInstr(i, param_offset, function_entry, kTagged);
+ param_offset++;
+ }
param->set_ssa_temp_index(alloc_ssa_temp_index());
+ if (NeedsPairLocation(param->representation())) alloc_ssa_temp_index();
AddToInitialDefinitions(function_entry, param);
(*env)[i] = param;
}
@@ -1101,7 +1190,8 @@
const intptr_t parameter_count = osr_variable_count();
ASSERT(parameter_count == env->length());
for (intptr_t i = 0; i < parameter_count; i++) {
- ParameterInstr* param = new (zone()) ParameterInstr(i, osr_entry);
+ ParameterInstr* param =
+ new (zone()) ParameterInstr(i, i, osr_entry, kTagged);
param->set_ssa_temp_index(alloc_ssa_temp_index());
AddToInitialDefinitions(osr_entry, param);
(*env)[i] = param;
@@ -1133,7 +1223,7 @@
param = new (Z) SpecialParameterInstr(SpecialParameterInstr::kStackTrace,
DeoptId::kNone, catch_entry);
} else {
- param = new (Z) ParameterInstr(i, catch_entry);
+ param = new (Z) ParameterInstr(i, i, catch_entry, kTagged);
}
param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
@@ -2582,8 +2672,8 @@
new (Z) PushArgumentsArray(zone(), arg_count);
for (intptr_t i = 0; i < arg_count; ++i) {
Value* arg = instruction->ArgumentValueAt(i);
- PushArgumentInstr* push_arg =
- new (Z) PushArgumentInstr(arg->CopyWithType(Z));
+ PushArgumentInstr* push_arg = new (Z) PushArgumentInstr(
+ arg->CopyWithType(Z), instruction->RequiredInputRepresentation(i));
arguments->Add(push_arg);
// Insert all PushArgument instructions immediately before call.
// PushArgumentInstr::EmitNativeCode may generate more efficient
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index b6ff531..03a2239 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -112,6 +112,9 @@
// the arguments descriptor.
intptr_t num_direct_parameters() const { return num_direct_parameters_; }
+ // The number of words on the stack used by the direct parameters.
+ intptr_t direct_parameters_size() const { return direct_parameters_size_; }
+
// The number of variables (or boxes) which code can load from / store to.
// The SSA renaming will insert phi's for them (and only them - i.e. there
// will be no phi insertion for [LocalVariable]s pointing to the expression
@@ -127,6 +130,19 @@
return variable_count() + graph_entry()->osr_entry()->stack_depth();
}
+ // This function returns the offset (in words) of the [index]th
+ // parameter, relative to the first parameter.
+ // If [last_slot] is true it gives the offset of the last slot of that
+ // location, otherwise it returns the first one.
+ static intptr_t ParameterOffsetAt(const Function& function,
+ intptr_t index,
+ bool last_slot = true);
+
+ static Representation ParameterRepresentationAt(const Function& function,
+ intptr_t index);
+
+ static Representation ReturnRepresentationOf(const Function& function);
+
// The number of variables (or boxes) inside the functions frame - meaning
// below the frame pointer. This does not include the expression stack.
intptr_t num_stack_locals() const {
@@ -161,6 +177,11 @@
return num_direct_parameters_ - variable->index().value();
}
+ static bool NeedsPairLocation(Representation representation) {
+ return representation == kUnboxedInt64 &&
+ compiler::target::kIntSpillFactor == 2;
+ }
+
// Flow graph orders.
const GrowableArray<BlockEntryInstr*>& preorder() const { return preorder_; }
const GrowableArray<BlockEntryInstr*>& postorder() const {
@@ -516,6 +537,7 @@
// Flow graph fields.
const ParsedFunction& parsed_function_;
intptr_t num_direct_parameters_;
+ intptr_t direct_parameters_size_;
GraphEntryInstr* graph_entry_;
GrowableArray<BlockEntryInstr*> preorder_;
GrowableArray<BlockEntryInstr*> postorder_;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 79b5fda9..a12c9a0 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -579,9 +579,11 @@
BeginCodeSourceRange();
ASSERT(pending_deoptimization_env_ == NULL);
pending_deoptimization_env_ = entry->env();
+ set_current_instruction(entry);
StatsBegin(entry);
entry->EmitNativeCode(this);
StatsEnd(entry);
+ set_current_instruction(nullptr);
pending_deoptimization_env_ = NULL;
EndCodeSourceRange(entry->token_pos());
@@ -593,7 +595,9 @@
// Compile all successors until an exit, branch, or a block entry.
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
Instruction* instr = it.Current();
+ set_current_instruction(instr);
StatsBegin(instr);
+
// Compose intervals.
code_source_map_builder_->StartInliningInterval(assembler()->CodeSize(),
instr->inlining_id());
@@ -628,6 +632,7 @@
}
#endif
StatsEnd(instr);
+ set_current_instruction(nullptr);
if (auto indirect_goto = instr->AsIndirectGoto()) {
indirect_gotos_.Add(indirect_goto);
@@ -700,11 +705,13 @@
const CombinedCodeStatistics::EntryCounter stats_tag =
CombinedCodeStatistics::SlowPathCounterFor(
slow_path->instruction()->tag());
+ set_current_instruction(slow_path->instruction());
SpecialStatsBegin(stats_tag);
BeginCodeSourceRange();
slow_path->GenerateCode(this);
EndCodeSourceRange(slow_path->instruction()->token_pos());
SpecialStatsEnd(stats_tag);
+ set_current_instruction(nullptr);
}
for (intptr_t i = 0; i < deopt_infos_.length(); i++) {
BeginCodeSourceRange();
@@ -863,14 +870,58 @@
// registers to the bitmap. This is why the second call to RecordSafepoint
// with the same instruction (and same location summary) sees a bitmap that
// is larger that StackSize(). It will never be larger than StackSize() +
- // live_registers_size.
+ // unboxed_arg_bits_count + live_registers_size.
// The first safepoint will grow the bitmap to be the size of
// spill_area_size but the second safepoint will truncate the bitmap and
- // append the live registers to it again. The bitmap produced by both calls
- // will be the same.
- ASSERT(bitmap->Length() <= (spill_area_size + saved_registers_size));
+ // append the bits for arguments and live registers to it again.
+ const intptr_t bitmap_previous_length = bitmap->Length();
bitmap->SetLength(spill_area_size);
+ intptr_t unboxed_arg_bits_count = 0;
+
+ auto instr = current_instruction();
+ const intptr_t args_count = instr->ArgumentCount();
+ bool pushed_unboxed = false;
+
+ for (intptr_t i = 0; i < args_count; i++) {
+ auto push_arg =
+ instr->ArgumentValueAt(i)->instruction()->AsPushArgument();
+ switch (push_arg->representation()) {
+ case kUnboxedInt64:
+ bitmap->SetRange(
+ bitmap->Length(),
+ bitmap->Length() + compiler::target::kIntSpillFactor - 1, false);
+ unboxed_arg_bits_count += compiler::target::kIntSpillFactor;
+ pushed_unboxed = true;
+ break;
+ case kUnboxedDouble:
+ bitmap->SetRange(
+ bitmap->Length(),
+ bitmap->Length() + compiler::target::kDoubleSpillFactor - 1,
+ false);
+ unboxed_arg_bits_count += compiler::target::kDoubleSpillFactor;
+ pushed_unboxed = true;
+ break;
+ case kTagged:
+ if (!pushed_unboxed) {
+ // GC considers everything to be tagged between prefix of stack
+ // frame (spill area size) and postfix of stack frame (e.g. slow
+ // path arguments, shared pushed registers).
+ // From the first unboxed argument on we will include bits in the
+ // postfix.
+ continue;
+ }
+ bitmap->Set(bitmap->Length(), true);
+ unboxed_arg_bits_count++;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ ASSERT(bitmap_previous_length <=
+ (spill_area_size + unboxed_arg_bits_count + saved_registers_size));
+
ASSERT(slow_path_argument_count == 0 || !using_shared_stub);
// Mark the bits in the stack map in the same order we push registers in
@@ -1389,11 +1440,15 @@
: ic_data.arguments_descriptor());
ASSERT(ArgumentsDescriptor(arguments_descriptor).TypeArgsLen() ==
args_info.type_args_len);
+ ASSERT(ArgumentsDescriptor(arguments_descriptor).Count() ==
+ args_info.count_without_type_args);
+ ASSERT(ArgumentsDescriptor(arguments_descriptor).Size() ==
+ args_info.size_without_type_args);
// Force-optimized functions lack the deopt info which allows patching of
// optimized static calls.
if (is_optimizing() && (!ForcedOptimization() || FLAG_precompiled_mode)) {
EmitOptimizedStaticCall(function, arguments_descriptor,
- args_info.count_with_type_args, deopt_id, token_pos,
+ args_info.size_with_type_args, deopt_id, token_pos,
locs, entry_kind);
} else {
ICData& call_ic_data = ICData::ZoneHandle(zone(), ic_data.raw());
@@ -1406,7 +1461,7 @@
call_ic_data = call_ic_data.Original();
}
AddCurrentDescriptor(RawPcDescriptors::kRewind, deopt_id, token_pos);
- EmitUnoptimizedStaticCall(args_info.count_with_type_args, deopt_id,
+ EmitUnoptimizedStaticCall(args_info.size_with_type_args, deopt_id,
token_pos, locs, call_ic_data, entry_kind);
}
}
@@ -2136,7 +2191,7 @@
const Function& function = *targets.TargetAt(smi_case)->target;
GenerateStaticDartCall(deopt_id, token_index, RawPcDescriptors::kOther,
locs, function, entry_kind);
- __ Drop(args_info.count_with_type_args);
+ __ Drop(args_info.size_with_type_args);
if (match_found != NULL) {
__ Jump(match_found);
}
@@ -2186,7 +2241,7 @@
const Function& function = *targets.TargetAt(i)->target;
GenerateStaticDartCall(deopt_id, token_index, RawPcDescriptors::kOther,
locs, function, entry_kind);
- __ Drop(args_info.count_with_type_args);
+ __ Drop(args_info.size_with_type_args);
if (!is_last_check || add_megamorphic_call) {
__ Jump(match_found);
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 0c2519d..fc573cc 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -973,14 +973,14 @@
void EmitOptimizedStaticCall(
const Function& function,
const Array& arguments_descriptor,
- intptr_t count_with_type_args,
+ intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
Code::EntryKind entry_kind = Code::EntryKind::kNormal);
void EmitUnoptimizedStaticCall(
- intptr_t count_with_type_args,
+ intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -1085,6 +1085,12 @@
return block_order_.length() - index - 1;
}
+ void set_current_instruction(Instruction* current_instruction) {
+ current_instruction_ = current_instruction;
+ }
+
+ Instruction* current_instruction() { return current_instruction_; }
+
void CompactBlock(BlockEntryInstr* block);
void CompactBlocks();
@@ -1208,6 +1214,9 @@
ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data_;
Array& edge_counters_array_;
+ // Instruction currently running EmitNativeCode().
+ Instruction* current_instruction_ = nullptr;
+
DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler);
};
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 4c049a6..5aad6fd 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -1071,11 +1071,11 @@
__ LoadObject(R8, parsed_function().function());
__ LoadFromOffset(kWord, R0, SP,
- (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
+ (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
__ LoadUniqueObject(R9, ic_data);
GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
entry_kind);
- __ Drop(ic_data.CountWithTypeArgs());
+ __ Drop(ic_data.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
@@ -1088,7 +1088,7 @@
entry_kind == Code::EntryKind::kUnchecked);
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
__ LoadFromOffset(kWord, R0, SP,
- (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
+ (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
__ LoadUniqueObject(R9, ic_data);
__ LoadUniqueObject(CODE_REG, stub);
const intptr_t entry_point_offset =
@@ -1098,7 +1098,7 @@
__ ldr(LR, compiler::FieldAddress(CODE_REG, entry_point_offset));
__ blx(LR);
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
- __ Drop(ic_data.CountWithTypeArgs());
+ __ Drop(ic_data.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitMegamorphicInstanceCall(
@@ -1147,7 +1147,7 @@
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
}
RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
- __ Drop(args_desc.CountWithTypeArgs());
+ __ Drop(args_desc.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
@@ -1171,7 +1171,7 @@
__ Comment("InstanceCallAOT (%s)", switchable_call_mode);
__ LoadFromOffset(
kWord, R0, SP,
- (ic_data.CountWithoutTypeArgs() - 1) * compiler::target::kWordSize);
+ (ic_data.SizeWithoutTypeArgs() - 1) * compiler::target::kWordSize);
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
// The AOT runtime will replace the slot in the object pool with the
// entrypoint address - see clustered_snapshot.cc.
@@ -1191,10 +1191,10 @@
EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther,
locs);
- __ Drop(ic_data.CountWithTypeArgs());
+ __ Drop(ic_data.SizeWithTypeArgs());
}
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t count_with_type_args,
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -1205,13 +1205,13 @@
__ LoadObject(R9, ic_data);
GenerateDartCall(deopt_id, token_pos, stub,
RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
- __ Drop(count_with_type_args);
+ __ Drop(size_with_type_args);
}
void FlowGraphCompiler::EmitOptimizedStaticCall(
const Function& function,
const Array& arguments_descriptor,
- intptr_t count_with_type_args,
+ intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -1228,7 +1228,7 @@
// we can record the outgoing edges to other code.
GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
function, entry_kind);
- __ Drop(count_with_type_args);
+ __ Drop(size_with_type_args);
}
void FlowGraphCompiler::EmitDispatchTableCall(
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 4eed614..2958722 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -1032,11 +1032,11 @@
// Pass the function explicitly, it is used in IC stub.
__ LoadObject(R6, parsed_function().function());
- __ LoadFromOffset(R0, SP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
+ __ LoadFromOffset(R0, SP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
__ LoadUniqueObject(R5, ic_data);
GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
entry_kind);
- __ Drop(ic_data.CountWithTypeArgs());
+ __ Drop(ic_data.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
@@ -1048,7 +1048,7 @@
ASSERT(entry_kind == Code::EntryKind::kNormal ||
entry_kind == Code::EntryKind::kUnchecked);
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
- __ LoadFromOffset(R0, SP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
+ __ LoadFromOffset(R0, SP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
compiler::ObjectPoolBuilder& op = __ object_pool_builder();
const intptr_t ic_data_index =
@@ -1065,7 +1065,7 @@
__ ldr(LR, compiler::FieldAddress(CODE_REG, entry_point_offset));
__ blr(LR);
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
- __ Drop(ic_data.CountWithTypeArgs());
+ __ Drop(ic_data.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitMegamorphicInstanceCall(
@@ -1111,7 +1111,7 @@
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
}
RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
- __ Drop(args_desc.CountWithTypeArgs());
+ __ Drop(args_desc.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
@@ -1133,7 +1133,7 @@
compiler::ObjectPoolBuilder& op = __ object_pool_builder();
__ Comment("InstanceCallAOT (%s)", switchable_call_mode);
- __ LoadFromOffset(R0, SP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
+ __ LoadFromOffset(R0, SP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize);
const intptr_t data_index =
op.AddObject(data, ObjectPool::Patchability::kPatchable);
@@ -1161,10 +1161,10 @@
EmitCallsiteMetadata(token_pos, DeoptId::kNone, RawPcDescriptors::kOther,
locs);
- __ Drop(ic_data.CountWithTypeArgs());
+ __ Drop(ic_data.SizeWithTypeArgs());
}
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t count_with_type_args,
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -1175,13 +1175,13 @@
__ LoadObject(R5, ic_data);
GenerateDartCall(deopt_id, token_pos, stub,
RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
- __ Drop(count_with_type_args);
+ __ Drop(size_with_type_args);
}
void FlowGraphCompiler::EmitOptimizedStaticCall(
const Function& function,
const Array& arguments_descriptor,
- intptr_t count_with_type_args,
+ intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -1198,7 +1198,7 @@
// we can record the outgoing edges to other code.
GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
function, entry_kind);
- __ Drop(count_with_type_args);
+ __ Drop(size_with_type_args);
}
void FlowGraphCompiler::EmitDispatchTableCall(
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 19d13b9..673e253 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -886,7 +886,7 @@
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
}
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t count_with_type_args,
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -897,7 +897,7 @@
__ LoadObject(ECX, ic_data);
GenerateDartCall(deopt_id, token_pos, stub,
RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
- __ Drop(count_with_type_args);
+ __ Drop(size_with_type_args);
}
void FlowGraphCompiler::EmitEdgeCounter(intptr_t edge_id) {
@@ -929,11 +929,11 @@
__ LoadObject(EAX, parsed_function().function());
// Load receiver into EBX.
__ movl(EBX, compiler::Address(
- ESP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize));
+ ESP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
__ LoadObject(ECX, ic_data);
GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
entry_kind);
- __ Drop(ic_data.CountWithTypeArgs());
+ __ Drop(ic_data.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
@@ -947,7 +947,7 @@
ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
// Load receiver into EBX.
__ movl(EBX, compiler::Address(
- ESP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize));
+ ESP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
__ LoadObject(ECX, ic_data, true);
__ LoadObject(CODE_REG, stub, true);
const intptr_t entry_point_offset =
@@ -956,7 +956,7 @@
: Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
__ call(compiler::FieldAddress(CODE_REG, entry_point_offset));
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
- __ Drop(ic_data.CountWithTypeArgs());
+ __ Drop(ic_data.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitMegamorphicInstanceCall(
@@ -993,7 +993,7 @@
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
}
RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
- __ Drop(args_desc.CountWithTypeArgs());
+ __ Drop(args_desc.SizeWithTypeArgs());
}
void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
@@ -1009,7 +1009,7 @@
void FlowGraphCompiler::EmitOptimizedStaticCall(
const Function& function,
const Array& arguments_descriptor,
- intptr_t count_with_type_args,
+ intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -1023,7 +1023,7 @@
// we can record the outgoing edges to other code.
GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
function, entry_kind);
- __ Drop(count_with_type_args);
+ __ Drop(size_with_type_args);
}
void FlowGraphCompiler::EmitDispatchTableCall(
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index ff151c8..1a6d288 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -1013,7 +1013,7 @@
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
}
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t count_with_type_args,
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -1024,7 +1024,7 @@
__ LoadObject(RBX, ic_data);
GenerateDartCall(deopt_id, token_pos, stub,
RawPcDescriptors::kUnoptStaticCall, locs, entry_kind);
- __ Drop(count_with_type_args, RCX);
+ __ Drop(size_with_type_args, RCX);
}
void FlowGraphCompiler::EmitEdgeCounter(intptr_t edge_id) {
@@ -1057,11 +1057,11 @@
__ LoadObject(RDI, parsed_function().function());
// Load receiver into RDX.
__ movq(RDX, compiler::Address(
- RSP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize));
+ RSP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
__ LoadUniqueObject(RBX, ic_data);
GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
entry_kind);
- __ Drop(ic_data.CountWithTypeArgs(), RCX);
+ __ Drop(ic_data.SizeWithTypeArgs(), RCX);
}
void FlowGraphCompiler::EmitInstanceCallJIT(const Code& stub,
@@ -1075,7 +1075,7 @@
ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
// Load receiver into RDX.
__ movq(RDX, compiler::Address(
- RSP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize));
+ RSP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
__ LoadUniqueObject(RBX, ic_data);
__ LoadUniqueObject(CODE_REG, stub);
const intptr_t entry_point_offset =
@@ -1084,7 +1084,7 @@
: Code::entry_point_offset(Code::EntryKind::kMonomorphicUnchecked);
__ call(compiler::FieldAddress(CODE_REG, entry_point_offset));
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kIcCall, locs);
- __ Drop(ic_data.CountWithTypeArgs(), RCX);
+ __ Drop(ic_data.SizeWithTypeArgs(), RCX);
}
void FlowGraphCompiler::EmitMegamorphicInstanceCall(
@@ -1127,7 +1127,7 @@
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
}
RecordCatchEntryMoves(pending_deoptimization_env_, try_index);
- __ Drop(args_desc.CountWithTypeArgs(), RCX);
+ __ Drop(args_desc.SizeWithTypeArgs(), RCX);
}
void FlowGraphCompiler::EmitInstanceCallAOT(const ICData& ic_data,
@@ -1150,7 +1150,7 @@
__ Comment("InstanceCallAOT (%s)", switchable_call_mode);
__ movq(RDX, compiler::Address(
- RSP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize));
+ RSP, (ic_data.SizeWithoutTypeArgs() - 1) * kWordSize));
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
// The AOT runtime will replace the slot in the object pool with the
// entrypoint address - see clustered_snapshot.cc.
@@ -1167,13 +1167,13 @@
__ call(RCX);
EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
- __ Drop(ic_data.CountWithTypeArgs(), RCX);
+ __ Drop(ic_data.SizeWithTypeArgs(), RCX);
}
void FlowGraphCompiler::EmitOptimizedStaticCall(
const Function& function,
const Array& arguments_descriptor,
- intptr_t count_with_type_args,
+ intptr_t size_with_type_args,
intptr_t deopt_id,
TokenPosition token_pos,
LocationSummary* locs,
@@ -1190,7 +1190,7 @@
// we can record the outgoing edges to other code.
GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
function, entry_kind);
- __ Drop(count_with_type_args, RCX);
+ __ Drop(size_with_type_args, RCX);
}
void FlowGraphCompiler::EmitDispatchTableCall(
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index b64697b..bf06f01 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -2605,8 +2605,8 @@
case Slot::Kind::kArgumentsDescriptor_type_args_len:
case Slot::Kind::kArgumentsDescriptor_positional_count:
case Slot::Kind::kArgumentsDescriptor_count:
+ case Slot::Kind::kArgumentsDescriptor_size:
case Slot::Kind::kTypeArguments:
- case Slot::Kind::kTypedDataBase_data_field:
case Slot::Kind::kTypedDataView_offset_in_bytes:
case Slot::Kind::kTypedDataView_data:
case Slot::Kind::kGrowableObjectArray_data:
@@ -2619,7 +2619,7 @@
case Slot::Kind::kClosure_hash:
case Slot::Kind::kCapturedVariable:
case Slot::Kind::kDartField:
- case Slot::Kind::kPointer_c_memory_address:
+ case Slot::Kind::kPointerBase_data_field:
case Slot::Kind::kType_arguments:
case Slot::Kind::kTypeArgumentsIndex:
return false;
@@ -3024,6 +3024,9 @@
// Find a more precise box instruction.
if (auto conv = value()->definition()->AsIntConverter()) {
Definition* replacement;
+ if (conv->from() == kUntagged) {
+ return this;
+ }
switch (conv->from()) {
case kUnboxedInt32:
replacement = new BoxInt32Instr(conv->value()->CopyWithType());
@@ -3169,6 +3172,14 @@
return this;
}
+#if defined(TARGET_ARCH_IS_32_BIT)
+ // Do not erase extending conversions from 32-bit untagged to 64-bit values
+ // because untagged does not specify whether it is signed or not.
+ if ((box_defn->from() == kUntagged) && to() == kUnboxedInt64) {
+ return this;
+ }
+#endif
+
if (box_defn->from() == to()) {
return box_defn->value()->definition();
}
@@ -4257,7 +4268,7 @@
LocationSummary* InstanceCallInstr::MakeLocationSummary(Zone* zone,
bool optimizing) const {
- return MakeCallSummary(zone);
+ return MakeCallSummary(zone, this);
}
static RawCode* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) {
@@ -4276,6 +4287,45 @@
}
}
+bool InstanceCallBaseInstr::HasNonSmiAssignableInterface(Zone* zone) const {
+ if (!interface_target().IsNull()) {
+ const AbstractType& target_type = AbstractType::Handle(
+ zone, Class::Handle(zone, interface_target().Owner()).RareType());
+ if (!CompileType::Smi().IsAssignableTo(target_type)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+Representation InstanceCallBaseInstr::RequiredInputRepresentation(
+ intptr_t idx) const {
+ // The first input is the array of types
+ // for generic functions
+ if (type_args_len() > 0) {
+ if (idx == 0) {
+ return kTagged;
+ }
+ idx--;
+ }
+ return FlowGraph::ParameterRepresentationAt(interface_target(), idx);
+}
+
+intptr_t InstanceCallBaseInstr::ArgumentsSize() const {
+ if (interface_target().IsNull()) {
+ return ArgumentCountWithoutTypeArgs() + ((type_args_len() > 0) ? 1 : 0);
+ }
+
+ return FlowGraph::ParameterOffsetAt(interface_target(),
+ ArgumentCountWithoutTypeArgs(),
+ /*last_slot=*/false) +
+ ((type_args_len() > 0) ? 1 : 0);
+}
+
+Representation InstanceCallBaseInstr::representation() const {
+ return FlowGraph::ReturnRepresentationOf(interface_target());
+}
+
void InstanceCallBaseInstr::UpdateReceiverSminess(Zone* zone) {
if (FLAG_precompiled_mode && !receiver_is_not_smi()) {
if (Receiver()->Type()->IsNotSmi()) {
@@ -4283,12 +4333,8 @@
return;
}
- if (!interface_target().IsNull()) {
- const AbstractType& target_type = AbstractType::Handle(
- zone, Class::Handle(zone, interface_target().Owner()).RareType());
- if (!CompileType::Smi().IsAssignableTo(target_type)) {
- set_receiver_is_not_smi(true);
- }
+ if (HasNonSmiAssignableInterface(zone)) {
+ set_receiver_is_not_smi(true);
}
}
}
@@ -4392,6 +4438,38 @@
return *binary_;
}
+Representation DispatchTableCallInstr::RequiredInputRepresentation(
+ intptr_t idx) const {
+ if (idx == (InputCount() - 1)) {
+ return kUntagged;
+ }
+
+ // The first input is the array of types
+ // for generic functions
+ if (type_args_len() > 0) {
+ if (idx == 0) {
+ return kTagged;
+ }
+ idx--;
+ }
+ return FlowGraph::ParameterRepresentationAt(interface_target(), idx);
+}
+
+intptr_t DispatchTableCallInstr::ArgumentsSize() const {
+ if (interface_target().IsNull()) {
+ return ArgumentCountWithoutTypeArgs() + ((type_args_len() > 0) ? 1 : 0);
+ }
+
+ return FlowGraph::ParameterOffsetAt(interface_target(),
+ ArgumentCountWithoutTypeArgs(),
+ /*last_slot=*/false) +
+ ((type_args_len() > 0) ? 1 : 0);
+}
+
+Representation DispatchTableCallInstr::representation() const {
+ return FlowGraph::ReturnRepresentationOf(interface_target());
+}
+
DispatchTableCallInstr* DispatchTableCallInstr::FromCall(
Zone* zone,
const InstanceCallBaseInstr* call,
@@ -4414,7 +4492,8 @@
void DispatchTableCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Array& arguments_descriptor = Array::ZoneHandle();
if (selector()->requires_args_descriptor) {
- ArgumentsInfo args_info(type_args_len(), ArgumentCount(), argument_names());
+ ArgumentsInfo args_info(type_args_len(), ArgumentCount(), ArgumentsSize(),
+ argument_names());
arguments_descriptor = args_info.ToArgumentsDescriptor();
}
const Register cid_reg = locs()->in(0).reg();
@@ -4430,11 +4509,35 @@
compiler->AddNullCheck(token_pos(), function_name);
}
}
- __ Drop(ArgumentCount());
+ __ Drop(ArgumentsSize());
compiler->AddDispatchTableCallTarget(selector());
}
+Representation StaticCallInstr::RequiredInputRepresentation(
+ intptr_t idx) const {
+ // The first input is the array of types
+ // for generic functions
+ if (type_args_len() > 0 || function().IsFactory()) {
+ if (idx == 0) {
+ return kTagged;
+ }
+ idx--;
+ }
+ return FlowGraph::ParameterRepresentationAt(function(), idx);
+}
+
+intptr_t StaticCallInstr::ArgumentsSize() const {
+ return FlowGraph::ParameterOffsetAt(function(),
+ ArgumentCountWithoutTypeArgs(),
+ /*last_slot=*/false) +
+ ((type_args_len() > 0) ? 1 : 0);
+}
+
+Representation StaticCallInstr::representation() const {
+ return FlowGraph::ReturnRepresentationOf(function());
+}
+
const CallTargets& StaticCallInstr::Targets() {
if (targets_ == nullptr) {
Zone* zone = Thread::Current()->zone();
@@ -4516,11 +4619,12 @@
LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
Zone* zone,
bool optimizing) const {
- return MakeCallSummary(zone);
+ return MakeCallSummary(zone, this);
}
void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- ArgumentsInfo args_info(type_args_len(), ArgumentCount(), argument_names());
+ ArgumentsInfo args_info(type_args_len(), ArgumentCount(), ArgumentsSize(),
+ argument_names());
UpdateReceiverSminess(compiler->zone());
compiler->EmitPolymorphicInstanceCall(
this, targets(), args_info, deopt_id(), token_pos(), locs(), complete(),
@@ -4656,7 +4760,7 @@
LocationSummary* StaticCallInstr::MakeLocationSummary(Zone* zone,
bool optimizing) const {
- return MakeCallSummary(zone);
+ return MakeCallSummary(zone, this);
}
void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -4674,8 +4778,8 @@
} else {
call_ic_data = &ICData::ZoneHandle(ic_data()->raw());
}
-
- ArgumentsInfo args_info(type_args_len(), ArgumentCount(), argument_names());
+ ArgumentsInfo args_info(type_args_len(), ArgumentCount(), ArgumentsSize(),
+ argument_names());
compiler->GenerateStaticCall(deopt_id(), token_pos(), function(), args_info,
locs(), *call_ic_data, rebind_rule_,
entry_kind());
@@ -5251,6 +5355,7 @@
LoadIndexedInstr::LoadIndexedInstr(Value* array,
Value* index,
+ bool index_unboxed,
intptr_t index_scale,
intptr_t class_id,
AlignmentType alignment,
@@ -5258,6 +5363,7 @@
TokenPosition token_pos,
CompileType* result_type)
: TemplateDefinition(deopt_id),
+ index_unboxed_(index_unboxed),
index_scale_(index_scale),
class_id_(class_id),
alignment_(StrengthenAlignment(class_id, alignment)),
@@ -5271,6 +5377,7 @@
Value* index,
Value* value,
StoreBarrierType emit_store_barrier,
+ bool index_unboxed,
intptr_t index_scale,
intptr_t class_id,
AlignmentType alignment,
@@ -5279,6 +5386,7 @@
SpeculativeMode speculative_mode)
: TemplateInstruction(deopt_id),
emit_store_barrier_(emit_store_barrier),
+ index_unboxed_(index_unboxed),
index_scale_(index_scale),
class_id_(class_id),
alignment_(StrengthenAlignment(class_id, alignment)),
@@ -5400,7 +5508,7 @@
LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone,
bool optimizing) const {
- return MakeCallSummary(zone);
+ return MakeCallSummary(zone, this);
}
void NativeCallInstr::SetupNative() {
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 6477f496..80c224c 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -61,7 +61,7 @@
namespace compiler {
class BlockBuilder;
struct TableSelector;
-}
+} // namespace compiler
class Value : public ZoneAllocated {
public:
@@ -239,9 +239,7 @@
thread->set_hierarchy_info(this);
}
- ~HierarchyInfo() {
- thread()->set_hierarchy_info(NULL);
- }
+ ~HierarchyInfo() { thread()->set_hierarchy_info(NULL); }
const CidRangeVector& SubtypeRangesForClass(const Class& klass,
bool include_abstract,
@@ -951,7 +949,11 @@
locs_ = MakeLocationSummary(zone, optimizing);
}
- static LocationSummary* MakeCallSummary(Zone* zone);
+ // Makes a new call location summary (or uses `locs`) and initializes the
+ // output register constraints depending on the representation of [instr].
+ static LocationSummary* MakeCallSummary(Zone* zone,
+ const Instruction* instr,
+ LocationSummary* locs = nullptr);
virtual void EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
@@ -2434,13 +2436,20 @@
class ParameterInstr : public Definition {
public:
ParameterInstr(intptr_t index,
+ intptr_t param_offset,
BlockEntryInstr* block,
+ Representation representation,
Register base_reg = FPREG)
- : index_(index), base_reg_(base_reg), block_(block) {}
+ : index_(index),
+ param_offset_(param_offset),
+ base_reg_(base_reg),
+ representation_(representation),
+ block_(block) {}
DECLARE_INSTRUCTION(Parameter)
intptr_t index() const { return index_; }
+ intptr_t param_offset() const { return param_offset_; }
Register base_reg() const { return base_reg_; }
// Get the block entry for that instruction.
@@ -2453,6 +2462,13 @@
return NULL;
}
+ virtual Representation representation() const { return representation_; }
+
+ virtual Representation RequiredInputRepresentation(intptr_t index) const {
+ ASSERT(index == 0);
+ return representation();
+ }
+
virtual bool ComputeCanDeoptimize() const { return false; }
virtual bool HasUnknownSideEffects() const { return false; }
@@ -2473,7 +2489,14 @@
virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
const intptr_t index_;
+
+ // The offset (in words) of the last slot of the parameter, relative
+ // to the first parameter.
+ // It is used in the FlowGraphAllocator when it sets the assigned location
+ // and spill slot for the parameter definition.
+ const intptr_t param_offset_;
const Register base_reg_;
+ const Representation representation_;
BlockEntryInstr* block_;
DISALLOW_COPY_AND_ASSIGN(ParameterInstr);
@@ -2577,7 +2600,7 @@
DISALLOW_COPY_AND_ASSIGN(StoreIndexedUnsafeInstr);
};
-// Loads a tagged pointer from slot accessable from a fixed register. It has
+// Loads a value from slot accessable from a fixed register. It has
// the form:
//
// base_reg[index + #constant]
@@ -2613,6 +2636,8 @@
return other->AsLoadIndexedUnsafe()->offset() == offset();
}
+ virtual Representation representation() const { return representation_; }
+
Value* index() const { return InputAt(0); }
Register base_reg() const { return FPREG; }
intptr_t offset() const { return offset_; }
@@ -2679,7 +2704,10 @@
class PushArgumentInstr : public TemplateDefinition<1, NoThrow> {
public:
- explicit PushArgumentInstr(Value* value) { SetInputAt(0, value); }
+ explicit PushArgumentInstr(Value* value, Representation representation)
+ : representation_(representation) {
+ SetInputAt(0, value);
+ }
DECLARE_INSTRUCTION(PushArgument)
@@ -2695,9 +2723,18 @@
return TokenPosition::kPushArgument;
}
+ virtual Representation representation() const { return representation_; }
+
+ virtual Representation RequiredInputRepresentation(intptr_t index) const {
+ ASSERT(index == 0);
+ return representation();
+ }
+
PRINT_OPERANDS_TO_SUPPORT
private:
+ const Representation representation_;
+
DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr);
};
@@ -2718,10 +2755,12 @@
ReturnInstr(TokenPosition token_pos,
Value* value,
intptr_t deopt_id,
- intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex)
+ intptr_t yield_index = RawPcDescriptors::kInvalidYieldIndex,
+ Representation representation = kTagged)
: TemplateInstruction(deopt_id),
token_pos_(token_pos),
- yield_index_(yield_index) {
+ yield_index_(yield_index),
+ representation_(representation) {
SetInputAt(0, value);
}
@@ -2747,11 +2786,26 @@
yield_index() == other_return->yield_index();
}
+ virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
+ ASSERT(index == 0);
+ return kNotSpeculative;
+ }
+
+ virtual intptr_t DeoptimizationTarget() const { return DeoptId::kNone; }
+
+ virtual Representation representation() const { return representation_; }
+
+ virtual Representation RequiredInputRepresentation(intptr_t index) const {
+ ASSERT(index == 0);
+ return representation_;
+ }
+
PRINT_OPERANDS_TO_SUPPORT
private:
const TokenPosition token_pos_;
const intptr_t yield_index_;
+ const Representation representation_;
DISALLOW_COPY_AND_ASSIGN(ReturnInstr);
};
@@ -3552,21 +3606,27 @@
struct ArgumentsInfo {
ArgumentsInfo(intptr_t type_args_len,
intptr_t count_with_type_args,
+ intptr_t size_with_type_args,
const Array& argument_names)
: type_args_len(type_args_len),
count_with_type_args(count_with_type_args),
+ size_with_type_args(size_with_type_args),
count_without_type_args(count_with_type_args -
(type_args_len > 0 ? 1 : 0)),
+ size_without_type_args(size_with_type_args -
+ (type_args_len > 0 ? 1 : 0)),
argument_names(argument_names) {}
RawArray* ToArgumentsDescriptor() const {
return ArgumentsDescriptor::New(type_args_len, count_without_type_args,
- argument_names);
+ size_without_type_args, argument_names);
}
const intptr_t type_args_len;
const intptr_t count_with_type_args;
+ const intptr_t size_with_type_args;
const intptr_t count_without_type_args;
+ const intptr_t size_without_type_args;
const Array& argument_names;
};
@@ -3610,12 +3670,17 @@
intptr_t ArgumentCountWithoutTypeArgs() const {
return ArgumentCount() - FirstArgIndex();
}
+ intptr_t ArgumentsSizeWithoutTypeArgs() const {
+ return ArgumentsSize() - FirstArgIndex();
+ }
// ArgumentCount() includes the type argument vector if any.
// Caution: Must override Instruction::ArgumentCount().
- virtual intptr_t ArgumentCount() const {
+ intptr_t ArgumentCount() const {
return push_arguments_ != nullptr ? push_arguments_->length()
: inputs_->length() - kExtraInputs;
}
+ virtual intptr_t ArgumentsSize() const { return ArgumentCount(); }
+
virtual void SetPushArguments(PushArgumentsArray* push_arguments) {
ASSERT(push_arguments_ == nullptr);
push_arguments_ = push_arguments;
@@ -3643,7 +3708,8 @@
virtual TokenPosition token_pos() const { return token_pos_; }
RawArray* GetArgumentsDescriptor() const {
return ArgumentsDescriptor::New(
- type_args_len(), ArgumentCountWithoutTypeArgs(), argument_names());
+ type_args_len(), ArgumentCountWithoutTypeArgs(),
+ ArgumentsSizeWithoutTypeArgs(), argument_names());
}
ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
@@ -3790,6 +3856,27 @@
// interface target, CompileType and hints from TFA.
void UpdateReceiverSminess(Zone* zone);
+ bool HasNonSmiAssignableInterface(Zone* zone) const;
+
+ virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
+ if (type_args_len() > 0) {
+ if (idx == 0) {
+ return kGuardInputs;
+ }
+ idx--;
+ }
+ return interface_target_.is_unboxed_parameter_at(idx) ? kNotSpeculative
+ : kGuardInputs;
+ }
+
+ virtual intptr_t ArgumentsSize() const;
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const;
+
+ virtual intptr_t DeoptimizationTarget() const { return DeoptId::kNone; }
+
+ virtual Representation representation() const;
+
protected:
friend class CallSpecializer;
void set_ic_data(ICData* value) { ic_data_ = value; }
@@ -4021,10 +4108,6 @@
Value* class_id() const { return InputAt(InputCount() - 1); }
- virtual Representation RequiredInputRepresentation(intptr_t idx) const {
- return (idx == (InputCount() - 1)) ? kUntagged : kTagged;
- }
-
virtual CompileType ComputeType() const;
virtual bool ComputeCanDeoptimize() const { return false; }
@@ -4037,6 +4120,23 @@
virtual bool HasUnknownSideEffects() const { return true; }
+ virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
+ if (type_args_len() > 0) {
+ if (idx == 0) {
+ return kGuardInputs;
+ }
+ idx--;
+ }
+ return interface_target_.is_unboxed_parameter_at(idx) ? kNotSpeculative
+ : kGuardInputs;
+ }
+
+ virtual intptr_t ArgumentsSize() const;
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const;
+
+ virtual Representation representation() const;
+
PRINT_OPERANDS_TO_SUPPORT
private:
@@ -4469,6 +4569,25 @@
bool IsRecognizedFactory() const { return is_known_list_constructor(); }
+ virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const {
+ if (type_args_len() > 0 || function().IsFactory()) {
+ if (idx == 0) {
+ return kGuardInputs;
+ }
+ idx--;
+ }
+ return function_.is_unboxed_parameter_at(idx) ? kNotSpeculative
+ : kGuardInputs;
+ }
+
+ virtual intptr_t ArgumentsSize() const;
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const;
+
+ virtual intptr_t DeoptimizationTarget() const { return DeoptId::kNone; }
+
+ virtual Representation representation() const;
+
virtual AliasIdentity Identity() const { return identity_; }
virtual void SetIdentity(AliasIdentity identity) { identity_ = identity; }
@@ -5121,6 +5240,7 @@
public:
LoadIndexedInstr(Value* array,
Value* index,
+ bool index_unboxed,
intptr_t index_scale,
intptr_t class_id,
AlignmentType alignment,
@@ -5137,7 +5257,16 @@
ASSERT(idx == 0 || idx == 1);
// The array may be tagged or untagged (for external arrays).
if (idx == 0) return kNoRepresentation;
- return kTagged;
+
+ if (index_unboxed_) {
+#if defined(TARGET_ARCH_IS_64_BIT)
+ return kUnboxedInt64;
+#else
+ return kUnboxedUint32;
+#endif
+ } else {
+ return kTagged; // Index is a smi.
+ }
}
bool IsExternal() const {
@@ -5162,6 +5291,7 @@
ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
private:
+ const bool index_unboxed_;
const intptr_t index_scale_;
const intptr_t class_id_;
const AlignmentType alignment_;
@@ -5326,6 +5456,7 @@
Value* index,
Value* value,
StoreBarrierType emit_store_barrier,
+ bool index_unboxed,
intptr_t index_scale,
intptr_t class_id,
AlignmentType alignment,
@@ -5386,6 +5517,7 @@
}
const StoreBarrierType emit_store_barrier_;
+ const bool index_unboxed_;
const intptr_t index_scale_;
const intptr_t class_id_;
const AlignmentType alignment_;
@@ -6263,6 +6395,10 @@
virtual TokenPosition token_pos() const { return TokenPosition::kBox; }
+ virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
+ return kNotSpeculative;
+ }
+
protected:
BoxInstr(Representation from_representation, Value* value)
: from_representation_(from_representation) {
@@ -6288,10 +6424,6 @@
virtual void InferRange(RangeAnalysis* analysis, Range* range);
- virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
- return kNotSpeculative;
- }
-
virtual CompileType ComputeType() const;
virtual bool RecomputeType();
@@ -6951,6 +7083,10 @@
TemplateDartCall<0>* call)
: TemplateDefinition(call->deopt_id()), call_(call), op_kind_(op_kind) {
ASSERT(call->type_args_len() == 0);
+ ASSERT(!call->IsInstanceCallBase() ||
+ !call->AsInstanceCallBase()->HasNonSmiAssignableInterface(
+ Thread::Current()->zone()));
+
SetInputAt(0, left);
SetInputAt(1, right);
}
@@ -6990,6 +7126,10 @@
call_(call),
is_negated_(false) {
ASSERT(call->type_args_len() == 0);
+ ASSERT(!call->IsInstanceCallBase() ||
+ !call->AsInstanceCallBase()->HasNonSmiAssignableInterface(
+ Thread::Current()->zone()));
+
SetInputAt(0, left);
SetInputAt(1, right);
}
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index b3aafaa..e47f315 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -32,21 +32,102 @@
namespace dart {
// Generic summary for call instructions that have all arguments pushed
-// on the stack and return the result in a fixed register R0.
-LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
+// on the stack and return the result in a fixed location depending on
+// the return value (R0, Location::Pair(R0, R1) or Q0).
+LocationSummary* Instruction::MakeCallSummary(Zone* zone,
+ const Instruction* instr,
+ LocationSummary* locs) {
+ ASSERT(locs == nullptr || locs->always_calls());
LocationSummary* result =
- new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
- result->set_out(0, Location::RegisterLocation(R0));
+ ((locs == nullptr)
+ ? (new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall))
+ : locs);
+ const auto representation = instr->representation();
+ switch (representation) {
+ case kTagged:
+ result->set_out(
+ 0, Location::RegisterLocation(CallingConventions::kReturnReg));
+ break;
+ case kUnboxedInt64:
+ result->set_out(
+ 0, Location::Pair(
+ Location::RegisterLocation(CallingConventions::kReturnReg),
+ Location::RegisterLocation(
+ CallingConventions::kSecondReturnReg)));
+ break;
+ case kUnboxedDouble:
+ result->set_out(
+ 0, Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
return result;
}
-DEFINE_BACKEND(LoadIndexedUnsafe, (Register out, Register index)) {
- ASSERT(instr->RequiredInputRepresentation(0) == kTagged); // It is a Smi.
- __ add(out, instr->base_reg(), compiler::Operand(index, LSL, 1));
- __ ldr(out, compiler::Address(out, instr->offset()));
+LocationSummary* LoadIndexedUnsafeInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ const intptr_t kNumInputs = 1;
+ const intptr_t kNumTemps = ((representation() == kUnboxedDouble) ? 1 : 0);
+ LocationSummary* locs = new (zone)
+ LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ locs->set_in(0, Location::RequiresRegister());
+ switch (representation()) {
+ case kTagged:
+ locs->set_out(0, Location::RequiresRegister());
+ break;
+ case kUnboxedInt64:
+ locs->set_out(0, Location::Pair(Location::RequiresRegister(),
+ Location::RequiresRegister()));
+ break;
+ case kUnboxedDouble:
+ locs->set_temp(0, Location::RequiresRegister());
+ locs->set_out(0, Location::RequiresFpuRegister());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return locs;
+}
+
+void LoadIndexedUnsafeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(RequiredInputRepresentation(0) == kTagged); // It is a Smi.
ASSERT(kSmiTag == 0);
ASSERT(kSmiTagSize == 1);
+
+ const Register index = locs()->in(0).reg();
+
+ switch (representation()) {
+ case kTagged: {
+ const auto out = locs()->out(0).reg();
+ __ add(out, base_reg(), compiler::Operand(index, LSL, 1));
+ __ ldr(out, compiler::Address(out, offset()));
+ break;
+ }
+ case kUnboxedInt64: {
+ const auto out_lo = locs()->out(0).AsPairLocation()->At(0).reg();
+ const auto out_hi = locs()->out(0).AsPairLocation()->At(1).reg();
+
+ __ add(out_hi, base_reg(), compiler::Operand(index, LSL, 1));
+ __ ldr(out_lo, compiler::Address(out_hi, offset()));
+ __ ldr(out_hi,
+ compiler::Address(out_hi, offset() + compiler::target::kWordSize));
+ break;
+ }
+ case kUnboxedDouble: {
+ const auto tmp = locs()->temp(0).reg();
+ const auto out = EvenDRegisterOf(locs()->out(0).fpu_reg());
+ __ add(tmp, base_reg(), compiler::Operand(index, LSL, 1));
+ __ LoadDFromOffset(out, tmp, offset());
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
}
DEFINE_BACKEND(StoreIndexedUnsafe,
@@ -82,7 +163,14 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, LocationAnyOrConstant(value()));
+ if (representation() == kUnboxedDouble) {
+ locs->set_in(0, Location::RequiresFpuRegister());
+ } else if (representation() == kUnboxedInt64) {
+ locs->set_in(0, Location::Pair(Location::RequiresRegister(),
+ Location::RequiresRegister()));
+ } else {
+ locs->set_in(0, LocationAnyOrConstant(value()));
+ }
return locs;
}
@@ -137,15 +225,24 @@
ASSERT(instr != nullptr);
if (ParallelMoveInstr* parallel_move = instr->AsParallelMove()) {
for (intptr_t i = 0, n = parallel_move->NumMoves(); i < n; ++i) {
- if (parallel_move->MoveOperandsAt(i)->src().IsRegister()) {
- busy |= (1 << parallel_move->MoveOperandsAt(i)->src().reg());
+ const auto src_loc = parallel_move->MoveOperandsAt(i)->src();
+ if (src_loc.IsRegister()) {
+ busy |= (1 << src_loc.reg());
+ } else if (src_loc.IsPairLocation()) {
+ busy |= (1 << src_loc.AsPairLocation()->At(0).reg());
+ busy |= (1 << src_loc.AsPairLocation()->At(1).reg());
}
}
} else {
ASSERT(instr->IsPushArgument() || (instr->ArgumentCount() > 0));
for (intptr_t i = 0, n = instr->locs()->input_count(); i < n; ++i) {
- if (instr->locs()->in(i).IsRegister()) {
- busy |= (1 << instr->locs()->in(i).reg());
+ const auto in_loc = instr->locs()->in(i);
+ if (in_loc.IsRegister()) {
+ busy |= (1 << in_loc.reg());
+ } else if (in_loc.IsPairLocation()) {
+ const auto pair_location = in_loc.AsPairLocation();
+ busy |= (1 << pair_location->At(0).reg());
+ busy |= (1 << pair_location->At(1).reg());
}
}
if (instr->ArgumentCount() > 0) {
@@ -199,6 +296,12 @@
const Location value = push_arg->locs()->in(0);
if (value.IsRegister()) {
pusher.PushRegister(compiler, value.reg());
+ } else if (value.IsPairLocation()) {
+ pusher.PushRegister(compiler, value.AsPairLocation()->At(1).reg());
+ pusher.PushRegister(compiler, value.AsPairLocation()->At(0).reg());
+ } else if (value.IsFpuRegister()) {
+ pusher.Flush(compiler);
+ __ vstmd(DB_W, SP, EvenDRegisterOf(value.fpu_reg()), 1);
} else {
const Register reg = pusher.FindFreeRegister(compiler, push_arg);
ASSERT(reg != kNoRegister);
@@ -221,7 +324,26 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterLocation(R0));
+ switch (representation()) {
+ case kTagged:
+ locs->set_in(0,
+ Location::RegisterLocation(CallingConventions::kReturnReg));
+ break;
+ case kUnboxedInt64:
+ locs->set_in(
+ 0, Location::Pair(
+ Location::RegisterLocation(CallingConventions::kReturnReg),
+ Location::RegisterLocation(
+ CallingConventions::kSecondReturnReg)));
+ break;
+ case kUnboxedDouble:
+ locs->set_in(
+ 0, Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
return locs;
}
@@ -229,8 +351,19 @@
// The entry needs to be patchable, no inlined objects are allowed in the area
// that will be overwritten by the patch instructions: a branch macro sequence.
void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- const Register result = locs()->in(0).reg();
- ASSERT(result == R0);
+ if (locs()->in(0).IsRegister()) {
+ const Register result = locs()->in(0).reg();
+ ASSERT(result == CallingConventions::kReturnReg);
+ } else if (locs()->in(0).IsPairLocation()) {
+ const Register result_lo = locs()->in(0).AsPairLocation()->At(0).reg();
+ const Register result_hi = locs()->in(0).AsPairLocation()->At(1).reg();
+ ASSERT(result_lo == CallingConventions::kReturnReg);
+ ASSERT(result_hi == CallingConventions::kSecondReturnReg);
+ } else {
+ ASSERT(locs()->in(0).IsFpuRegister());
+ const FpuRegister result = locs()->in(0).fpu_reg();
+ ASSERT(result == CallingConventions::kReturnFpuReg);
+ }
if (compiler->intrinsic_mode()) {
// Intrinsics don't have a frame.
@@ -368,8 +501,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
summary->set_in(0, Location::RegisterLocation(R0)); // ClassId
- summary->set_out(0, Location::RegisterLocation(R0));
- return summary;
+ return MakeCallSummary(zone, this, summary);
}
LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
@@ -379,8 +511,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
summary->set_in(0, Location::RegisterLocation(R0)); // Function.
- summary->set_out(0, Location::RegisterLocation(R0));
- return summary;
+ return MakeCallSummary(zone, this, summary);
}
void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -1464,8 +1595,10 @@
__ Push(array);
const int kTypeArgsLen = 0;
const int kNumberOfArguments = 1;
+ constexpr int kSizeOfArguments = 1;
const Array& kNoArgumentNames = Object::null_array();
- ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
+ ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kSizeOfArguments,
+ kNoArgumentNames);
compiler->GenerateStaticCall(deopt_id(), token_pos(), CallFunction(),
args_info, locs(), ICData::Handle(),
ICData::kStatic);
@@ -1636,23 +1769,24 @@
compiler::Address element_address(kNoRegister);
if (directly_addressable) {
- element_address = index.IsRegister()
- ? __ ElementAddressForRegIndex(
- true, // Load.
- IsExternal(), class_id(), index_scale(), array,
- index.reg())
- : __ ElementAddressForIntIndex(
- true, // Load.
- IsExternal(), class_id(), index_scale(), array,
- compiler::target::SmiValue(index.constant()),
- IP); // Temp register.
+ element_address =
+ index.IsRegister()
+ ? __ ElementAddressForRegIndex(true, // Load.
+ IsExternal(), class_id(),
+ index_scale(), index_unboxed_, array,
+ index.reg())
+ : __ ElementAddressForIntIndex(
+ true, // Load.
+ IsExternal(), class_id(), index_scale(), array,
+ compiler::target::SmiValue(index.constant()),
+ IP); // Temp register.
// Warning: element_address may use register IP as base.
} else {
if (index.IsRegister()) {
__ LoadElementAddressForRegIndex(address,
true, // Load.
IsExternal(), class_id(), index_scale(),
- array, index.reg());
+ index_unboxed_, array, index.reg());
} else {
__ LoadElementAddressForIntIndex(
address,
@@ -1803,7 +1937,14 @@
intptr_t idx) const {
// Array can be a Dart object or a pointer to external data.
if (idx == 0) return kNoRepresentation; // Flexible input representation.
- if (idx == 1) return kTagged; // Index is a smi.
+ if (idx == 1) {
+ if (index_unboxed_) {
+ // TODO(dartbug.com/39432): kUnboxedInt32 || kUnboxedUint32.
+ return kNoRepresentation;
+ } else {
+ return kTagged; // Index is a smi.
+ }
+ }
ASSERT(idx == 2);
switch (class_id_) {
case kArrayCid:
@@ -1941,7 +2082,7 @@
index.IsRegister()
? __ ElementAddressForRegIndex(false, // Store.
IsExternal(), class_id(),
- index_scale(), array,
+ index_scale(), index_unboxed_, array,
index.reg())
: __ ElementAddressForIntIndex(
false, // Store.
@@ -1952,7 +2093,7 @@
__ LoadElementAddressForRegIndex(temp,
false, // Store.
IsExternal(), class_id(), index_scale(),
- array, index.reg());
+ index_unboxed_, array, index.reg());
} else {
__ LoadElementAddressForIntIndex(
temp,
@@ -2447,7 +2588,8 @@
const Location index = locs()->in(1);
compiler::Address element_address = __ ElementAddressForRegIndex(
- true, IsExternal(), class_id(), index_scale(), str, index.reg());
+ true, IsExternal(), class_id(), index_scale(), /*index_unboxed=*/false,
+ str, index.reg());
// Warning: element_address may use register IP as base.
if (representation() == kUnboxedInt64) {
@@ -3772,8 +3914,9 @@
__ Push(locs->in(0).reg());
__ Push(locs->in(1).reg());
const auto& selector = String::Handle(instruction()->call()->Selector());
- const auto& arguments_descriptor = Array::Handle(
- ArgumentsDescriptor::New(/*type_args_len=*/0, /*num_arguments=*/2));
+ const auto& arguments_descriptor =
+ Array::Handle(ArgumentsDescriptor::NewBoxed(
+ /*type_args_len=*/0, /*num_arguments=*/2));
compiler->EmitMegamorphicInstanceCall(
selector, arguments_descriptor, instruction()->call()->deopt_id(),
instruction()->token_pos(), locs, try_index_, kNumSlowPathArgs);
@@ -3920,8 +4063,9 @@
__ Push(locs->in(0).reg());
__ Push(locs->in(1).reg());
const auto& selector = String::Handle(instruction()->call()->Selector());
- const auto& arguments_descriptor = Array::Handle(
- ArgumentsDescriptor::New(/*type_args_len=*/0, /*num_arguments=*/2));
+ const auto& arguments_descriptor =
+ Array::Handle(ArgumentsDescriptor::NewBoxed(
+ /*type_args_len=*/0, /*num_arguments=*/2));
compiler->EmitMegamorphicInstanceCall(
selector, arguments_descriptor, instruction()->call()->deopt_id(),
instruction()->token_pos(), locs, try_index_, kNumSlowPathArgs);
@@ -5901,8 +6045,10 @@
const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
const int kTypeArgsLen = 0;
const int kNumberOfArguments = 1;
+ constexpr int kSizeOfArguments = 1;
const Array& kNoArgumentNames = Object::null_array();
- ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
+ ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kSizeOfArguments,
+ kNoArgumentNames);
compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), target,
args_info, locs(), ICData::Handle(),
ICData::kStatic);
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 8cdadfc..4486d3c 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -30,21 +30,84 @@
namespace dart {
// Generic summary for call instructions that have all arguments pushed
-// on the stack and return the result in a fixed register R0.
-LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
+// on the stack and return the result in a fixed register R0 (or V0 if
+// the return type is double).
+LocationSummary* Instruction::MakeCallSummary(Zone* zone,
+ const Instruction* instr,
+ LocationSummary* locs) {
+ ASSERT(locs == nullptr || locs->always_calls());
LocationSummary* result =
- new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
- result->set_out(0, Location::RegisterLocation(R0));
+ ((locs == nullptr)
+ ? (new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall))
+ : locs);
+ const auto representation = instr->representation();
+ switch (representation) {
+ case kTagged:
+ case kUnboxedInt64:
+ result->set_out(
+ 0, Location::RegisterLocation(CallingConventions::kReturnReg));
+ break;
+ case kUnboxedDouble:
+ result->set_out(
+ 0, Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
return result;
}
-DEFINE_BACKEND(LoadIndexedUnsafe, (Register out, Register index)) {
- ASSERT(instr->RequiredInputRepresentation(0) == kTagged); // It is a Smi.
- __ add(out, instr->base_reg(), compiler::Operand(index, LSL, 2));
- __ ldr(out, compiler::Address(out, instr->offset()));
+LocationSummary* LoadIndexedUnsafeInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ const intptr_t kNumInputs = 1;
+ const intptr_t kNumTemps = ((representation() == kUnboxedDouble) ? 1 : 0);
+ LocationSummary* locs = new (zone)
+ LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ locs->set_in(0, Location::RequiresRegister());
+ switch (representation()) {
+ case kTagged:
+ case kUnboxedInt64:
+ locs->set_out(0, Location::RequiresRegister());
+ break;
+ case kUnboxedDouble:
+ locs->set_temp(0, Location::RequiresRegister());
+ locs->set_out(0, Location::RequiresFpuRegister());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return locs;
+}
+
+void LoadIndexedUnsafeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(RequiredInputRepresentation(0) == kTagged); // It is a Smi.
ASSERT(kSmiTag == 0);
ASSERT(kSmiTagSize == 1);
+
+ const Register index = locs()->in(0).reg();
+
+ switch (representation()) {
+ case kTagged:
+ case kUnboxedInt64: {
+ const auto out = locs()->out(0).reg();
+ __ add(out, base_reg(), compiler::Operand(index, LSL, 2));
+ __ ldr(out, compiler::Address(out, offset()));
+ break;
+ }
+ case kUnboxedDouble: {
+ const auto tmp = locs()->temp(0).reg();
+ const auto out = locs()->out(0).fpu_reg();
+ __ add(tmp, base_reg(), compiler::Operand(index, LSL, 2));
+ __ LoadDFromOffset(out, tmp, offset());
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
}
DEFINE_BACKEND(StoreIndexedUnsafe,
@@ -80,7 +143,13 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, LocationAnyOrConstant(value()));
+ if (representation() == kUnboxedDouble) {
+ locs->set_in(0, Location::RequiresFpuRegister());
+ } else if (representation() == kUnboxedInt64) {
+ locs->set_in(0, Location::RequiresRegister());
+ } else {
+ locs->set_in(0, LocationAnyOrConstant(value()));
+ }
return locs;
}
@@ -145,6 +214,10 @@
reg = pusher.GetFreeTempRegister();
__ LoadObject(reg, value.constant());
}
+ } else if (value.IsFpuRegister()) {
+ pusher.Flush(compiler);
+ __ PushDouble(value.fpu_reg());
+ continue;
} else {
ASSERT(value.IsStackSlot());
const intptr_t value_offset = value.ToStackSlotOffset();
@@ -162,7 +235,20 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterLocation(R0));
+ switch (representation()) {
+ case kTagged:
+ case kUnboxedInt64:
+ locs->set_in(0,
+ Location::RegisterLocation(CallingConventions::kReturnReg));
+ break;
+ case kUnboxedDouble:
+ locs->set_in(
+ 0, Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
return locs;
}
@@ -170,8 +256,14 @@
// The entry needs to be patchable, no inlined objects are allowed in the area
// that will be overwritten by the patch instructions: a branch macro sequence.
void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- const Register result = locs()->in(0).reg();
- ASSERT(result == R0);
+ if (locs()->in(0).IsRegister()) {
+ const Register result = locs()->in(0).reg();
+ ASSERT(result == CallingConventions::kReturnReg);
+ } else {
+ ASSERT(locs()->in(0).IsFpuRegister());
+ const FpuRegister result = locs()->in(0).fpu_reg();
+ ASSERT(result == CallingConventions::kReturnFpuReg);
+ }
if (compiler->intrinsic_mode()) {
// Intrinsics don't have a frame.
@@ -306,8 +398,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
summary->set_in(0, Location::RegisterLocation(R0)); // ClassId
- summary->set_out(0, Location::RegisterLocation(R0));
- return summary;
+ return MakeCallSummary(zone, this, summary);
}
LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
@@ -317,8 +408,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
summary->set_in(0, Location::RegisterLocation(R0)); // Function.
- summary->set_out(0, Location::RegisterLocation(R0));
- return summary;
+ return MakeCallSummary(zone, this, summary);
}
void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -1325,8 +1415,10 @@
__ Push(array);
const int kTypeArgsLen = 0;
const int kNumberOfArguments = 1;
+ constexpr int kSizeOfArguments = 1;
const Array& kNoArgumentNames = Object::null_array();
- ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
+ ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kSizeOfArguments,
+ kNoArgumentNames);
compiler->GenerateStaticCall(deopt_id(), token_pos(), CallFunction(),
args_info, locs(), ICData::Handle(),
ICData::kStatic);
@@ -1441,13 +1533,13 @@
const Location index = locs()->in(1);
compiler::Address element_address(TMP); // Bad address.
- element_address =
- index.IsRegister()
- ? __ ElementAddressForRegIndex(IsExternal(), class_id(),
- index_scale(), array, index.reg(), TMP)
- : __ ElementAddressForIntIndex(IsExternal(), class_id(),
- index_scale(), array,
- Smi::Cast(index.constant()).Value());
+ element_address = index.IsRegister()
+ ? __ ElementAddressForRegIndex(
+ IsExternal(), class_id(), index_scale(),
+ index_unboxed_, array, index.reg(), TMP)
+ : __ ElementAddressForIntIndex(
+ IsExternal(), class_id(), index_scale(), array,
+ Smi::Cast(index.constant()).Value());
if ((representation() == kUnboxedDouble) ||
(representation() == kUnboxedFloat32x4) ||
(representation() == kUnboxedInt32x4) ||
@@ -1576,7 +1668,8 @@
}
// Warning: element_address may use register TMP as base.
compiler::Address element_address = __ ElementAddressForRegIndexWithSize(
- IsExternal(), class_id(), sz, index_scale(), str, index.reg(), TMP);
+ IsExternal(), class_id(), sz, index_scale(), /*index_unboxed=*/false, str,
+ index.reg(), TMP);
__ ldr(result, element_address, sz);
__ SmiTag(result);
@@ -1586,7 +1679,13 @@
intptr_t idx) const {
// Array can be a Dart object or a pointer to external data.
if (idx == 0) return kNoRepresentation; // Flexible input representation.
- if (idx == 1) return kTagged; // Index is a smi.
+ if (idx == 1) {
+ if (index_unboxed_) {
+ return kNoRepresentation; // Index can be any unboxed representation.
+ } else {
+ return kTagged; // Index is a smi.
+ }
+ }
ASSERT(idx == 2);
switch (class_id_) {
case kArrayCid:
@@ -1687,7 +1786,8 @@
if (class_id() == kArrayCid && ShouldEmitStoreBarrier()) {
if (index.IsRegister()) {
__ ComputeElementAddressForRegIndex(temp, IsExternal(), class_id(),
- index_scale(), array, index.reg());
+ index_scale(), index_unboxed_, array,
+ index.reg());
} else {
__ ComputeElementAddressForIntIndex(temp, IsExternal(), class_id(),
index_scale(), array,
@@ -1699,14 +1799,13 @@
return;
}
- element_address =
- index.IsRegister()
- ? __ ElementAddressForRegIndex(IsExternal(), class_id(),
- index_scale(), array,
- index.reg(), temp)
- : __ ElementAddressForIntIndex(IsExternal(), class_id(),
- index_scale(), array,
- Smi::Cast(index.constant()).Value());
+ element_address = index.IsRegister()
+ ? __ ElementAddressForRegIndex(
+ IsExternal(), class_id(), index_scale(),
+ index_unboxed_, array, index.reg(), temp)
+ : __ ElementAddressForIntIndex(
+ IsExternal(), class_id(), index_scale(), array,
+ Smi::Cast(index.constant()).Value());
switch (class_id()) {
case kArrayCid:
@@ -3288,8 +3387,9 @@
}
__ PushPair(locs->in(1).reg(), locs->in(0).reg());
const auto& selector = String::Handle(instruction()->call()->Selector());
- const auto& arguments_descriptor = Array::Handle(
- ArgumentsDescriptor::New(/*type_args_len=*/0, /*num_arguments=*/2));
+ const auto& arguments_descriptor =
+ Array::Handle(ArgumentsDescriptor::NewBoxed(
+ /*type_args_len=*/0, /*num_arguments=*/2));
compiler->EmitMegamorphicInstanceCall(
selector, arguments_descriptor, instruction()->call()->deopt_id(),
instruction()->token_pos(), locs, try_index_, kNumSlowPathArgs);
@@ -3435,8 +3535,9 @@
}
__ PushPair(locs->in(1).reg(), locs->in(0).reg());
const auto& selector = String::Handle(instruction()->call()->Selector());
- const auto& arguments_descriptor = Array::Handle(
- ArgumentsDescriptor::New(/*type_args_len=*/0, /*num_arguments=*/2));
+ const auto& arguments_descriptor =
+ Array::Handle(ArgumentsDescriptor::NewBoxed(
+ /*type_args_len=*/0, /*num_arguments=*/2));
compiler->EmitMegamorphicInstanceCall(
selector, arguments_descriptor, instruction()->call()->deopt_id(),
instruction()->token_pos(), locs, try_index_, kNumSlowPathArgs);
@@ -4962,8 +5063,10 @@
const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
const int kTypeArgsLen = 0;
const int kNumberOfArguments = 1;
+ constexpr int kSizeOfArguments = 1;
const Array& kNoArgumentNames = Object::null_array();
- ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
+ ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kSizeOfArguments,
+ kNoArgumentNames);
compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), target,
args_info, locs(), ICData::Handle(),
ICData::kStatic);
@@ -6317,9 +6420,7 @@
}
} else if (to() == kUnboxedInt64) {
if (from() == kUnboxedUint32) {
- if (out != value) {
- __ mov(out, value);
- }
+ __ uxtw(out, value);
} else {
ASSERT(from() == kUnboxedInt32);
__ sxtw(out, value); // Signed extension 32->64.
diff --git a/runtime/vm/compiler/backend/il_deserializer.cc b/runtime/vm/compiler/backend/il_deserializer.cc
index 9fd98ac..9901da4 100644
--- a/runtime/vm/compiler/backend/il_deserializer.cc
+++ b/runtime/vm/compiler/backend/il_deserializer.cc
@@ -222,8 +222,20 @@
block_it.Advance()) {
auto const entry = block_it.Current();
if (!IsHandledInstruction(entry)) unhandled->Add(entry);
- // Don't check the Phi definitions in JoinEntrys, as those are now handled
- // and also parsed differently from other definitions.
+ // Check that the Phi instructions in JoinEntrys do not have pair
+ // representation.
+ if (auto const join_block = entry->AsJoinEntry()) {
+ auto const phis = join_block->phis();
+ auto const length = ((phis == nullptr) ? 0 : phis->length());
+ for (intptr_t i = 0; i < length; i++) {
+ auto const current = phis->At(i);
+ for (intptr_t j = 0; j < current->InputCount(); j++) {
+ if (current->InputAt(j)->definition()->HasPairRepresentation()) {
+ unhandled->Add(current);
+ }
+ }
+ }
+ }
if (auto const def_block = entry->AsBlockEntryWithInitialDefs()) {
auto const defs = def_block->initial_definitions();
for (intptr_t i = 0; i < defs->length(); i++) {
@@ -1134,7 +1146,19 @@
const InstrInfo& info) {
ASSERT(current_block_ != nullptr);
if (auto const index_sexp = CheckInteger(Retrieve(sexp, 1))) {
- return new (zone()) ParameterInstr(index_sexp->value(), current_block_);
+ const auto param_offset_sexp =
+ CheckInteger(sexp->ExtraLookupValue("param_offset"));
+ ASSERT(param_offset_sexp != nullptr);
+ const auto representation_sexp =
+ CheckSymbol(sexp->ExtraLookupValue("representation"));
+ Representation representation;
+ if (!Location::ParseRepresentation(representation_sexp->value(),
+ &representation)) {
+ StoreError(representation_sexp, "unknown parameter representation");
+ }
+ return new (zone())
+ ParameterInstr(index_sexp->value(), param_offset_sexp->value(),
+ current_block_, representation);
}
return nullptr;
}
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 80796f1..d9c0348b 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -31,7 +31,11 @@
// Generic summary for call instructions that have all arguments pushed
// on the stack and return the result in a fixed register EAX.
-LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
+LocationSummary* Instruction::MakeCallSummary(Zone* zone,
+ const Instruction* instr,
+ LocationSummary* locs) {
+ // This is unused on ia32.
+ ASSERT(locs == nullptr);
const intptr_t kNumInputs = 0;
const intptr_t kNumTemps = 0;
LocationSummary* result = new (zone)
@@ -42,6 +46,7 @@
DEFINE_BACKEND(LoadIndexedUnsafe, (Register out, Register index)) {
ASSERT(instr->RequiredInputRepresentation(0) == kTagged); // It is a Smi.
+ ASSERT(instr->representation() == kTagged);
__ movl(out, compiler::Address(instr->base_reg(), index, TIMES_2,
instr->offset()));
@@ -76,6 +81,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ ASSERT(representation() == kTagged);
locs->set_in(0, LocationAnyOrConstant(value()));
return locs;
}
@@ -101,6 +107,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ ASSERT(representation() == kTagged);
locs->set_in(0, Location::RegisterLocation(EAX));
return locs;
}
@@ -1176,8 +1183,10 @@
__ pushl(array);
const int kTypeArgsLen = 0;
const int kNumberOfArguments = 1;
+ constexpr int kSizeOfArguments = 1;
const Array& kNoArgumentNames = Object::null_array();
- ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
+ ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kSizeOfArguments,
+ kNoArgumentNames);
compiler->GenerateStaticCall(deopt_id(), token_pos(), CallFunction(),
args_info, locs(), ICData::Handle(),
ICData::kStatic);
@@ -1283,14 +1292,14 @@
const Location index = locs()->in(1);
compiler::Address element_address =
- index.IsRegister()
- ? compiler::Assembler::ElementAddressForRegIndex(
- IsExternal(), class_id(), index_scale(), array, index.reg())
- : compiler::Assembler::ElementAddressForIntIndex(
- IsExternal(), class_id(), index_scale(), array,
- Smi::Cast(index.constant()).Value());
+ index.IsRegister() ? compiler::Assembler::ElementAddressForRegIndex(
+ IsExternal(), class_id(), index_scale(),
+ index_unboxed_, array, index.reg())
+ : compiler::Assembler::ElementAddressForIntIndex(
+ IsExternal(), class_id(), index_scale(), array,
+ Smi::Cast(index.constant()).Value());
- if (index_scale() == 1) {
+ if (index_scale() == 1 && !index_unboxed_) {
if (index.IsRegister()) {
__ SmiUntag(index.reg());
} else {
@@ -1347,8 +1356,8 @@
element_address =
index.IsRegister()
? compiler::Assembler::ElementAddressForRegIndex(
- IsExternal(), class_id(), index_scale(), array, index.reg(),
- kWordSize)
+ IsExternal(), class_id(), index_scale(), index_unboxed_,
+ array, index.reg(), kWordSize)
: compiler::Assembler::ElementAddressForIntIndex(
IsExternal(), class_id(), index_scale(), array,
Smi::Cast(index.constant()).Value(), kWordSize);
@@ -1402,7 +1411,14 @@
intptr_t idx) const {
// Array can be a Dart object or a pointer to external data.
if (idx == 0) return kNoRepresentation; // Flexible input representation.
- if (idx == 1) return kTagged; // Index is a smi.
+ if (idx == 1) {
+ if (index_unboxed_) {
+ // TODO(dartbug.com/39432): kUnboxedInt32 || kUnboxedUint32.
+ return kNoRepresentation;
+ } else {
+ return kTagged; // Index is a smi.
+ }
+ }
ASSERT(idx == 2);
switch (class_id_) {
case kArrayCid:
@@ -1512,14 +1528,14 @@
const Location index = locs()->in(1);
compiler::Address element_address =
- index.IsRegister()
- ? compiler::Assembler::ElementAddressForRegIndex(
- IsExternal(), class_id(), index_scale(), array, index.reg())
- : compiler::Assembler::ElementAddressForIntIndex(
- IsExternal(), class_id(), index_scale(), array,
- Smi::Cast(index.constant()).Value());
+ index.IsRegister() ? compiler::Assembler::ElementAddressForRegIndex(
+ IsExternal(), class_id(), index_scale(),
+ index_unboxed_, array, index.reg())
+ : compiler::Assembler::ElementAddressForIntIndex(
+ IsExternal(), class_id(), index_scale(), array,
+ Smi::Cast(index.constant()).Value());
- if ((index_scale() == 1) && index.IsRegister()) {
+ if ((index_scale() == 1) && index.IsRegister() && !index_unboxed_) {
__ SmiUntag(index.reg());
}
switch (class_id()) {
@@ -1602,8 +1618,8 @@
element_address =
index.IsRegister()
? compiler::Assembler::ElementAddressForRegIndex(
- IsExternal(), class_id(), index_scale(), array, index.reg(),
- kWordSize)
+ IsExternal(), class_id(), index_scale(), index_unboxed_,
+ array, index.reg(), kWordSize)
: compiler::Assembler::ElementAddressForIntIndex(
IsExternal(), class_id(), index_scale(), array,
Smi::Cast(index.constant()).Value(), kWordSize);
@@ -4000,7 +4016,8 @@
compiler::Address element_address =
compiler::Assembler::ElementAddressForRegIndex(
- IsExternal(), class_id(), index_scale(), str, index.reg());
+ IsExternal(), class_id(), index_scale(), /*index_unboxed=*/false, str,
+ index.reg());
if ((index_scale() == 1)) {
__ SmiUntag(index.reg());
@@ -4890,8 +4907,10 @@
const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
const int kTypeArgsLen = 0;
const int kNumberOfArguments = 1;
+ constexpr int kSizeOfArguments = 1;
const Array& kNoArgumentNames = Object::null_array();
- ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
+ ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kSizeOfArguments,
+ kNoArgumentNames);
compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), target,
args_info, locs(), ICData::Handle(),
ICData::kStatic);
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
index 45b7a03..f2e5cf9 100644
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ b/runtime/vm/compiler/backend/il_serializer.cc
@@ -931,6 +931,9 @@
void ParameterInstr::AddOperandsToSExpression(SExpList* sexp,
FlowGraphSerializer* s) const {
s->AddInteger(sexp, index());
+ s->AddExtraInteger(sexp, "param_offset", param_offset());
+ s->AddExtraSymbol(sexp, "representation",
+ Location::RepresentationToCString(representation()));
}
void SpecialParameterInstr::AddOperandsToSExpression(
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 5625a0c..c031db4 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -30,21 +30,80 @@
namespace dart {
// Generic summary for call instructions that have all arguments pushed
-// on the stack and return the result in a fixed register RAX.
-LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
+// on the stack and return the result in a fixed register RAX (or XMM0 if
+// the return type is double).
+LocationSummary* Instruction::MakeCallSummary(Zone* zone,
+ const Instruction* instr,
+ LocationSummary* locs) {
+ ASSERT(locs == nullptr || locs->always_calls());
LocationSummary* result =
- new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
- result->set_out(0, Location::RegisterLocation(RAX));
+ ((locs == nullptr)
+ ? (new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall))
+ : locs);
+ const auto representation = instr->representation();
+ switch (representation) {
+ case kTagged:
+ case kUnboxedInt64:
+ result->set_out(
+ 0, Location::RegisterLocation(CallingConventions::kReturnReg));
+ break;
+ case kUnboxedDouble:
+ result->set_out(
+ 0, Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
return result;
}
-DEFINE_BACKEND(LoadIndexedUnsafe, (Register out, Register index)) {
- ASSERT(instr->RequiredInputRepresentation(0) == kTagged); // It is a Smi.
- __ movq(out, compiler::Address(instr->base_reg(), index, TIMES_4,
- instr->offset()));
+LocationSummary* LoadIndexedUnsafeInstr::MakeLocationSummary(Zone* zone,
+ bool opt) const {
+ const intptr_t kNumInputs = 1;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* locs = new (zone)
+ LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ locs->set_in(0, Location::RequiresRegister());
+ switch (representation()) {
+ case kTagged:
+ case kUnboxedInt64:
+ locs->set_out(0, Location::RequiresRegister());
+ break;
+ case kUnboxedDouble:
+ locs->set_out(0, Location::RequiresFpuRegister());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return locs;
+}
+
+void LoadIndexedUnsafeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(RequiredInputRepresentation(0) == kTagged); // It is a Smi.
ASSERT(kSmiTag == 0);
ASSERT(kSmiTagSize == 1);
+
+ const Register index = locs()->in(0).reg();
+
+ switch (representation()) {
+ case kTagged:
+ case kUnboxedInt64: {
+ const auto out = locs()->out(0).reg();
+ __ movq(out, compiler::Address(base_reg(), index, TIMES_4, offset()));
+ break;
+ }
+ case kUnboxedDouble: {
+ const auto out = locs()->out(0).fpu_reg();
+ __ movsd(out, compiler::Address(base_reg(), index, TIMES_4, offset()));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
}
DEFINE_BACKEND(StoreIndexedUnsafe,
@@ -76,7 +135,13 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, LocationAnyOrConstant(value()));
+ if (representation() == kUnboxedDouble) {
+ locs->set_in(0, Location::RequiresFpuRegister());
+ } else if (representation() == kUnboxedInt64) {
+ locs->set_in(0, Location::RequiresRegister());
+ } else {
+ locs->set_in(0, LocationAnyOrConstant(value()));
+ }
return locs;
}
@@ -89,6 +154,9 @@
__ pushq(value.reg());
} else if (value.IsConstant()) {
__ PushObject(value.constant());
+ } else if (value.IsFpuRegister()) {
+ __ AddImmediate(RSP, compiler::Immediate(-kDoubleSize));
+ __ movsd(compiler::Address(RSP, 0), value.fpu_reg());
} else {
ASSERT(value.IsStackSlot());
__ pushq(LocationToStackSlotAddress(value));
@@ -101,7 +169,20 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterLocation(RAX));
+ switch (representation()) {
+ case kTagged:
+ case kUnboxedInt64:
+ locs->set_in(0,
+ Location::RegisterLocation(CallingConventions::kReturnReg));
+ break;
+ case kUnboxedDouble:
+ locs->set_in(
+ 0, Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
return locs;
}
@@ -109,8 +190,14 @@
// The entry needs to be patchable, no inlined objects are allowed in the area
// that will be overwritten by the patch instruction: a jump).
void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- Register result = locs()->in(0).reg();
- ASSERT(result == RAX);
+ if (locs()->in(0).IsRegister()) {
+ const Register result = locs()->in(0).reg();
+ ASSERT(result == CallingConventions::kReturnReg);
+ } else {
+ ASSERT(locs()->in(0).IsFpuRegister());
+ const FpuRegister result = locs()->in(0).fpu_reg();
+ ASSERT(result == CallingConventions::kReturnFpuReg);
+ }
if (compiler->intrinsic_mode()) {
// Intrinsics don't have a frame.
@@ -1240,8 +1327,10 @@
__ pushq(array);
const int kTypeArgsLen = 0;
const int kNumberOfArguments = 1;
+ constexpr int kSizeOfArguments = 1;
const Array& kNoArgumentNames = Object::null_array();
- ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
+ ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kSizeOfArguments,
+ kNoArgumentNames);
compiler->GenerateStaticCall(deopt_id(), token_pos(), CallFunction(),
args_info, locs(), ICData::Handle(),
ICData::kStatic);
@@ -1398,14 +1487,14 @@
const Location index = locs()->in(1);
compiler::Address element_address =
- index.IsRegister()
- ? compiler::Assembler::ElementAddressForRegIndex(
- IsExternal(), class_id(), index_scale(), array, index.reg())
- : compiler::Assembler::ElementAddressForIntIndex(
- IsExternal(), class_id(), index_scale(), array,
- Smi::Cast(index.constant()).Value());
+ index.IsRegister() ? compiler::Assembler::ElementAddressForRegIndex(
+ IsExternal(), class_id(), index_scale(),
+ index_unboxed_, array, index.reg())
+ : compiler::Assembler::ElementAddressForIntIndex(
+ IsExternal(), class_id(), index_scale(), array,
+ Smi::Cast(index.constant()).Value());
- if (index_scale() == 1) {
+ if (index_scale() == 1 && !index_unboxed_) {
if (index.IsRegister()) {
__ SmiUntag(index.reg());
} else {
@@ -1500,7 +1589,8 @@
compiler::Address element_address =
compiler::Assembler::ElementAddressForRegIndex(
- IsExternal(), class_id(), index_scale(), str, index.reg());
+ IsExternal(), class_id(), index_scale(), /*index_unboxed=*/false, str,
+ index.reg());
if ((index_scale() == 1)) {
__ SmiUntag(index.reg());
@@ -1547,7 +1637,13 @@
Representation StoreIndexedInstr::RequiredInputRepresentation(
intptr_t idx) const {
if (idx == 0) return kNoRepresentation;
- if (idx == 1) return kTagged;
+ if (idx == 1) {
+ if (index_unboxed_) {
+ return kUnboxedInt64;
+ } else {
+ return kTagged; // Index is a smi.
+ }
+ }
ASSERT(idx == 2);
switch (class_id_) {
case kArrayCid:
@@ -1658,14 +1754,14 @@
const Location index = locs()->in(1);
compiler::Address element_address =
- index.IsRegister()
- ? compiler::Assembler::ElementAddressForRegIndex(
- IsExternal(), class_id(), index_scale(), array, index.reg())
- : compiler::Assembler::ElementAddressForIntIndex(
- IsExternal(), class_id(), index_scale(), array,
- Smi::Cast(index.constant()).Value());
+ index.IsRegister() ? compiler::Assembler::ElementAddressForRegIndex(
+ IsExternal(), class_id(), index_scale(),
+ index_unboxed_, array, index.reg())
+ : compiler::Assembler::ElementAddressForIntIndex(
+ IsExternal(), class_id(), index_scale(), array,
+ Smi::Cast(index.constant()).Value());
- if ((index_scale() == 1) && index.IsRegister()) {
+ if ((index_scale() == 1) && index.IsRegister() && !index_unboxed_) {
__ SmiUntag(index.reg());
}
switch (class_id()) {
@@ -3293,8 +3389,9 @@
__ pushq(locs->in(0).reg());
__ pushq(locs->in(1).reg());
const auto& selector = String::Handle(instruction()->call()->Selector());
- const auto& arguments_descriptor = Array::Handle(
- ArgumentsDescriptor::New(/*type_args_len=*/0, /*num_arguments=*/2));
+ const auto& arguments_descriptor =
+ Array::Handle(ArgumentsDescriptor::NewBoxed(
+ /*type_args_len=*/0, /*num_arguments=*/2));
compiler->EmitMegamorphicInstanceCall(
selector, arguments_descriptor, instruction()->call()->deopt_id(),
instruction()->token_pos(), locs, try_index_, kNumSlowPathArgs);
@@ -3466,8 +3563,9 @@
__ pushq(locs->in(1).reg());
const auto& selector = String::Handle(instruction()->call()->Selector());
- const auto& arguments_descriptor = Array::Handle(
- ArgumentsDescriptor::New(/*type_args_len=*/0, /*num_arguments=*/2));
+ const auto& arguments_descriptor =
+ Array::Handle(ArgumentsDescriptor::NewBoxed(
+ /*type_args_len=*/0, /*num_arguments=*/2));
compiler->EmitMegamorphicInstanceCall(
selector, arguments_descriptor, instruction()->call()->deopt_id(),
@@ -5055,8 +5153,10 @@
const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
const int kTypeArgsLen = 0;
const int kNumberOfArguments = 1;
+ constexpr int kSizeOfArguments = 1;
const Array& kNoArgumentNames = Object::null_array();
- ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kNoArgumentNames);
+ ArgumentsInfo args_info(kTypeArgsLen, kNumberOfArguments, kSizeOfArguments,
+ kNoArgumentNames);
compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), target,
args_info, locs(), ICData::Handle(),
ICData::kStatic);
@@ -6739,8 +6839,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
summary->set_in(0, Location::RegisterLocation(RCX)); // ClassId
- summary->set_out(0, Location::RegisterLocation(RAX));
- return summary;
+ return MakeCallSummary(zone, this, summary);
}
LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone,
@@ -6750,8 +6849,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
summary->set_in(0, Location::RegisterLocation(RAX)); // Function.
- summary->set_out(0, Location::RegisterLocation(RAX));
- return summary;
+ return MakeCallSummary(zone, this, summary);
}
void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 77a65b7..139e73d 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -659,6 +659,9 @@
RedefinitionInstr* redefinition =
new (zone) RedefinitionInstr(actual->Copy(zone));
redefinition->set_ssa_temp_index(caller_graph->alloc_ssa_temp_index());
+ if (FlowGraph::NeedsPairLocation(redefinition->representation())) {
+ caller_graph->alloc_ssa_temp_index();
+ }
if (target_info->IsSingleCid()) {
redefinition->UpdateType(CompileType::FromCid(target_info->cid_start));
}
@@ -707,6 +710,9 @@
Slot::Closure_context(), call_data->call->token_pos());
context_load->set_ssa_temp_index(
caller_graph->alloc_ssa_temp_index());
+ if (FlowGraph::NeedsPairLocation(context_load->representation())) {
+ caller_graph->alloc_ssa_temp_index();
+ }
context_load->InsertBefore(callee_entry->next());
param->ReplaceUsesWith(context_load);
break;
@@ -875,7 +881,8 @@
if (constant != NULL) {
return new (Z) ConstantInstr(constant->value());
} else {
- ParameterInstr* param = new (Z) ParameterInstr(i, graph->graph_entry());
+ ParameterInstr* param = new (Z)
+ ParameterInstr(i, -1, graph->graph_entry(), kNoRepresentation);
param->UpdateType(*argument->Type());
return param;
}
@@ -1799,6 +1806,9 @@
new (Z) RedefinitionInstr(new (Z) Value(receiver));
redefinition->set_ssa_temp_index(
owner_->caller_graph()->alloc_ssa_temp_index());
+ if (FlowGraph::NeedsPairLocation(redefinition->representation())) {
+ owner_->caller_graph()->alloc_ssa_temp_index();
+ }
if (FlowGraphInliner::TryInlineRecognizedMethod(
owner_->caller_graph(), receiver_cid, target, call_, redefinition,
call_->token_pos(), call_->ic_data(), graph_entry, &entry, &last,
@@ -2060,6 +2070,9 @@
call_->complete());
fallback_call->set_ssa_temp_index(
owner_->caller_graph()->alloc_ssa_temp_index());
+ if (FlowGraph::NeedsPairLocation(fallback_call->representation())) {
+ owner_->caller_graph()->alloc_ssa_temp_index();
+ }
fallback_call->InheritDeoptTarget(zone(), call_);
fallback_call->set_total_call_count(call_->CallCount());
ReturnInstr* fallback_return = new ReturnInstr(
@@ -2453,8 +2466,9 @@
// Array load and return.
intptr_t index_scale = compiler::target::Instance::ElementSizeFor(array_cid);
LoadIndexedInstr* load = new (Z) LoadIndexedInstr(
- new (Z) Value(array), new (Z) Value(index), index_scale, array_cid,
- kAlignedAccess, deopt_id, call->token_pos(), ResultType(call));
+ new (Z) Value(array), new (Z) Value(index), /*index_unboxed=*/false,
+ index_scale, array_cid, kAlignedAccess, deopt_id, call->token_pos(),
+ ResultType(call));
*last = load;
cursor = flow_graph->AppendTo(cursor, load,
@@ -2675,8 +2689,8 @@
compiler::target::Instance::ElementSizeFor(array_cid);
*last = new (Z) StoreIndexedInstr(
new (Z) Value(array), new (Z) Value(index), new (Z) Value(stored_value),
- needs_store_barrier, index_scale, array_cid, kAlignedAccess,
- call->deopt_id(), call->token_pos());
+ needs_store_barrier, /*index_unboxed=*/false, index_scale, array_cid,
+ kAlignedAccess, call->deopt_id(), call->token_pos());
flow_graph->AppendTo(cursor, *last, call->env(), FlowGraph::kEffect);
// We need a return value to replace uses of the original definition. However,
// the final instruction is a use of 'void operator[]=()', so we use null.
@@ -2940,11 +2954,10 @@
// Fill out the generated template with loads.
// Load from either external or internal.
- LoadIndexedInstr* load =
- new (Z) LoadIndexedInstr(new (Z) Value(array), new (Z) Value(index),
- 1, // Index scale
- view_cid, kUnalignedAccess, DeoptId::kNone,
- call->token_pos(), ResultType(call));
+ LoadIndexedInstr* load = new (Z) LoadIndexedInstr(
+ new (Z) Value(array), new (Z) Value(index),
+ /*index_unboxed=*/false, /*index_scale=*/1, view_cid, kUnalignedAccess,
+ DeoptId::kNone, call->token_pos(), ResultType(call));
flow_graph->AppendTo(
cursor, load, call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
FlowGraph::kValue);
@@ -2967,8 +2980,9 @@
intptr_t view_cid) {
return new (Z) StoreIndexedInstr(
new (Z) Value(array), new (Z) Value(index), new (Z) Value(stored_value),
- kNoStoreBarrier, 1, // Index scale
- view_cid, kUnalignedAccess, call->deopt_id(), call->token_pos());
+ kNoStoreBarrier, /*index_unboxed=*/false,
+ /*index_scale=*/1, view_cid, kUnalignedAccess, call->deopt_id(),
+ call->token_pos());
}
static bool InlineByteArrayBaseStore(FlowGraph* flow_graph,
@@ -3215,10 +3229,10 @@
cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
}
- LoadIndexedInstr* load_indexed = new (Z)
- LoadIndexedInstr(new (Z) Value(str), new (Z) Value(index),
- compiler::target::Instance::ElementSizeFor(cid), cid,
- kAlignedAccess, DeoptId::kNone, call->token_pos());
+ LoadIndexedInstr* load_indexed = new (Z) LoadIndexedInstr(
+ new (Z) Value(str), new (Z) Value(index), /*index_unboxed=*/false,
+ compiler::target::Instance::ElementSizeFor(cid), cid, kAlignedAccess,
+ DeoptId::kNone, call->token_pos());
cursor = flow_graph->AppendTo(cursor, load_indexed, NULL, FlowGraph::kValue);
auto box = BoxInstr::Create(kUnboxedIntPtr, new Value(load_indexed));
@@ -4231,12 +4245,11 @@
value->AsUnboxInteger()->mark_truncating();
flow_graph->AppendTo(*entry, value, env, FlowGraph::kValue);
- *last =
- new (Z) StoreIndexedInstr(new (Z) Value(str), new (Z) Value(index),
- new (Z) Value(value), kNoStoreBarrier,
- 1, // Index scale
- kOneByteStringCid, kAlignedAccess,
- call->deopt_id(), call->token_pos());
+ *last = new (Z) StoreIndexedInstr(
+ new (Z) Value(str), new (Z) Value(index), new (Z) Value(value),
+ kNoStoreBarrier, /*index_unboxed=*/false,
+ /*index_scale=*/1, kOneByteStringCid, kAlignedAccess,
+ call->deopt_id(), call->token_pos());
flow_graph->AppendTo(value, *last, env, FlowGraph::kEffect);
// We need a return value to replace uses of the original definition.
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 7635384..402954d 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -617,7 +617,15 @@
auto& initial_definitions = *entry->initial_definitions();
for (intptr_t i = 0; i < initial_definitions.length(); i++) {
Definition* defn = initial_definitions[i];
- ASSERT(!defn->HasPairRepresentation());
+ if (defn->HasPairRepresentation()) {
+ // The lower bits are pushed after the higher bits
+ LiveRange* range =
+ GetLiveRange(ToSecondPairVreg(defn->ssa_temp_index()));
+ range->AddUseInterval(entry->start_pos(), entry->start_pos() + 2);
+ range->DefineAt(entry->start_pos());
+ ProcessInitialDefinition(defn, range, entry,
+ /*second_location_for_definition=*/true);
+ }
LiveRange* range = GetLiveRange(defn->ssa_temp_index());
range->AddUseInterval(entry->start_pos(), entry->start_pos() + 2);
range->DefineAt(entry->start_pos());
@@ -647,9 +655,11 @@
}
}
-void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn,
- LiveRange* range,
- BlockEntryInstr* block) {
+void FlowGraphAllocator::ProcessInitialDefinition(
+ Definition* defn,
+ LiveRange* range,
+ BlockEntryInstr* block,
+ bool second_location_for_definition) {
// Save the range end because it may change below.
const intptr_t range_end = range->End();
@@ -687,17 +697,24 @@
}
if (defn->IsParameter()) {
+ // Only function entries may have unboxed parameters, possibly making the
+ // parameters size different from the number of parameters on 32-bit
+ // architectures.
+ const intptr_t parameters_size = block->IsFunctionEntry()
+ ? flow_graph_.direct_parameters_size()
+ : flow_graph_.num_direct_parameters();
ParameterInstr* param = defn->AsParameter();
- intptr_t slot_index = param->index();
+ intptr_t slot_index =
+ param->param_offset() + (second_location_for_definition ? -1 : 0);
ASSERT(slot_index >= 0);
if (param->base_reg() == FPREG) {
// Slot index for the rightmost fixed parameter is -1.
- slot_index -= flow_graph_.num_direct_parameters();
+ slot_index -= parameters_size;
} else {
// Slot index for a "frameless" parameter is reversed.
ASSERT(param->base_reg() == SPREG);
- ASSERT(slot_index < flow_graph_.num_direct_parameters());
- slot_index = flow_graph_.num_direct_parameters() - 1 - slot_index;
+ ASSERT(slot_index < parameters_size);
+ slot_index = parameters_size - 1 - slot_index;
}
if (param->base_reg() == FPREG) {
@@ -707,9 +724,19 @@
ASSERT(param->base_reg() == SPREG);
slot_index += compiler::target::frame_layout.last_param_from_entry_sp;
}
- range->set_assigned_location(
- Location::StackSlot(slot_index, param->base_reg()));
- range->set_spill_slot(Location::StackSlot(slot_index, param->base_reg()));
+
+ if (param->representation() == kUnboxedInt64 ||
+ param->representation() == kTagged) {
+ const auto location = Location::StackSlot(slot_index, param->base_reg());
+ range->set_assigned_location(location);
+ range->set_spill_slot(location);
+ } else {
+ ASSERT(param->representation() == kUnboxedDouble);
+ const auto location =
+ Location::DoubleStackSlot(slot_index, param->base_reg());
+ range->set_assigned_location(location);
+ range->set_spill_slot(location);
+ }
} else if (defn->IsSpecialParameter()) {
SpecialParameterInstr* param = defn->AsSpecialParameter();
ASSERT(param->kind() == SpecialParameterInstr::kArgDescriptor);
@@ -738,8 +765,7 @@
range->finger()->FirstRegisterBeneficialUse(block->start_pos());
if (use != NULL) {
LiveRange* tail = SplitBetween(range, block->start_pos(), use->pos());
- // Parameters and constants are tagged, so allocated to CPU registers.
- CompleteRange(tail, Location::kRegister);
+ CompleteRange(tail, defn->RegisterKindForResult());
}
ConvertAllUses(range);
Location spill_slot = range->spill_slot();
@@ -2854,9 +2880,12 @@
initial_definitions = entry->initial_definitions();
for (intptr_t i = 0; i < initial_definitions->length(); ++i) {
Definition* def = (*initial_definitions)[i];
- ASSERT(!def->HasPairRepresentation());
value_representations_[def->ssa_temp_index()] =
RepresentationForRange(def->representation());
+ if (def->HasPairRepresentation()) {
+ value_representations_[ToSecondPairVreg(def->ssa_temp_index())] =
+ RepresentationForRange(def->representation());
+ }
}
} else if (auto join = block->AsJoinEntry()) {
for (PhiIterator it(join); !it.Done(); it.Advance()) {
diff --git a/runtime/vm/compiler/backend/linearscan.h b/runtime/vm/compiler/backend/linearscan.h
index 8b774cc..541bd2c 100644
--- a/runtime/vm/compiler/backend/linearscan.h
+++ b/runtime/vm/compiler/backend/linearscan.h
@@ -128,7 +128,8 @@
void ProcessInitialDefinition(Definition* defn,
LiveRange* range,
- BlockEntryInstr* block);
+ BlockEntryInstr* block,
+ bool second_location_for_definition = false);
void ConnectIncomingPhiMoves(JoinEntryInstr* join);
void BlockLocation(Location loc, intptr_t from, intptr_t to);
void BlockRegisterLocation(Location loc,
diff --git a/runtime/vm/compiler/backend/locations.cc b/runtime/vm/compiler/backend/locations.cc
index 6cc94cf..2153fac 100644
--- a/runtime/vm/compiler/backend/locations.cc
+++ b/runtime/vm/compiler/backend/locations.cc
@@ -13,6 +13,31 @@
namespace dart {
+const char* Location::RepresentationToCString(Representation repr) {
+ switch (repr) {
+#define REPR_CASE(Name) \
+ case k##Name: \
+ return #Name;
+ FOR_EACH_REPRESENTATION_KIND(REPR_CASE)
+#undef KIND_CASE
+ default:
+ UNREACHABLE();
+ }
+ return nullptr;
+}
+
+bool Location::ParseRepresentation(const char* str, Representation* out) {
+ ASSERT(str != nullptr && out != nullptr);
+#define KIND_CASE(Name) \
+ if (strcmp(str, #Name) == 0) { \
+ *out = k##Name; \
+ return true; \
+ }
+ FOR_EACH_REPRESENTATION_KIND(KIND_CASE)
+#undef KIND_CASE
+ return false;
+}
+
intptr_t RegisterSet::RegisterCount(intptr_t registers) {
// Brian Kernighan's algorithm for counting the bits set.
intptr_t count = 0;
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index da9cc2b..117092a 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -20,20 +20,25 @@
class PairLocation;
class Value;
+#define FOR_EACH_REPRESENTATION_KIND(M) \
+ M(NoRepresentation) \
+ M(Tagged) \
+ M(Untagged) \
+ M(UnboxedDouble) \
+ M(UnboxedFloat) \
+ M(UnboxedInt32) \
+ M(UnboxedUint32) \
+ M(UnboxedInt64) \
+ M(UnboxedFloat32x4) \
+ M(UnboxedInt32x4) \
+ M(UnboxedFloat64x2) \
+ M(PairOfTagged)
+
enum Representation {
- kNoRepresentation,
- kTagged,
- kUntagged,
- kUnboxedDouble,
- kUnboxedFloat,
- kUnboxedInt32,
- kUnboxedUint32,
- kUnboxedInt64,
- kUnboxedFloat32x4,
- kUnboxedInt32x4,
- kUnboxedFloat64x2,
- kPairOfTagged,
- kNumRepresentations
+#define DECLARE_REPRESENTATION(name) k##name,
+ FOR_EACH_REPRESENTATION_KIND(DECLARE_REPRESENTATION)
+#undef DECLARE_REPRESENTATION
+ kNumRepresentations
};
// 'UnboxedFfiIntPtr' should be able to hold a pointer of the target word-size.
@@ -79,6 +84,9 @@
static const uword kLocationTagMask = 0x3;
public:
+ static bool ParseRepresentation(const char* str, Representation* out);
+ static const char* RepresentationToCString(Representation repr);
+
// Constant payload can overlap with kind field so Kind values
// have to be chosen in a way that their last 2 bits are never
// the same as kConstantTag or kPairLocationTag.
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 6f4700f..8a81d68 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2703,8 +2703,7 @@
case Slot::Kind::kClosure_function:
case Slot::Kind::kClosure_function_type_arguments:
case Slot::Kind::kClosure_instantiator_type_arguments:
- case Slot::Kind::kPointer_c_memory_address:
- case Slot::Kind::kTypedDataBase_data_field:
+ case Slot::Kind::kPointerBase_data_field:
case Slot::Kind::kTypedDataView_data:
case Slot::Kind::kType_arguments:
case Slot::Kind::kTypeArgumentsIndex:
@@ -2722,6 +2721,7 @@
case Slot::Kind::kArgumentsDescriptor_type_args_len:
case Slot::Kind::kArgumentsDescriptor_positional_count:
case Slot::Kind::kArgumentsDescriptor_count:
+ case Slot::Kind::kArgumentsDescriptor_size:
*range = Range(RangeBoundary::FromConstant(0), RangeBoundary::MaxSmi());
break;
}
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index d887101..b8ca816 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3586,6 +3586,9 @@
ConstantInstr* copy =
new (flow_graph_->zone()) ConstantInstr(orig->value());
copy->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+ if (FlowGraph::NeedsPairLocation(copy->representation())) {
+ flow_graph_->alloc_ssa_temp_index();
+ }
old->ReplaceUsesWith(copy);
copy->set_previous(old->previous()); // partial link
(*idefs)[j] = copy;
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index ffa2de3..8010098 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -642,21 +642,23 @@
// v1 <- LoadIndexed(array)
v1 = builder.AddDefinition(new LoadIndexedInstr(
- new Value(array), new Value(vc0), 1, kTypedDataUint32ArrayCid,
- kAlignedAccess, DeoptId::kNone, TokenPosition::kNoSource));
+ new Value(array), new Value(vc0), /*index_unboxed=*/false, 1,
+ kTypedDataUint32ArrayCid, kAlignedAccess, DeoptId::kNone,
+ TokenPosition::kNoSource));
// v2 <- LoadUntagged(array)
// StoreIndexed(v2, index=0, value=42)
v2 = builder.AddDefinition(new LoadUntaggedInstr(new Value(array), 0));
store = builder.AddInstruction(new StoreIndexedInstr(
- new Value(v2), new Value(vc0), new Value(vc42), kNoStoreBarrier, 1,
- kTypedDataUint32ArrayCid, kAlignedAccess, DeoptId::kNone,
- TokenPosition::kNoSource));
+ new Value(v2), new Value(vc0), new Value(vc42), kNoStoreBarrier,
+ /*index_unboxed=*/false, 1, kTypedDataUint32ArrayCid, kAlignedAccess,
+ DeoptId::kNone, TokenPosition::kNoSource));
// v3 <- LoadIndexed(array)
v3 = builder.AddDefinition(new LoadIndexedInstr(
- new Value(array), new Value(vc0), 1, kTypedDataUint32ArrayCid,
- kAlignedAccess, DeoptId::kNone, TokenPosition::kNoSource));
+ new Value(array), new Value(vc0), /*index_unboxed=*/false, 1,
+ kTypedDataUint32ArrayCid, kAlignedAccess, DeoptId::kNone,
+ TokenPosition::kNoSource));
// return v3
ret = builder.AddInstruction(new ReturnInstr(
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index f310041..83f819a 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -58,7 +58,6 @@
V(Closure, hash, Context, VAR) \
V(GrowableObjectArray, length, Smi, VAR) \
V(GrowableObjectArray, data, Array, VAR) \
- V(TypedDataBase, data_field, Dynamic, FINAL) \
V(TypedDataBase, length, Smi, FINAL) \
V(TypedDataView, offset_in_bytes, Smi, FINAL) \
V(TypedDataView, data, Dynamic, FINAL) \
@@ -71,7 +70,8 @@
V(ArgumentsDescriptor, type_args_len, Smi, FINAL) \
V(ArgumentsDescriptor, positional_count, Smi, FINAL) \
V(ArgumentsDescriptor, count, Smi, FINAL) \
- V(Pointer, c_memory_address, Dynamic, FINAL) \
+ V(ArgumentsDescriptor, size, Smi, FINAL) \
+ V(PointerBase, data_field, Dynamic, FINAL) \
V(Type, arguments, TypeArguments, FINAL)
// Slot is an abstraction that describes an readable (and possibly writeable)
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index 02a82c8..33fa26d 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -58,7 +58,7 @@
{
BlockBuilder builder(H.flow_graph(), normal_entry);
- v0 = builder.AddParameter(0, /*with_frame=*/true);
+ v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
builder.AddBranch(
new StrictCompareInstr(
TokenPosition::kNoSource, Token::kEQ_STRICT, new Value(v0),
@@ -124,7 +124,7 @@
{
BlockBuilder builder(H.flow_graph(), b1);
- v0 = builder.AddParameter(0, /*with_frame=*/true);
+ v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
auto load_cid = builder.AddDefinition(new LoadClassIdInstr(new Value(v0)));
builder.AddBranch(
new StrictCompareInstr(
@@ -216,7 +216,7 @@
{
BlockBuilder builder(H.flow_graph(), b1);
- v0 = builder.AddParameter(0, /*with_frame=*/true);
+ v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
builder.AddBranch(new StrictCompareInstr(
TokenPosition::kNoSource, Token::kEQ_STRICT,
new Value(v0), new Value(H.IntConstant(1)),
@@ -306,7 +306,7 @@
{
BlockBuilder builder(H.flow_graph(), b1);
- v0 = builder.AddParameter(0, /*with_frame=*/true);
+ v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
builder.AddBranch(new StrictCompareInstr(
TokenPosition::kNoSource, Token::kEQ_STRICT,
new Value(v0), new Value(H.IntConstant(1)),
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 2508edf..70b5134 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -125,13 +125,16 @@
Token::IsEqualityOperator(op_kind) ||
Token::IsBinaryOperator(op_kind)) {
// Guess cid: if one of the inputs is a number assume that the other
- // is a number of same type.
- const intptr_t cid_0 = class_ids[0];
- const intptr_t cid_1 = class_ids[1];
- if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
- class_ids[0] = cid_1;
- } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) {
- class_ids[1] = cid_0;
+ // is a number of same type, unless the interface target tells us this
+ // is impossible.
+ if (!call->HasNonSmiAssignableInterface(zone())) {
+ const intptr_t cid_0 = class_ids[0];
+ const intptr_t cid_1 = class_ids[1];
+ if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
+ class_ids[0] = cid_1;
+ } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) {
+ class_ids[1] = cid_0;
+ }
}
}
}
@@ -1696,9 +1699,9 @@
compiler::target::TypedDataBase::data_field_offset());
flow_graph_->InsertBefore(call, data, call->env(), FlowGraph::kValue);
- Definition* load = new (Z)
- LoadIndexedInstr(new (Z) Value(data), new (Z) Value(index), index_scale,
- cid, kAlignedAccess, DeoptId::kNone, call->token_pos());
+ Definition* load = new (Z) LoadIndexedInstr(
+ new (Z) Value(data), new (Z) Value(index), /*index_unboxed=*/false,
+ index_scale, cid, kAlignedAccess, DeoptId::kNone, call->token_pos());
flow_graph_->InsertBefore(call, load, call->env(), FlowGraph::kValue);
if (cid == kTypedDataFloat32ArrayCid) {
@@ -1776,8 +1779,9 @@
auto store = new (Z) StoreIndexedInstr(
new (Z) Value(data), new (Z) Value(index), new (Z) Value(value),
- kNoStoreBarrier, index_scale, cid, kAlignedAccess, DeoptId::kNone,
- call->token_pos(), Instruction::kNotSpeculative);
+ kNoStoreBarrier, /*index_unboxed=*/false, index_scale, cid,
+ kAlignedAccess, DeoptId::kNone, call->token_pos(),
+ Instruction::kNotSpeculative);
flow_graph_->InsertBefore(call, store, call->env(), FlowGraph::kEffect);
}
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index ea37001..6ee4ead 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -193,9 +193,18 @@
Value* value = Pop();
ASSERT(stack_ == nullptr);
-
- ReturnInstr* return_instr =
- new (Z) ReturnInstr(position, value, GetNextDeoptId(), yield_index);
+ const Function& function = parsed_function_->function();
+ Representation representation;
+ if (function.has_unboxed_integer_return()) {
+ representation = kUnboxedInt64;
+ } else if (function.has_unboxed_double_return()) {
+ representation = kUnboxedDouble;
+ } else {
+ ASSERT(!function.has_unboxed_return());
+ representation = kTagged;
+ }
+ ReturnInstr* return_instr = new (Z) ReturnInstr(
+ position, value, GetNextDeoptId(), yield_index, representation);
if (exit_collector_ != nullptr) exit_collector_->AddExit(return_instr);
instructions <<= return_instr;
@@ -320,23 +329,24 @@
Fragment BaseFlowGraphBuilder::LoadIndexed(intptr_t index_scale) {
Value* index = Pop();
Value* array = Pop();
- LoadIndexedInstr* instr = new (Z)
- LoadIndexedInstr(array, index, index_scale, kArrayCid, kAlignedAccess,
- DeoptId::kNone, TokenPosition::kNoSource);
+ LoadIndexedInstr* instr = new (Z) LoadIndexedInstr(
+ array, index, /*index_unboxed=*/false, index_scale, kArrayCid,
+ kAlignedAccess, DeoptId::kNone, TokenPosition::kNoSource);
Push(instr);
return Fragment(instr);
}
-Fragment BaseFlowGraphBuilder::LoadIndexedTypedData(classid_t class_id) {
+Fragment BaseFlowGraphBuilder::LoadIndexedTypedData(classid_t class_id,
+ intptr_t index_scale,
+ bool index_unboxed) {
// We use C behavior when dereferencing pointers, we assume alignment.
const AlignmentType alignment = kAlignedAccess;
- const intptr_t scale = compiler::target::Instance::ElementSizeFor(class_id);
Value* index = Pop();
Value* c_pointer = Pop();
- LoadIndexedInstr* instr =
- new (Z) LoadIndexedInstr(c_pointer, index, scale, class_id, alignment,
- DeoptId::kNone, TokenPosition::kNoSource);
+ LoadIndexedInstr* instr = new (Z)
+ LoadIndexedInstr(c_pointer, index, index_unboxed, index_scale, class_id,
+ alignment, DeoptId::kNone, TokenPosition::kNoSource);
Push(instr);
return Fragment(instr);
}
@@ -355,19 +365,25 @@
return Fragment(store);
}
-Fragment BaseFlowGraphBuilder::ConvertUntaggedToIntptr() {
+Fragment BaseFlowGraphBuilder::ConvertUntaggedToUnboxed(
+ Representation to_representation) {
+ ASSERT(to_representation == kUnboxedIntPtr ||
+ to_representation == kUnboxedFfiIntPtr);
Value* value = Pop();
auto converted = new (Z)
- IntConverterInstr(kUntagged, kUnboxedIntPtr, value, DeoptId::kNone);
+ IntConverterInstr(kUntagged, to_representation, value, DeoptId::kNone);
converted->mark_truncating();
Push(converted);
return Fragment(converted);
}
-Fragment BaseFlowGraphBuilder::ConvertIntptrToUntagged() {
+Fragment BaseFlowGraphBuilder::ConvertUnboxedToUntagged(
+ Representation from_representation) {
+ ASSERT(from_representation == kUnboxedIntPtr ||
+ from_representation == kUnboxedFfiIntPtr);
Value* value = Pop();
auto converted = new (Z)
- IntConverterInstr(kUnboxedIntPtr, kUntagged, value, DeoptId::kNone);
+ IntConverterInstr(from_representation, kUntagged, value, DeoptId::kNone);
converted->mark_truncating();
Push(converted);
return Fragment(converted);
@@ -552,23 +568,25 @@
value->BindsToConstant() ? kNoStoreBarrier : kEmitStoreBarrier;
StoreIndexedInstr* store = new (Z) StoreIndexedInstr(
Pop(), // Array.
- index, value, emit_store_barrier,
+ index, value, emit_store_barrier, /*index_unboxed=*/false,
+
compiler::target::Instance::ElementSizeFor(class_id), class_id,
kAlignedAccess, DeoptId::kNone, TokenPosition::kNoSource);
return Fragment(store);
}
-Fragment BaseFlowGraphBuilder::StoreIndexedTypedData(classid_t class_id) {
+Fragment BaseFlowGraphBuilder::StoreIndexedTypedData(classid_t class_id,
+ intptr_t index_scale,
+ bool index_unboxed) {
// We use C behavior when dereferencing pointers, we assume alignment.
const AlignmentType alignment = kAlignedAccess;
- const intptr_t scale = compiler::target::Instance::ElementSizeFor(class_id);
Value* value = Pop();
Value* index = Pop();
Value* c_pointer = Pop();
StoreIndexedInstr* instr = new (Z) StoreIndexedInstr(
- c_pointer, index, value, kNoStoreBarrier, scale, class_id, alignment,
- DeoptId::kNone, TokenPosition::kNoSource,
+ c_pointer, index, value, kNoStoreBarrier, index_unboxed, index_scale,
+ class_id, alignment, DeoptId::kNone, TokenPosition::kNoSource,
Instruction::SpeculativeMode::kNotSpeculative);
return Fragment(instr);
}
@@ -777,10 +795,12 @@
return Fragment(instr);
}
-Fragment BaseFlowGraphBuilder::LoadFpRelativeSlot(intptr_t offset,
- CompileType result_type) {
- LoadIndexedUnsafeInstr* instr =
- new (Z) LoadIndexedUnsafeInstr(Pop(), offset, result_type);
+Fragment BaseFlowGraphBuilder::LoadFpRelativeSlot(
+ intptr_t offset,
+ CompileType result_type,
+ Representation representation) {
+ LoadIndexedUnsafeInstr* instr = new (Z)
+ LoadIndexedUnsafeInstr(Pop(), offset, result_type, representation);
Push(instr);
return Fragment(instr);
}
@@ -888,6 +908,12 @@
return Fragment(allocate);
}
+Fragment BaseFlowGraphBuilder::Box(Representation from) {
+ BoxInstr* box = BoxInstr::Create(from, Pop());
+ Push(box);
+ return Fragment(box);
+}
+
Fragment BaseFlowGraphBuilder::BuildFfiAsFunctionInternalCall(
const TypeArguments& signatures) {
ASSERT(signatures.IsInstantiated());
@@ -903,8 +929,9 @@
Function::Handle(Z, Type::Cast(native_type).signature())));
Fragment code;
- code += LoadNativeField(Slot::Pointer_c_memory_address());
- LocalVariable* address = MakeTemporary();
+ // Store the pointer in the context, we cannot load the untagged address
+ // here as these can be unoptimized call sites.
+ LocalVariable* pointer = MakeTemporary();
auto& context_slots = CompilerState::Current().GetDummyContextSlots(
/*context_id=*/0, /*num_variables=*/1);
@@ -912,7 +939,7 @@
LocalVariable* context = MakeTemporary();
code += LoadLocal(context);
- code += LoadLocal(address);
+ code += LoadLocal(pointer);
code += StoreInstanceField(TokenPosition::kNoSource, *context_slots[0]);
code += AllocateClosure(TokenPosition::kNoSource, target);
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index d0612ea..4046087 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -159,12 +159,14 @@
Fragment LoadNativeField(const Slot& native_field);
Fragment LoadIndexed(intptr_t index_scale);
// Takes a [class_id] valid for StoreIndexed.
- Fragment LoadIndexedTypedData(classid_t class_id);
+ Fragment LoadIndexedTypedData(classid_t class_id,
+ intptr_t index_scale,
+ bool index_unboxed);
Fragment LoadUntagged(intptr_t offset);
Fragment StoreUntagged(intptr_t offset);
- Fragment ConvertUntaggedToIntptr();
- Fragment ConvertIntptrToUntagged();
+ Fragment ConvertUntaggedToUnboxed(Representation to);
+ Fragment ConvertUnboxedToUntagged(Representation from);
Fragment UnboxSmiToIntptr();
Fragment FloatToDouble();
Fragment DoubleToFloat();
@@ -199,7 +201,12 @@
Fragment StoreStaticField(TokenPosition position, const Field& field);
Fragment StoreIndexed(classid_t class_id);
// Takes a [class_id] valid for StoreIndexed.
- Fragment StoreIndexedTypedData(classid_t class_id);
+ Fragment StoreIndexedTypedData(classid_t class_id,
+ intptr_t index_scale,
+ bool index_unboxed);
+
+ // Sign-extends kUnboxedInt32 and zero-extends kUnboxedUint32.
+ Fragment Box(Representation from);
void Push(Definition* definition);
Definition* Peek(intptr_t depth = 0);
@@ -252,7 +259,9 @@
Fragment BinaryIntegerOp(Token::Kind op,
Representation representation,
bool is_truncating = false);
- Fragment LoadFpRelativeSlot(intptr_t offset, CompileType result_type);
+ Fragment LoadFpRelativeSlot(intptr_t offset,
+ CompileType result_type,
+ Representation representation = kTagged);
Fragment StoreFpRelativeSlot(intptr_t offset);
Fragment BranchIfTrue(TargetEntryInstr** then_entry,
TargetEntryInstr** otherwise_entry,
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index bde75d5..dda878c 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -1498,7 +1498,7 @@
const intptr_t num_type_args =
((flags & kFlagHasTypeArgs) != 0) ? reader_.ReadUInt() : 0;
if ((flags & kFlagHasNamedArgs) == 0) {
- return ArgumentsDescriptor::New(num_type_args, num_arguments);
+ return ArgumentsDescriptor::NewBoxed(num_type_args, num_arguments);
} else {
const intptr_t num_arg_names = reader_.ReadListLength();
const Array& array = Array::Handle(Z, Array::New(num_arg_names));
@@ -1507,7 +1507,8 @@
name ^= ReadObject();
array.SetAt(i, name);
}
- return ArgumentsDescriptor::New(num_type_args, num_arguments, array);
+ return ArgumentsDescriptor::NewBoxed(num_type_args, num_arguments,
+ array);
}
}
case kScript: {
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index 9706b1a..bcdb962 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -182,7 +182,7 @@
const auto& list_class =
Class::Handle(Z, corelib.LookupClassAllowPrivate(Symbols::_List()));
// Build type from the raw bytes (needs temporary translator).
- TypeTranslator type_translator(&reader, active_class_, true,
+ TypeTranslator type_translator(&reader, this, active_class_, true,
active_class_->RequireLegacyErasure());
auto& type_arguments =
TypeArguments::Handle(Z, TypeArguments::New(1, Heap::kOld));
@@ -224,7 +224,7 @@
ASSERT(klass.is_const());
instance = Instance::New(klass, Heap::kOld);
// Build type from the raw bytes (needs temporary translator).
- TypeTranslator type_translator(&reader, active_class_, true,
+ TypeTranslator type_translator(&reader, this, active_class_, true,
active_class_->RequireLegacyErasure());
const intptr_t number_of_type_arguments = reader.ReadUInt();
if (klass.NumTypeArguments() > 0) {
@@ -267,7 +267,7 @@
ASSERT(!constant.IsNull());
// Build type from the raw bytes (needs temporary translator).
- TypeTranslator type_translator(&reader, active_class_, true,
+ TypeTranslator type_translator(&reader, this, active_class_, true,
active_class_->RequireLegacyErasure());
const intptr_t number_of_type_arguments = reader.ReadUInt();
ASSERT(number_of_type_arguments > 0);
@@ -301,7 +301,7 @@
}
case kTypeLiteralConstant: {
// Build type from the raw bytes (needs temporary translator).
- TypeTranslator type_translator(&reader, active_class_, true,
+ TypeTranslator type_translator(&reader, this, active_class_, true,
active_class_->RequireLegacyErasure());
instance = type_translator.BuildType().raw();
break;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 9d7e9e8..54c2e4b 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -314,9 +314,11 @@
field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
const Tag initializer_tag = ReadTag();
if (class_field.is_late()) {
- instructions +=
- BuildLateFieldInitializer(Field::ZoneHandle(Z, class_field.raw()),
- initializer_tag == kSomething);
+ if (!is_constructor_initialized) {
+ instructions += BuildLateFieldInitializer(
+ Field::ZoneHandle(Z, class_field.raw()),
+ initializer_tag == kSomething);
+ }
} else if (initializer_tag == kSomething) {
EnterScope(field_offset);
// If this field is initialized in constructor then we can ignore the
@@ -2481,8 +2483,8 @@
// - the arguments descriptor.
const Array& args_descriptor =
- Array::Handle(Z, ArgumentsDescriptor::New(num_type_arguments,
- num_arguments, argument_names));
+ Array::Handle(Z, ArgumentsDescriptor::NewBoxed(
+ num_type_arguments, num_arguments, argument_names));
instructions += Constant(Array::ZoneHandle(Z, args_descriptor.raw()));
// - an array containing the actual arguments.
@@ -5108,6 +5110,8 @@
false, // is_method
true, // is_closure
&function_node_helper);
+ // type_translator_.SetupUnboxingInfoMetadata is not called here at the
+ // moment because closures do not have unboxed parameters and return value
function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
// Finalize function type.
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index ec67dc0..d782e5d 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -34,8 +34,11 @@
data_program_offset),
flow_graph_builder_(flow_graph_builder),
active_class_(&flow_graph_builder->active_class_),
- type_translator_(this, active_class_, /* finalize= */ true),
constant_reader_(this, active_class_),
+ type_translator_(this,
+ &constant_reader_,
+ active_class_,
+ /* finalize= */ true),
bytecode_metadata_helper_(this, active_class_),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this, &constant_reader_),
@@ -362,8 +365,8 @@
FlowGraphBuilder* flow_graph_builder_;
ActiveClass* const active_class_;
- TypeTranslator type_translator_;
ConstantReader constant_reader_;
+ TypeTranslator type_translator_;
BytecodeMetadataHelper bytecode_metadata_helper_;
DirectCallMetadataHelper direct_call_metadata_helper_;
InferredTypeMetadataHelper inferred_type_metadata_helper_;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 4712a7b..dadcf40 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -566,8 +566,7 @@
if (is_static) {
instructions += StoreStaticField(position, field);
} else {
- instructions += StoreInstanceFieldGuarded(
- field, StoreInstanceFieldInstr::Kind::kInitializing);
+ instructions += StoreInstanceFieldGuarded(field);
}
return instructions;
@@ -1215,20 +1214,20 @@
LocalVariable* arg_pointer = parsed_function_->RawParameterVariable(0);
LocalVariable* arg_offset = parsed_function_->RawParameterVariable(1);
- body += LoadLocal(arg_pointer);
- body += CheckNullOptimized(TokenPosition::kNoSource,
- String::ZoneHandle(Z, function.name()));
- body += LoadNativeField(Slot::Pointer_c_memory_address());
- body += UnboxTruncate(kUnboxedFfiIntPtr);
body += LoadLocal(arg_offset);
body += CheckNullOptimized(TokenPosition::kNoSource,
String::ZoneHandle(Z, function.name()));
+ LocalVariable* arg_offset_not_null = MakeTemporary();
+
+ body += LoadLocal(arg_pointer);
+ body += CheckNullOptimized(TokenPosition::kNoSource,
+ String::ZoneHandle(Z, function.name()));
+ // No GC from here til LoadIndexed.
+ body += LoadUntagged(compiler::target::PointerBase::data_field_offset());
+ body += LoadLocal(arg_offset_not_null);
body += UnboxTruncate(kUnboxedFfiIntPtr);
- body +=
- BinaryIntegerOp(Token::kADD, kUnboxedFfiIntPtr, /* truncate= */ true);
- body += ConvertIntptrToUntagged();
- body += IntConstant(0);
- body += LoadIndexedTypedData(typed_data_cid);
+ body += LoadIndexedTypedData(typed_data_cid, /*index_scale=*/1,
+ /*index_unboxed=*/true);
if (kind == MethodRecognizer::kFfiLoadFloat ||
kind == MethodRecognizer::kFfiLoadDouble) {
if (kind == MethodRecognizer::kFfiLoadFloat) {
@@ -1265,11 +1264,13 @@
LocalVariable* pointer = MakeTemporary();
body += LoadLocal(pointer);
body += LoadLocal(address);
- body += StoreInstanceField(TokenPosition::kNoSource,
- Slot::Pointer_c_memory_address());
+ body += UnboxTruncate(kUnboxedFfiIntPtr);
+ body += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
+ body += StoreUntagged(compiler::target::Pointer::data_field_offset());
body += DropTempsPreserveTop(1); // Drop [address] keep [pointer].
}
}
+ body += DropTempsPreserveTop(1); // Drop [arg_offset].
} break;
case MethodRecognizer::kFfiStoreInt8:
case MethodRecognizer::kFfiStoreInt16:
@@ -1329,24 +1330,27 @@
}
ASSERT(function.NumParameters() == 3);
+ body += LoadLocal(arg_offset);
+ body += CheckNullOptimized(TokenPosition::kNoSource,
+ String::ZoneHandle(Z, function.name()));
+ LocalVariable* arg_offset_not_null = MakeTemporary();
+ body += LoadLocal(arg_value);
+ body += CheckNullOptimized(TokenPosition::kNoSource,
+ String::ZoneHandle(Z, function.name()));
+ LocalVariable* arg_value_not_null = MakeTemporary();
+
body += LoadLocal(arg_pointer); // Pointer.
body += CheckNullOptimized(TokenPosition::kNoSource,
String::ZoneHandle(Z, function.name()));
- body += LoadNativeField(Slot::Pointer_c_memory_address());
+ // No GC from here til StoreIndexed.
+ body += LoadUntagged(compiler::target::PointerBase::data_field_offset());
+ body += LoadLocal(arg_offset_not_null);
body += UnboxTruncate(kUnboxedFfiIntPtr);
- body += LoadLocal(arg_offset); // Offset.
- body += CheckNullOptimized(TokenPosition::kNoSource,
- String::ZoneHandle(Z, function.name()));
- body += UnboxTruncate(kUnboxedFfiIntPtr);
- body +=
- BinaryIntegerOp(Token::kADD, kUnboxedFfiIntPtr, /* truncate= */ true);
- body += ConvertIntptrToUntagged();
- body += IntConstant(0);
- body += LoadLocal(arg_value); // Value.
- body += CheckNullOptimized(TokenPosition::kNoSource,
- String::ZoneHandle(Z, function.name()));
+ body += LoadLocal(arg_value_not_null);
if (kind == MethodRecognizer::kFfiStorePointer) {
- body += LoadNativeField(Slot::Pointer_c_memory_address());
+ // This can only be Pointer, so it is always safe to LoadUntagged.
+ body += LoadUntagged(compiler::target::Pointer::data_field_offset());
+ body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
} else if (kind == MethodRecognizer::kFfiStoreFloat ||
kind == MethodRecognizer::kFfiStoreDouble) {
body += UnboxTruncate(kUnboxedDouble);
@@ -1356,7 +1360,10 @@
} else {
body += UnboxTruncate(native_rep.AsRepresentationOverApprox(zone_));
}
- body += StoreIndexedTypedData(typed_data_cid);
+ body += StoreIndexedTypedData(typed_data_cid, /*index_scale=*/1,
+ /*index_unboxed=*/true);
+ body += Drop(); // Drop [arg_value].
+ body += Drop(); // Drop [arg_offset].
body += NullConstant();
} break;
case MethodRecognizer::kFfiFromAddress: {
@@ -1373,21 +1380,19 @@
body += LoadLocal(parsed_function_->RawParameterVariable(0)); // Address.
body += CheckNullOptimized(TokenPosition::kNoSource,
String::ZoneHandle(Z, function.name()));
-#if defined(TARGET_ARCH_IS_32_BIT)
- // Truncate to 32 bits on 32 bit architecture.
body += UnboxTruncate(kUnboxedFfiIntPtr);
- body += Box(kUnboxedFfiIntPtr);
-#endif // defined(TARGET_ARCH_IS_32_BIT)
- body += StoreInstanceField(TokenPosition::kNoSource,
- Slot::Pointer_c_memory_address(),
- StoreInstanceFieldInstr::Kind::kInitializing);
+ body += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
+ body += StoreUntagged(compiler::target::Pointer::data_field_offset());
} break;
case MethodRecognizer::kFfiGetAddress: {
ASSERT(function.NumParameters() == 1);
body += LoadLocal(parsed_function_->RawParameterVariable(0)); // Pointer.
body += CheckNullOptimized(TokenPosition::kNoSource,
String::ZoneHandle(Z, function.name()));
- body += LoadNativeField(Slot::Pointer_c_memory_address());
+ // This can only be Pointer, so it is always safe to LoadUntagged.
+ body += LoadUntagged(compiler::target::Pointer::data_field_offset());
+ body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
+ body += Box(kUnboxedFfiIntPtr);
} break;
default: {
UNREACHABLE();
@@ -1444,11 +1449,11 @@
body += LoadLocal(view_object);
body += LoadLocal(typed_data);
body += LoadUntagged(compiler::target::TypedDataBase::data_field_offset());
- body += ConvertUntaggedToIntptr();
+ body += ConvertUntaggedToUnboxed(kUnboxedIntPtr);
body += LoadLocal(offset_in_bytes);
body += UnboxSmiToIntptr();
body += AddIntptrIntegers();
- body += ConvertIntptrToUntagged();
+ body += ConvertUnboxedToUntagged(kUnboxedIntPtr);
body += StoreUntagged(compiler::target::TypedDataBase::data_field_offset());
return body;
@@ -1791,12 +1796,28 @@
return names.raw();
}
-Fragment FlowGraphBuilder::PushExplicitParameters(const Function& function) {
+Fragment FlowGraphBuilder::PushExplicitParameters(
+ const Function& function,
+ const Function& target /* = Function::null_function()*/) {
Fragment instructions;
for (intptr_t i = function.NumImplicitParameters(),
n = function.NumParameters();
i < n; ++i) {
- instructions += LoadLocal(parsed_function_->ParameterVariable(i));
+ Fragment push_param = LoadLocal(parsed_function_->ParameterVariable(i));
+ if (!target.IsNull() && target.is_unboxed_parameter_at(i)) {
+ Representation to;
+ if (target.is_unboxed_integer_parameter_at(i)) {
+ to = kUnboxedInt64;
+ } else {
+ ASSERT(target.is_unboxed_double_parameter_at(i));
+ to = kUnboxedDouble;
+ }
+ const auto unbox = UnboxInstr::Create(to, Pop(), DeoptId::kNone,
+ Instruction::kNotSpeculative);
+ Push(unbox);
+ push_param += Fragment(unbox);
+ }
+ instructions += push_param;
}
return instructions;
}
@@ -1871,7 +1892,7 @@
// it in.
const intptr_t receiver_index = descriptor.TypeArgsLen() > 0 ? 1 : 0;
body += Constant(TypeArguments::ZoneHandle(Z, TypeArguments::null()));
- body += IntConstant(receiver_index + descriptor.Count());
+ body += IntConstant(receiver_index + descriptor.Size());
body += CreateArray();
LocalVariable* array = MakeTemporary();
if (receiver_index > 0) {
@@ -1914,7 +1935,7 @@
const int kTypeArgsLen = 0;
ArgumentsDescriptor two_arguments(
- Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, 2)));
+ Array::Handle(Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, 2)));
Function& no_such_method =
Function::ZoneHandle(Z, Resolver::ResolveDynamicForReceiverClass(
Class::Handle(Z, function.Owner()),
@@ -2056,7 +2077,7 @@
if (is_implicit_closure_function && !function.is_static()) {
if (parsed_function_->has_arg_desc_var()) {
body += LoadArgDescriptor();
- body += LoadNativeField(Slot::ArgumentsDescriptor_count());
+ body += LoadNativeField(Slot::ArgumentsDescriptor_size());
body += LoadLocal(parsed_function_->current_context_var());
body += LoadNativeField(Slot::GetContextVariableSlotFor(
thread_, *parsed_function_->receiver_var()));
@@ -2096,7 +2117,7 @@
if (function.HasOptionalParameters()) {
body += LoadArgDescriptor();
- body += LoadNativeField(Slot::ArgumentsDescriptor_count());
+ body += LoadNativeField(Slot::ArgumentsDescriptor_size());
} else {
body += IntConstant(function.NumParameters());
}
@@ -2214,7 +2235,7 @@
// If there is no variable for the arguments descriptor (this function's
// signature doesn't require it), then we need to create one.
Array& args_desc = Array::ZoneHandle(
- Z, ArgumentsDescriptor::New(0, function.NumParameters()));
+ Z, ArgumentsDescriptor::NewBoxed(0, function.NumParameters()));
body += Constant(args_desc);
} else {
body += LoadArgDescriptor();
@@ -2715,8 +2736,7 @@
// Push receiver.
ASSERT(function.NumImplicitParameters() == 1);
body += LoadLocal(parsed_function_->receiver_var());
-
- body += PushExplicitParameters(function);
+ body += PushExplicitParameters(function, target);
const intptr_t argument_count = function.NumParameters();
const auto& argument_names =
@@ -2725,6 +2745,12 @@
body += StaticCall(TokenPosition::kNoSource, target, argument_count,
argument_names, ICData::kNoRebind, nullptr, type_args_len);
+ if (target.has_unboxed_integer_return()) {
+ body += Box(kUnboxedInt64);
+ } else if (target.has_unboxed_double_return()) {
+ body += Box(kUnboxedDouble);
+ }
+
// Later optimization passes assume that result of a x.[]=(...) call is not
// used. We must guarantee this invariant because violation will lead to an
// illegal IL once we replace x.[]=(...) with a sequence that does not
@@ -2756,12 +2782,6 @@
return Fragment(unbox);
}
-Fragment FlowGraphBuilder::Box(Representation from) {
- BoxInstr* box = BoxInstr::Create(from, Pop());
- Push(box);
- return Fragment(box);
-}
-
Fragment FlowGraphBuilder::NativeReturn(
const compiler::ffi::CallbackMarshaller& marshaller) {
auto* instr = new (Z) NativeReturnInstr(TokenPosition::kNoSource, Pop(),
@@ -2791,9 +2811,9 @@
LocalVariable* pointer = MakeTemporary();
code += LoadLocal(pointer);
code += LoadLocal(address);
- code += StoreInstanceField(TokenPosition::kNoSource,
- Slot::Pointer_c_memory_address(),
- StoreInstanceFieldInstr::Kind::kInitializing);
+ code += UnboxTruncate(kUnboxedFfiIntPtr);
+ code += ConvertUnboxedToUntagged(kUnboxedFfiIntPtr);
+ code += StoreUntagged(compiler::target::Pointer::data_field_offset());
code += StoreLocal(TokenPosition::kNoSource, result);
code += Drop(); // StoreLocal^
code += Drop(); // address
@@ -2841,11 +2861,13 @@
String::ZoneHandle(Z, marshaller.function_name()));
if (marshaller.IsPointer(arg_index)) {
- body += LoadNativeField(Slot::Pointer_c_memory_address());
+ // This can only be Pointer, so it is always safe to LoadUntagged.
+ body += LoadUntagged(compiler::target::Pointer::data_field_offset());
+ body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
+ } else {
+ body += UnboxTruncate(marshaller.RepInDart(arg_index));
}
- body += UnboxTruncate(marshaller.RepInDart(arg_index));
-
if (marshaller.RequiresBitCast(arg_index)) {
body += BitCast(marshaller.RepInDart(arg_index),
marshaller.RepInFfiCall(arg_index));
@@ -2889,15 +2911,18 @@
body += FfiConvertArgumentToNative(marshaller, i);
}
- // Push the function pointer, which is stored (boxed) in the first slot of the
- // context.
+ // Push the function pointer, which is stored (as Pointer object) in the
+ // first slot of the context.
body += LoadLocal(parsed_function_->ParameterVariable(0));
body += LoadNativeField(Slot::Closure_context());
body += LoadNativeField(Slot::GetContextVariableSlotFor(
thread_, *MakeImplicitClosureScope(
Z, Class::Handle(I->object_store()->ffi_pointer_class()))
->context_variables()[0]));
- body += UnboxTruncate(kUnboxedFfiIntPtr);
+
+ // This can only be Pointer, so it is always safe to LoadUntagged.
+ body += LoadUntagged(compiler::target::Pointer::data_field_offset());
+ body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
body += FfiCall(marshaller);
body += FfiConvertArgumentToDart(marshaller, compiler::ffi::kResultIndex);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 564fb8f..a61c5b1 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -71,7 +71,9 @@
RawArray* GetOptionalParameterNames(const Function& function);
// Generate fragment which pushes all explicit parameters of [function].
- Fragment PushExplicitParameters(const Function& function);
+ Fragment PushExplicitParameters(
+ const Function& function,
+ const Function& target = Function::null_function());
FlowGraph* BuildGraphOfMethodExtractor(const Function& method);
FlowGraph* BuildGraphOfNoSuchMethodDispatcher(const Function& function);
@@ -190,9 +192,6 @@
// target representation.
Fragment UnboxTruncate(Representation to);
- // Sign-extends kUnboxedInt32 and zero-extends kUnboxedUint32.
- Fragment Box(Representation from);
-
// Creates an ffi.Pointer holding a given address (TOS).
Fragment FfiPointerFromAddress(const Type& result_type);
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 90fb260..6a8b7cd 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -6,6 +6,7 @@
#include "vm/class_finalizer.h"
#include "vm/compiler/aot/precompiler.h"
+#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/frontend/constant_reader.h"
#include "vm/log.h"
#include "vm/object_store.h"
@@ -1690,7 +1691,8 @@
constant_reader_(constant_reader) {}
InferredTypeMetadata InferredTypeMetadataHelper::GetInferredType(
- intptr_t node_offset) {
+ intptr_t node_offset,
+ bool read_constant) {
const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
if (md_offset < 0) {
return InferredTypeMetadata(kDynamicCid,
@@ -1706,8 +1708,10 @@
const Object* constant_value = &Object::null_object();
if ((flags & InferredTypeMetadata::kFlagConstant) != 0) {
const intptr_t constant_offset = helper_->ReadUInt();
- constant_value = &Object::ZoneHandle(
- H.zone(), constant_reader_->ReadConstant(constant_offset));
+ if (read_constant) {
+ constant_value = &Object::ZoneHandle(
+ H.zone(), constant_reader_->ReadConstant(constant_offset));
+ }
}
if (H.IsRoot(kernel_name)) {
@@ -1854,6 +1858,39 @@
info->called_on_null = helper_->ReadByte() != 0;
}
+UnboxingInfoMetadataHelper::UnboxingInfoMetadataHelper(
+ KernelReaderHelper* helper)
+ : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
+
+UnboxingInfoMetadata* UnboxingInfoMetadataHelper::GetUnboxingInfoMetadata(
+ intptr_t node_offset) {
+ const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
+
+ if (md_offset < 0) {
+ return nullptr;
+ }
+
+ AlternativeReadingScopeWithNewData alt(&helper_->reader_,
+ &H.metadata_payloads(), md_offset);
+
+ const intptr_t num_args = helper_->ReadUInt();
+ const auto info = new (helper_->zone_) UnboxingInfoMetadata();
+ info->SetArgsCount(num_args);
+ for (intptr_t i = 0; i < num_args; i++) {
+ const auto arg_info = helper_->ReadByte();
+ assert(arg_info >= UnboxingInfoMetadata::kBoxed &&
+ arg_info < UnboxingInfoMetadata::kUnboxingCandidate);
+ info->unboxed_args_info[i] =
+ static_cast<UnboxingInfoMetadata::UnboxingInfoTag>(arg_info);
+ }
+ const auto return_info = helper_->ReadByte();
+ assert(return_info >= UnboxingInfoMetadata::kBoxed &&
+ return_info < UnboxingInfoMetadata::kUnboxingCandidate);
+ info->return_info =
+ static_cast<UnboxingInfoMetadata::UnboxingInfoTag>(return_info);
+ return info;
+}
+
intptr_t KernelReaderHelper::ReaderOffset() const {
return reader_.offset();
}
@@ -2777,13 +2814,17 @@
}
TypeTranslator::TypeTranslator(KernelReaderHelper* helper,
+ ConstantReader* constant_reader,
ActiveClass* active_class,
bool finalize,
bool apply_legacy_erasure)
: helper_(helper),
+ constant_reader_(constant_reader),
translation_helper_(helper->translation_helper_),
active_class_(active_class),
type_parameter_scope_(NULL),
+ inferred_type_metadata_helper_(helper_, constant_reader_),
+ unboxing_info_metadata_helper_(helper_),
zone_(translation_helper_.zone()),
result_(AbstractType::Handle(translation_helper_.zone())),
finalize_(finalize),
@@ -3278,6 +3319,75 @@
return type;
}
+static void SetupUnboxingInfoOfParameter(const Function& function,
+ intptr_t param_index,
+ const UnboxingInfoMetadata* metadata) {
+ const intptr_t param_pos =
+ param_index + (function.HasThisParameter() ? 1 : 0);
+
+ if (param_pos < function.maximum_unboxed_parameter_count()) {
+ switch (metadata->unboxed_args_info[param_index]) {
+ case UnboxingInfoMetadata::kUnboxedIntCandidate:
+ if (FlowGraphCompiler::SupportsUnboxedInt64()) {
+ function.set_unboxed_integer_parameter_at(param_pos);
+ }
+ break;
+ case UnboxingInfoMetadata::kUnboxedDoubleCandidate:
+ if (FlowGraphCompiler::SupportsUnboxedDoubles()) {
+ function.set_unboxed_double_parameter_at(param_pos);
+ }
+ break;
+ case UnboxingInfoMetadata::kUnboxingCandidate:
+ UNREACHABLE();
+ break;
+ case UnboxingInfoMetadata::kBoxed:
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+}
+
+void TypeTranslator::SetupUnboxingInfoMetadata(const Function& function,
+ intptr_t library_kernel_offset) {
+ const intptr_t kernel_offset =
+ function.kernel_offset() + library_kernel_offset;
+
+ const auto unboxing_info =
+ unboxing_info_metadata_helper_.GetUnboxingInfoMetadata(kernel_offset);
+
+ // TODO(dartbug.com/32292): accept unboxed parameters and return value
+ // when FLAG_use_table_dispatch == false.
+ if (FLAG_precompiled_mode && unboxing_info != nullptr &&
+ FLAG_use_table_dispatch && FLAG_use_bare_instructions) {
+ for (intptr_t i = 0; i < unboxing_info->unboxed_args_info.length(); i++) {
+ SetupUnboxingInfoOfParameter(function, i, unboxing_info);
+ }
+
+ switch (unboxing_info->return_info) {
+ case UnboxingInfoMetadata::kUnboxedIntCandidate:
+ if (FlowGraphCompiler::SupportsUnboxedInt64()) {
+ function.set_unboxed_integer_return();
+ }
+ break;
+ case UnboxingInfoMetadata::kUnboxedDoubleCandidate:
+ if (FlowGraphCompiler::SupportsUnboxedDoubles()) {
+ function.set_unboxed_double_return();
+ }
+ break;
+ case UnboxingInfoMetadata::kUnboxingCandidate:
+ UNREACHABLE();
+ break;
+ case UnboxingInfoMetadata::kBoxed:
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+}
+
void TypeTranslator::SetupFunctionParameters(
const Class& klass,
const Function& function,
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 2ece5ec..e5f6221 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -877,6 +877,8 @@
TranslationHelper& translation_helper_;
private:
+ MetadataHelper();
+
void SetMetadataMappings(intptr_t mappings_offset, intptr_t mappings_num);
void ScanMetadataMappings();
@@ -940,13 +942,15 @@
return (cid == kDynamicCid) && (flags == kFlagNullable);
}
bool IsNullable() const { return (flags & kFlagNullable) != 0; }
- bool IsInt() const { return (flags & kFlagInt) != 0; }
+ bool IsInt() const {
+ return (flags & kFlagInt) != 0 || cid == kMintCid || cid == kSmiCid;
+ }
bool IsSkipCheck() const { return (flags & kFlagSkipCheck) != 0; }
bool IsConstant() const { return (flags & kFlagConstant) != 0; }
bool ReceiverNotInt() const { return (flags & kFlagReceiverNotInt) != 0; }
CompileType ToCompileType(Zone* zone) const {
- if (IsInt()) {
+ if (IsInt() && cid == kDynamicCid) {
return CompileType::FromAbstractType(
Type::ZoneHandle(zone, Type::IntType()), IsNullable());
} else {
@@ -963,7 +967,8 @@
explicit InferredTypeMetadataHelper(KernelReaderHelper* helper,
ConstantReader* constant_reader);
- InferredTypeMetadata GetInferredType(intptr_t node_offset);
+ InferredTypeMetadata GetInferredType(intptr_t node_offset,
+ bool read_constant = true);
private:
ConstantReader* constant_reader_;
@@ -1074,6 +1079,42 @@
DISALLOW_COPY_AND_ASSIGN(TableSelectorMetadataHelper);
};
+// Information about a function regarding unboxed parameters and return value.
+class UnboxingInfoMetadata : public ZoneAllocated {
+ public:
+ enum UnboxingInfoTag {
+ kBoxed = 0,
+ kUnboxedIntCandidate = 1 << 0,
+ kUnboxedDoubleCandidate = 1 << 1,
+ kUnboxingCandidate = kUnboxedIntCandidate | kUnboxedDoubleCandidate,
+ };
+
+ UnboxingInfoMetadata() : unboxed_args_info(0) { return_info = kBoxed; }
+
+ void SetArgsCount(intptr_t num_args) {
+ ASSERT(unboxed_args_info.is_empty());
+ unboxed_args_info.SetLength(num_args);
+ unboxed_args_info.FillWith(kBoxed, 0, num_args);
+ }
+
+ GrowableArray<UnboxingInfoTag> unboxed_args_info;
+ UnboxingInfoTag return_info;
+
+ DISALLOW_COPY_AND_ASSIGN(UnboxingInfoMetadata);
+};
+
+// Helper class which provides access to unboxing information metadata.
+class UnboxingInfoMetadataHelper : public MetadataHelper {
+ public:
+ static const char* tag() { return "vm.unboxing-info.metadata"; }
+
+ explicit UnboxingInfoMetadataHelper(KernelReaderHelper* helper);
+
+ UnboxingInfoMetadata* GetUnboxingInfoMetadata(intptr_t node_offset);
+
+ DISALLOW_COPY_AND_ASSIGN(UnboxingInfoMetadataHelper);
+};
+
class KernelReaderHelper {
public:
KernelReaderHelper(Zone* zone,
@@ -1212,6 +1253,7 @@
friend class TableSelectorMetadataHelper;
friend class TypeParameterHelper;
friend class TypeTranslator;
+ friend class UnboxingInfoMetadataHelper;
friend class VariableDeclarationHelper;
friend class ObfuscationProhibitionsMetadataHelper;
friend bool NeedsDynamicInvocationForwarder(const Function& function);
@@ -1371,6 +1413,7 @@
class TypeTranslator {
public:
TypeTranslator(KernelReaderHelper* helper,
+ ConstantReader* constant_reader,
ActiveClass* active_class,
bool finalize = false,
bool apply_legacy_erasure = false);
@@ -1398,6 +1441,9 @@
FunctionNodeHelper* function_node_helper);
private:
+ void SetupUnboxingInfoMetadata(const Function& function,
+ intptr_t library_kernel_offset);
+
void BuildTypeInternal();
void BuildInterfaceType(bool simple);
void BuildFunctionType(bool simple);
@@ -1430,9 +1476,12 @@
};
KernelReaderHelper* helper_;
+ ConstantReader* constant_reader_;
TranslationHelper& translation_helper_;
ActiveClass* const active_class_;
TypeParameterScope* type_parameter_scope_;
+ InferredTypeMetadataHelper inferred_type_metadata_helper_;
+ UnboxingInfoMetadataHelper unboxing_info_metadata_helper_;
Zone* zone_;
AbstractType& result_;
bool finalize_;
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index ee1f4ee..d3367e4 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -23,10 +23,14 @@
// Returns static type of the parameter if it can be trusted (was type checked
// by caller) and dynamic otherwise.
-static CompileType ParameterType(LocalVariable* param) {
+static CompileType ParameterType(LocalVariable* param,
+ Representation representation = kTagged) {
return param->was_type_checked_by_caller()
- ? CompileType::FromAbstractType(param->type())
- : CompileType::Dynamic();
+ ? CompileType::FromAbstractType(param->type(),
+ representation == kTagged)
+ : ((representation == kTagged)
+ ? CompileType::Dynamic()
+ : CompileType::FromCid(kDynamicCid).CopyNonNullable());
}
bool PrologueBuilder::PrologueSkippableOnUncheckedEntry(
@@ -145,6 +149,9 @@
const int num_params =
num_fixed_params + num_opt_pos_params + num_opt_named_params;
ASSERT(function_.NumParameters() == num_params);
+ const intptr_t fixed_params_size =
+ FlowGraph::ParameterOffsetAt(function_, num_params, /*last_slot=*/false) -
+ num_opt_named_params - num_opt_pos_params;
// Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
// where num_pos_args is the number of positional arguments passed in.
@@ -187,13 +194,44 @@
// Copy mandatory parameters down.
intptr_t param = 0;
+ intptr_t param_offset = -1;
+
+ const auto update_param_offset = [¶m_offset](const Function& function,
+ intptr_t param_id) {
+ if (param_id < 0) {
+ // Type arguments of Factory constructor is processed with parameters
+ param_offset++;
+ return;
+ }
+
+ // update parameter offset
+ if (function.is_unboxed_integer_parameter_at(param_id)) {
+ param_offset += compiler::target::kIntSpillFactor;
+ } else if (function.is_unboxed_double_parameter_at(param_id)) {
+ param_offset += compiler::target::kDoubleSpillFactor;
+ } else {
+ ASSERT(!function.is_unboxed_parameter_at(param_id));
+ // Tagged parameters always occupy one word
+ param_offset++;
+ }
+ };
+
for (; param < num_fixed_params; ++param) {
+ const intptr_t param_index = param - (function_.IsFactory() ? 1 : 0);
+ update_param_offset(function_, param_index);
+
+ const auto representation =
+ ((param_index >= 0)
+ ? FlowGraph::ParameterRepresentationAt(function_, param_index)
+ : kTagged);
+
copy_args_prologue += LoadLocal(optional_count_var);
copy_args_prologue += LoadFpRelativeSlot(
compiler::target::kWordSize *
(compiler::target::frame_layout.param_end_from_fp +
- num_fixed_params - param),
- ParameterType(ParameterVariable(param)));
+ fixed_params_size - param_offset),
+ ParameterType(ParameterVariable(param), representation),
+ representation);
copy_args_prologue +=
StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
copy_args_prologue += Drop();
@@ -203,6 +241,9 @@
if (num_opt_pos_params > 0) {
JoinEntryInstr* next_missing = NULL;
for (intptr_t opt_param = 1; param < num_params; ++param, ++opt_param) {
+ const intptr_t param_index = param - (function_.IsFactory() ? 1 : 0);
+ update_param_offset(function_, param_index);
+
TargetEntryInstr *supplied, *missing;
copy_args_prologue += IntConstant(opt_param);
copy_args_prologue += LoadLocal(optional_count_var);
@@ -214,7 +255,7 @@
good += LoadFpRelativeSlot(
compiler::target::kWordSize *
(compiler::target::frame_layout.param_end_from_fp +
- num_fixed_params - param),
+ fixed_params_size - param_offset),
ParameterType(ParameterVariable(param)));
good += StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
good += Drop();
@@ -340,9 +381,12 @@
good += Goto(join);
}
- // We had no match, let's just load the default constant.
+ // We had no match. If the param is required, throw a NoSuchMethod error.
+ // Otherwise just load the default constant.
Fragment not_good(missing);
- {
+ if (FLAG_null_safety && function_.IsRequiredAt(opt_param_position[i])) {
+ not_good += Goto(nsm);
+ } else {
not_good += Constant(
DefaultParameterValueAt(opt_param_position[i] - num_fixed_params));
@@ -426,7 +470,7 @@
Fragment store_type_args;
store_type_args += LoadArgDescriptor();
- store_type_args += LoadNativeField(Slot::ArgumentsDescriptor_count());
+ store_type_args += LoadNativeField(Slot::ArgumentsDescriptor_size());
store_type_args += LoadFpRelativeSlot(
compiler::target::kWordSize *
(1 + compiler::target::frame_layout.param_end_from_fp),
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 23885c3..260c822 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -66,6 +66,7 @@
inferred_type_metadata_helper_(&helper_, &constant_reader_),
procedure_attributes_metadata_helper_(&helper_),
type_translator_(&helper_,
+ &constant_reader_,
&active_class_,
/*finalize=*/true) {
H.InitFromScript(helper_.script());
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index 771c086..af792ff 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -154,6 +154,29 @@
return safe_index;
}
+static Definition* CreateBoxedResultIfNeeded(BlockBuilder* builder,
+ Definition* value,
+ Representation representation) {
+ const auto& function = builder->function();
+ if (function.has_unboxed_return()) {
+ return value;
+ } else {
+ return builder->AddDefinition(
+ BoxInstr::Create(representation, new Value(value)));
+ }
+}
+
+static Definition* CreateUnboxedResultIfNeeded(BlockBuilder* builder,
+ Definition* value) {
+ const auto& function = builder->function();
+ if (function.has_unboxed_return() && value->representation() == kTagged) {
+ return builder->AddUnboxInstr(FlowGraph::ReturnRepresentationOf(function),
+ new Value(value), /* is_checked = */ true);
+ } else {
+ return value;
+ }
+}
+
static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph,
intptr_t array_cid) {
GraphEntryInstr* graph_entry = flow_graph->graph_entry();
@@ -172,9 +195,9 @@
}
Definition* result = builder.AddDefinition(new LoadIndexedInstr(
- new Value(array), new Value(index),
- target::Instance::ElementSizeFor(array_cid), // index scale
- array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+ new Value(array), new Value(index), /*index_unboxed=*/false,
+ /*index_scale=*/target::Instance::ElementSizeFor(array_cid), array_cid,
+ kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
// We don't perform [RangeAnalysis] for graph intrinsics. To inform the
// following boxing instruction about a more precise range we attach it here
@@ -204,33 +227,27 @@
switch (array_cid) {
case kTypedDataInt32ArrayCid:
case kExternalTypedDataInt32ArrayCid:
- result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedInt32, new Value(result)));
+ result = CreateBoxedResultIfNeeded(&builder, result, kUnboxedInt32);
break;
case kTypedDataUint32ArrayCid:
case kExternalTypedDataUint32ArrayCid:
- result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedUint32, new Value(result)));
+ result = CreateBoxedResultIfNeeded(&builder, result, kUnboxedUint32);
break;
case kTypedDataFloat32ArrayCid:
result = builder.AddDefinition(
new FloatToDoubleInstr(new Value(result), DeoptId::kNone));
FALL_THROUGH;
case kTypedDataFloat64ArrayCid:
- result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedDouble, new Value(result)));
+ result = CreateBoxedResultIfNeeded(&builder, result, kUnboxedDouble);
break;
case kTypedDataFloat32x4ArrayCid:
- result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedFloat32x4, new Value(result)));
+ result = CreateBoxedResultIfNeeded(&builder, result, kUnboxedFloat32x4);
break;
case kTypedDataInt32x4ArrayCid:
- result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedInt32x4, new Value(result)));
+ result = CreateBoxedResultIfNeeded(&builder, result, kUnboxedInt32x4);
break;
case kTypedDataFloat64x2ArrayCid:
- result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedFloat64x2, new Value(result)));
+ result = CreateBoxedResultIfNeeded(&builder, result, kUnboxedFloat64x2);
break;
case kArrayCid:
case kImmutableArrayCid:
@@ -243,21 +260,20 @@
case kTypedDataUint16ArrayCid:
case kExternalTypedDataUint8ArrayCid:
case kExternalTypedDataUint8ClampedArrayCid:
- result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedIntPtr, new Value(result)));
+ result = CreateBoxedResultIfNeeded(&builder, result, kUnboxedIntPtr);
break;
case kTypedDataInt64ArrayCid:
case kTypedDataUint64ArrayCid:
- result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedInt64, new Value(result)));
+ result = CreateBoxedResultIfNeeded(&builder, result, kUnboxedInt64);
break;
default:
UNREACHABLE();
break;
}
- if (clear_environment) {
+ if (result->IsBoxInteger() && clear_environment) {
result->AsBoxInteger()->ClearEnv();
}
+ result = CreateUnboxedResultIfNeeded(&builder, result);
builder.AddReturn(new Value(result));
return true;
}
@@ -362,8 +378,9 @@
RawObject::IsTypedDataClassId(array_cid));
builder.AddInstruction(new StoreIndexedInstr(
new Value(array), new Value(index), new Value(value), kNoStoreBarrier,
- target::Instance::ElementSizeFor(array_cid), // index scale
- array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+ /*index_unboxed=*/false,
+ /*index_scale=*/target::Instance::ElementSizeFor(array_cid), array_cid,
+ kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
// Return null.
Definition* null_def = builder.AddNullDefinition();
builder.AddReturn(new Value(null_def));
@@ -497,8 +514,9 @@
}
Definition* load = builder.AddDefinition(new LoadIndexedInstr(
- new Value(str), new Value(index), target::Instance::ElementSizeFor(cid),
- cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+ new Value(str), new Value(index), /*index_unboxed=*/false,
+ target::Instance::ElementSizeFor(cid), cid, kAlignedAccess,
+ DeoptId::kNone, builder.TokenPos()));
// We don't perform [RangeAnalysis] for graph intrinsics. To inform the
// following boxing instruction about a more precise range we attach it here
@@ -509,8 +527,11 @@
load->set_range(range);
Definition* result =
- builder.AddDefinition(BoxInstr::Create(kUnboxedIntPtr, new Value(load)));
- result->AsBoxInteger()->ClearEnv();
+ CreateBoxedResultIfNeeded(&builder, load, kUnboxedIntPtr);
+
+ if (result->IsBoxInteger()) {
+ result->AsBoxInteger()->ClearEnv();
+ }
builder.AddReturn(new Value(result));
return true;
@@ -560,8 +581,8 @@
Definition* unboxed_result = builder.AddDefinition(SimdOpInstr::Create(
SimdOpInstr::KindForOperator(cid, kind), new Value(left_simd),
new Value(right_simd), DeoptId::kNone));
- Definition* result =
- builder.AddDefinition(BoxInstr::Create(rep, new Value(unboxed_result)));
+ Definition* result = CreateBoxedResultIfNeeded(&builder, unboxed_result, rep);
+
builder.AddReturn(new Value(result));
return true;
}
@@ -610,15 +631,19 @@
Definition* receiver = builder.AddParameter(0, /*with_frame=*/false);
+ const auto& function = flow_graph->function();
Definition* unboxed_receiver =
- builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver),
- /* is_checked = */ true);
+ !function.is_unboxed_parameter_at(0)
+ ? builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver),
+ /* is_checked = */ true)
+ : receiver;
Definition* unboxed_result = builder.AddDefinition(
SimdOpInstr::Create(kind, new Value(unboxed_receiver), DeoptId::kNone));
- Definition* result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
+ Definition* result =
+ CreateBoxedResultIfNeeded(&builder, unboxed_result, kUnboxedDouble);
+
builder.AddReturn(new Value(result));
return true;
}
@@ -652,6 +677,8 @@
Definition* length = builder.AddDefinition(
new LoadFieldInstr(new Value(array), field, builder.TokenPos()));
+
+ length = CreateUnboxedResultIfNeeded(&builder, length);
builder.AddReturn(new Value(length));
return true;
}
@@ -695,6 +722,7 @@
new Value(array), Slot::GrowableObjectArray_data(), builder.TokenPos()));
Definition* capacity = builder.AddDefinition(new LoadFieldInstr(
new Value(backing_store), Slot::Array_length(), builder.TokenPos()));
+ capacity = CreateUnboxedResultIfNeeded(&builder, capacity);
builder.AddReturn(new Value(capacity));
return true;
}
@@ -714,9 +742,10 @@
new LoadFieldInstr(new Value(growable_array),
Slot::GrowableObjectArray_data(), builder.TokenPos()));
Definition* result = builder.AddDefinition(new LoadIndexedInstr(
- new Value(backing_store), new Value(index),
- target::Instance::ElementSizeFor(kArrayCid), // index scale
- kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+ new Value(backing_store), new Value(index), /*index_unboxed=*/false,
+ /*index_scale=*/target::Instance::ElementSizeFor(kArrayCid), kArrayCid,
+ kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+ result = CreateUnboxedResultIfNeeded(&builder, result);
builder.AddReturn(new Value(result));
return true;
}
@@ -744,8 +773,9 @@
builder.AddInstruction(new StoreIndexedInstr(
new Value(array), new Value(index), new Value(value), kEmitStoreBarrier,
- target::Instance::ElementSizeFor(kArrayCid), // index scale
- kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+ /*index_unboxed=*/false,
+ /*index_scale=*/target::Instance::ElementSizeFor(kArrayCid), kArrayCid,
+ kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
// Return null.
Definition* null_def = builder.AddNullDefinition();
builder.AddReturn(new Value(null_def));
@@ -778,9 +808,9 @@
builder.AddInstruction(new StoreIndexedInstr(
new Value(backing_store), new Value(index), new Value(value),
- kEmitStoreBarrier,
- target::Instance::ElementSizeFor(kArrayCid), // index scale
- kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+ kEmitStoreBarrier, /*index_unboxed=*/false,
+ /*index_scale=*/target::Instance::ElementSizeFor(kArrayCid), kArrayCid,
+ kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
// Return null.
Definition* null_def = builder.AddNullDefinition();
builder.AddReturn(new Value(null_def));
@@ -827,6 +857,26 @@
return true;
}
+static Definition* ConvertOrUnboxDoubleParameter(BlockBuilder* builder,
+ Definition* value,
+ intptr_t index,
+ bool is_checked) {
+ const auto& function = builder->function();
+ if (function.is_unboxed_double_parameter_at(index)) {
+ return value;
+ } else if (function.is_unboxed_integer_parameter_at(index)) {
+ if (compiler::target::kWordSize == 4) {
+ // Int64ToDoubleInstr is not implemented in 32-bit platforms
+ return nullptr;
+ }
+ auto to_double = new Int64ToDoubleInstr(new Value(value), DeoptId::kNone);
+ return builder->AddDefinition(to_double);
+ } else {
+ ASSERT(!function.is_unboxed_parameter_at(index));
+ return builder->AddUnboxInstr(kUnboxedDouble, value, is_checked);
+ }
+}
+
bool GraphIntrinsifier::Build_DoubleFlipSignBit(FlowGraph* flow_graph) {
if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
return false;
@@ -836,19 +886,22 @@
BlockBuilder builder(flow_graph, normal_entry);
Definition* receiver = builder.AddParameter(0, /*with_frame=*/false);
- Definition* unboxed_value =
- builder.AddUnboxInstr(kUnboxedDouble, new Value(receiver),
- /* is_checked = */ true);
+ Definition* unboxed_value = ConvertOrUnboxDoubleParameter(
+ &builder, receiver, 0, /* is_checked = */ true);
+ if (unboxed_value == nullptr) {
+ return false;
+ }
Definition* unboxed_result = builder.AddDefinition(new UnaryDoubleOpInstr(
Token::kNEGATE, new Value(unboxed_value), DeoptId::kNone));
- Definition* result = builder.AddDefinition(
- BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
+ Definition* result =
+ CreateBoxedResultIfNeeded(&builder, unboxed_result, kUnboxedDouble);
builder.AddReturn(new Value(result));
return true;
}
static bool BuildInvokeMathCFunction(BlockBuilder* builder,
MethodRecognizer::Kind kind,
+ FlowGraph* flow_graph,
intptr_t num_parameters = 1) {
if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
return false;
@@ -858,17 +911,19 @@
for (intptr_t i = 0; i < num_parameters; i++) {
Definition* value = builder->AddParameter(i, /*with_frame=*/false);
- Definition* unboxed_value =
- builder->AddUnboxInstr(kUnboxedDouble, value, /* is_checked = */ false);
+ Definition* unboxed_value = ConvertOrUnboxDoubleParameter(
+ builder, value, i, /* is_checked = */ false);
+ if (unboxed_value == nullptr) {
+ return false;
+ }
args->Add(new Value(unboxed_value));
}
Definition* unboxed_result =
builder->AddDefinition(new InvokeMathCFunctionInstr(
args, DeoptId::kNone, kind, builder->TokenPos()));
- Definition* result = builder->AddDefinition(
- BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
-
+ Definition* result =
+ CreateBoxedResultIfNeeded(builder, unboxed_result, kUnboxedDouble);
builder->AddReturn(new Value(result));
return true;
@@ -881,7 +936,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathSin);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathSin,
+ flow_graph);
}
bool GraphIntrinsifier::Build_MathCos(FlowGraph* flow_graph) {
@@ -891,7 +947,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathCos);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathCos,
+ flow_graph);
}
bool GraphIntrinsifier::Build_MathTan(FlowGraph* flow_graph) {
@@ -901,7 +958,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathTan);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathTan,
+ flow_graph);
}
bool GraphIntrinsifier::Build_MathAsin(FlowGraph* flow_graph) {
@@ -911,7 +969,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAsin);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAsin,
+ flow_graph);
}
bool GraphIntrinsifier::Build_MathAcos(FlowGraph* flow_graph) {
@@ -921,7 +980,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAcos);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAcos,
+ flow_graph);
}
bool GraphIntrinsifier::Build_MathAtan(FlowGraph* flow_graph) {
@@ -931,7 +991,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan,
+ flow_graph);
}
bool GraphIntrinsifier::Build_MathAtan2(FlowGraph* flow_graph) {
@@ -942,6 +1003,7 @@
BlockBuilder builder(flow_graph, normal_entry);
return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan2,
+ flow_graph,
/* num_parameters = */ 2);
}
@@ -953,6 +1015,7 @@
BlockBuilder builder(flow_graph, normal_entry);
return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleMod,
+ flow_graph,
/* num_parameters = */ 2);
}
@@ -966,7 +1029,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleCeil);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleCeil,
+ flow_graph);
}
bool GraphIntrinsifier::Build_DoubleFloor(FlowGraph* flow_graph) {
@@ -979,7 +1043,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleFloor);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleFloor,
+ flow_graph);
}
bool GraphIntrinsifier::Build_DoubleTruncate(FlowGraph* flow_graph) {
@@ -992,7 +1057,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleTruncate);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleTruncate,
+ flow_graph);
}
bool GraphIntrinsifier::Build_DoubleRound(FlowGraph* flow_graph) {
@@ -1002,7 +1068,8 @@
auto normal_entry = graph_entry->normal_entry();
BlockBuilder builder(flow_graph, normal_entry);
- return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleRound);
+ return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleRound,
+ flow_graph);
}
} // namespace compiler
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index 89995fb..99d186f 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -210,6 +210,16 @@
recognized_methods[i].enum_name,
recognized_methods[i].fp);
func.set_recognized_kind(kind);
+ switch (kind) {
+#define RECOGNIZE_METHOD(class_name, function_name, enum_name, fp) \
+ case MethodRecognizer::k##enum_name: \
+ func.reset_unboxed_parameters_and_return(); \
+ break;
+ ALL_INTRINSICS_LIST(RECOGNIZE_METHOD)
+#undef RECOGNIZE_METHOD
+ default:
+ break;
+ }
} else if (!FLAG_precompiled_mode) {
FATAL2("Missing %s::%s\n", recognized_methods[i].class_name,
recognized_methods[i].function_name);
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 072fcf4..781c353 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -300,6 +300,9 @@
// Information about frame_layout that compiler should be targeting.
extern FrameLayout frame_layout;
+constexpr intptr_t kIntSpillFactor = sizeof(int64_t) / kWordSize;
+constexpr intptr_t kDoubleSpillFactor = sizeof(double) / kWordSize;
+
// Returns the FP-relative index where [variable] can be found (assumes
// [variable] is not captured), in bytes.
inline int FrameOffsetInBytesForVariable(const LocalVariable* variable) {
@@ -514,9 +517,13 @@
static word NextFieldOffset();
};
-class TypedDataBase : public AllStatic {
+class PointerBase : public AllStatic {
public:
static word data_field_offset();
+};
+
+class TypedDataBase : public PointerBase {
+ public:
static word length_offset();
static word InstanceSize();
static word NextFieldOffset();
@@ -570,13 +577,13 @@
static word position_offset();
static word name_offset();
static word count_offset();
+ static word size_offset();
static word type_args_len_offset();
static word positional_count_offset();
};
-class Pointer : public AllStatic {
+class Pointer : public PointerBase {
public:
- static word c_memory_address_offset();
static word type_arguments_offset();
static word InstanceSize();
static word NextFieldOffset();
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 128aa14..c7b17d0 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -55,8 +55,10 @@
AbstractType_type_test_stub_entry_point_offset = 4;
static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
16;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_size_offset =
+ 20;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_first_named_entry_offset = 24;
+ ArgumentsDescriptor_first_named_entry_offset = 28;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_named_entry_size = 8;
static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
@@ -64,7 +66,7 @@
static constexpr dart::compiler::target::word
ArgumentsDescriptor_position_offset = 4;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_positional_count_offset = 20;
+ ArgumentsDescriptor_positional_count_offset = 24;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_type_args_len_offset = 12;
static constexpr dart::compiler::target::word Array_data_offset = 12;
@@ -173,9 +175,8 @@
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
140;
static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
- 8;
-static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
+static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
SingleTargetCache_entry_point_offset = 8;
static constexpr dart::compiler::target::word
@@ -350,8 +351,6 @@
static constexpr dart::compiler::target::word
TypeArguments_instantiations_offset = 4;
static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
-static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
- 4;
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
static constexpr dart::compiler::target::word TypedDataView_data_offset = 12;
static constexpr dart::compiler::target::word
@@ -410,7 +409,7 @@
static constexpr dart::compiler::target::word Field_InstanceSize = 64;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
16;
@@ -520,8 +519,10 @@
AbstractType_type_test_stub_entry_point_offset = 8;
static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
32;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_size_offset =
+ 40;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_first_named_entry_offset = 48;
+ ArgumentsDescriptor_first_named_entry_offset = 56;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_named_entry_size = 16;
static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
@@ -529,7 +530,7 @@
static constexpr dart::compiler::target::word
ArgumentsDescriptor_position_offset = 8;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_positional_count_offset = 40;
+ ArgumentsDescriptor_positional_count_offset = 48;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_type_args_len_offset = 24;
static constexpr dart::compiler::target::word Array_data_offset = 24;
@@ -638,9 +639,9 @@
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
280;
static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
+static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
+static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
16;
-static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
SingleTargetCache_entry_point_offset = 16;
static constexpr dart::compiler::target::word
@@ -817,8 +818,6 @@
static constexpr dart::compiler::target::word
TypeArguments_instantiations_offset = 8;
static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
-static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
- 8;
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
static constexpr dart::compiler::target::word
@@ -878,7 +877,7 @@
static constexpr dart::compiler::target::word Field_InstanceSize = 112;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 144;
+static constexpr dart::compiler::target::word Function_InstanceSize = 152;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
32;
@@ -987,8 +986,10 @@
AbstractType_type_test_stub_entry_point_offset = 4;
static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
16;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_size_offset =
+ 20;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_first_named_entry_offset = 24;
+ ArgumentsDescriptor_first_named_entry_offset = 28;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_named_entry_size = 8;
static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
@@ -996,7 +997,7 @@
static constexpr dart::compiler::target::word
ArgumentsDescriptor_position_offset = 4;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_positional_count_offset = 20;
+ ArgumentsDescriptor_positional_count_offset = 24;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_type_args_len_offset = 12;
static constexpr dart::compiler::target::word Array_data_offset = 12;
@@ -1105,9 +1106,8 @@
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
140;
static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
- 8;
-static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
+static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
SingleTargetCache_entry_point_offset = 8;
static constexpr dart::compiler::target::word
@@ -1282,8 +1282,6 @@
static constexpr dart::compiler::target::word
TypeArguments_instantiations_offset = 4;
static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
-static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
- 4;
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
static constexpr dart::compiler::target::word TypedDataView_data_offset = 12;
static constexpr dart::compiler::target::word
@@ -1339,7 +1337,7 @@
static constexpr dart::compiler::target::word Field_InstanceSize = 64;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
16;
@@ -1449,8 +1447,10 @@
AbstractType_type_test_stub_entry_point_offset = 8;
static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
32;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_size_offset =
+ 40;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_first_named_entry_offset = 48;
+ ArgumentsDescriptor_first_named_entry_offset = 56;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_named_entry_size = 16;
static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
@@ -1458,7 +1458,7 @@
static constexpr dart::compiler::target::word
ArgumentsDescriptor_position_offset = 8;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_positional_count_offset = 40;
+ ArgumentsDescriptor_positional_count_offset = 48;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_type_args_len_offset = 24;
static constexpr dart::compiler::target::word Array_data_offset = 24;
@@ -1567,9 +1567,9 @@
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
280;
static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
+static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
+static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
16;
-static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
SingleTargetCache_entry_point_offset = 16;
static constexpr dart::compiler::target::word
@@ -1746,8 +1746,6 @@
static constexpr dart::compiler::target::word
TypeArguments_instantiations_offset = 8;
static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
-static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
- 8;
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
static constexpr dart::compiler::target::word
@@ -1808,7 +1806,7 @@
static constexpr dart::compiler::target::word Field_InstanceSize = 112;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 144;
+static constexpr dart::compiler::target::word Function_InstanceSize = 152;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
32;
@@ -1919,8 +1917,10 @@
AbstractType_type_test_stub_entry_point_offset = 4;
static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
16;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_size_offset =
+ 20;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_first_named_entry_offset = 24;
+ ArgumentsDescriptor_first_named_entry_offset = 28;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_named_entry_size = 8;
static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
@@ -1928,7 +1928,7 @@
static constexpr dart::compiler::target::word
ArgumentsDescriptor_position_offset = 4;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_positional_count_offset = 20;
+ ArgumentsDescriptor_positional_count_offset = 24;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_type_args_len_offset = 12;
static constexpr dart::compiler::target::word Array_data_offset = 12;
@@ -2034,9 +2034,8 @@
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
140;
static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
- 8;
-static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
+static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
SingleTargetCache_entry_point_offset = 8;
static constexpr dart::compiler::target::word
@@ -2211,8 +2210,6 @@
static constexpr dart::compiler::target::word
TypeArguments_instantiations_offset = 4;
static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
-static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
- 4;
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
static constexpr dart::compiler::target::word TypedDataView_data_offset = 12;
static constexpr dart::compiler::target::word
@@ -2268,7 +2265,7 @@
static constexpr dart::compiler::target::word Field_InstanceSize = 64;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
16;
@@ -2378,8 +2375,10 @@
AbstractType_type_test_stub_entry_point_offset = 8;
static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
32;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_size_offset =
+ 40;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_first_named_entry_offset = 48;
+ ArgumentsDescriptor_first_named_entry_offset = 56;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_named_entry_size = 16;
static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
@@ -2387,7 +2386,7 @@
static constexpr dart::compiler::target::word
ArgumentsDescriptor_position_offset = 8;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_positional_count_offset = 40;
+ ArgumentsDescriptor_positional_count_offset = 48;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_type_args_len_offset = 24;
static constexpr dart::compiler::target::word Array_data_offset = 24;
@@ -2493,9 +2492,9 @@
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
280;
static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
+static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
+static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
16;
-static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
SingleTargetCache_entry_point_offset = 16;
static constexpr dart::compiler::target::word
@@ -2672,8 +2671,6 @@
static constexpr dart::compiler::target::word
TypeArguments_instantiations_offset = 8;
static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
-static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
- 8;
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
static constexpr dart::compiler::target::word
@@ -2730,7 +2727,7 @@
static constexpr dart::compiler::target::word Field_InstanceSize = 112;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 144;
+static constexpr dart::compiler::target::word Function_InstanceSize = 152;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
32;
@@ -2839,8 +2836,10 @@
AbstractType_type_test_stub_entry_point_offset = 4;
static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
16;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_size_offset =
+ 20;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_first_named_entry_offset = 24;
+ ArgumentsDescriptor_first_named_entry_offset = 28;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_named_entry_size = 8;
static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
@@ -2848,7 +2847,7 @@
static constexpr dart::compiler::target::word
ArgumentsDescriptor_position_offset = 4;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_positional_count_offset = 20;
+ ArgumentsDescriptor_positional_count_offset = 24;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_type_args_len_offset = 12;
static constexpr dart::compiler::target::word Array_data_offset = 12;
@@ -2954,9 +2953,8 @@
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
140;
static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
-static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
- 8;
-static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
+static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
SingleTargetCache_entry_point_offset = 8;
static constexpr dart::compiler::target::word
@@ -3131,8 +3129,6 @@
static constexpr dart::compiler::target::word
TypeArguments_instantiations_offset = 4;
static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
-static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
- 4;
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
static constexpr dart::compiler::target::word TypedDataView_data_offset = 12;
static constexpr dart::compiler::target::word
@@ -3185,7 +3181,7 @@
static constexpr dart::compiler::target::word Field_InstanceSize = 64;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 8;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
16;
@@ -3295,8 +3291,10 @@
AbstractType_type_test_stub_entry_point_offset = 8;
static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
32;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_size_offset =
+ 40;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_first_named_entry_offset = 48;
+ ArgumentsDescriptor_first_named_entry_offset = 56;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_named_entry_size = 16;
static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
@@ -3304,7 +3302,7 @@
static constexpr dart::compiler::target::word
ArgumentsDescriptor_position_offset = 8;
static constexpr dart::compiler::target::word
- ArgumentsDescriptor_positional_count_offset = 40;
+ ArgumentsDescriptor_positional_count_offset = 48;
static constexpr dart::compiler::target::word
ArgumentsDescriptor_type_args_len_offset = 24;
static constexpr dart::compiler::target::word Array_data_offset = 24;
@@ -3410,9 +3408,9 @@
static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
280;
static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
-static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
+static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
+static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
16;
-static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
SingleTargetCache_entry_point_offset = 16;
static constexpr dart::compiler::target::word
@@ -3589,8 +3587,6 @@
static constexpr dart::compiler::target::word
TypeArguments_instantiations_offset = 8;
static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
-static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
- 8;
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
static constexpr dart::compiler::target::word
@@ -3648,7 +3644,7 @@
static constexpr dart::compiler::target::word Field_InstanceSize = 112;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 144;
+static constexpr dart::compiler::target::word Function_InstanceSize = 152;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
32;
@@ -3766,7 +3762,9 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_count_offset = 16;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_first_named_entry_offset = 24;
+ AOT_ArgumentsDescriptor_size_offset = 20;
+static constexpr dart::compiler::target::word
+ AOT_ArgumentsDescriptor_first_named_entry_offset = 28;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_named_entry_size = 8;
static constexpr dart::compiler::target::word
@@ -3774,7 +3772,7 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_position_offset = 4;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_positional_count_offset = 20;
+ AOT_ArgumentsDescriptor_positional_count_offset = 24;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_type_args_len_offset = 12;
static constexpr dart::compiler::target::word AOT_Array_data_offset = 12;
@@ -3888,9 +3886,9 @@
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
12;
static constexpr dart::compiler::target::word
- AOT_Pointer_c_memory_address_offset = 8;
+ AOT_PointerBase_data_field_offset = 4;
static constexpr dart::compiler::target::word
- AOT_Pointer_type_arguments_offset = 4;
+ AOT_Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_entry_point_offset = 8;
static constexpr dart::compiler::target::word
@@ -4077,8 +4075,6 @@
static constexpr dart::compiler::target::word
AOT_TypeArguments_instantiations_offset = 4;
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 12;
-static constexpr dart::compiler::target::word
- AOT_TypedDataBase_data_field_offset = 4;
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
8;
static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
@@ -4274,7 +4270,9 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_count_offset = 32;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_first_named_entry_offset = 48;
+ AOT_ArgumentsDescriptor_size_offset = 40;
+static constexpr dart::compiler::target::word
+ AOT_ArgumentsDescriptor_first_named_entry_offset = 56;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_named_entry_size = 16;
static constexpr dart::compiler::target::word
@@ -4282,7 +4280,7 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_position_offset = 8;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_positional_count_offset = 40;
+ AOT_ArgumentsDescriptor_positional_count_offset = 48;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_type_args_len_offset = 24;
static constexpr dart::compiler::target::word AOT_Array_data_offset = 24;
@@ -4396,9 +4394,9 @@
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
16;
static constexpr dart::compiler::target::word
- AOT_Pointer_c_memory_address_offset = 16;
+ AOT_PointerBase_data_field_offset = 8;
static constexpr dart::compiler::target::word
- AOT_Pointer_type_arguments_offset = 8;
+ AOT_Pointer_type_arguments_offset = 16;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_entry_point_offset = 16;
static constexpr dart::compiler::target::word
@@ -4586,8 +4584,6 @@
static constexpr dart::compiler::target::word
AOT_TypeArguments_instantiations_offset = 8;
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
-static constexpr dart::compiler::target::word
- AOT_TypedDataBase_data_field_offset = 8;
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
16;
static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
@@ -4788,7 +4784,9 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_count_offset = 32;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_first_named_entry_offset = 48;
+ AOT_ArgumentsDescriptor_size_offset = 40;
+static constexpr dart::compiler::target::word
+ AOT_ArgumentsDescriptor_first_named_entry_offset = 56;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_named_entry_size = 16;
static constexpr dart::compiler::target::word
@@ -4796,7 +4794,7 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_position_offset = 8;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_positional_count_offset = 40;
+ AOT_ArgumentsDescriptor_positional_count_offset = 48;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_type_args_len_offset = 24;
static constexpr dart::compiler::target::word AOT_Array_data_offset = 24;
@@ -4910,9 +4908,9 @@
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
16;
static constexpr dart::compiler::target::word
- AOT_Pointer_c_memory_address_offset = 16;
+ AOT_PointerBase_data_field_offset = 8;
static constexpr dart::compiler::target::word
- AOT_Pointer_type_arguments_offset = 8;
+ AOT_Pointer_type_arguments_offset = 16;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_entry_point_offset = 16;
static constexpr dart::compiler::target::word
@@ -5100,8 +5098,6 @@
static constexpr dart::compiler::target::word
AOT_TypeArguments_instantiations_offset = 8;
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
-static constexpr dart::compiler::target::word
- AOT_TypedDataBase_data_field_offset = 8;
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
16;
static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
@@ -5302,7 +5298,9 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_count_offset = 16;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_first_named_entry_offset = 24;
+ AOT_ArgumentsDescriptor_size_offset = 20;
+static constexpr dart::compiler::target::word
+ AOT_ArgumentsDescriptor_first_named_entry_offset = 28;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_named_entry_size = 8;
static constexpr dart::compiler::target::word
@@ -5310,7 +5308,7 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_position_offset = 4;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_positional_count_offset = 20;
+ AOT_ArgumentsDescriptor_positional_count_offset = 24;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_type_args_len_offset = 12;
static constexpr dart::compiler::target::word AOT_Array_data_offset = 12;
@@ -5420,9 +5418,9 @@
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
12;
static constexpr dart::compiler::target::word
- AOT_Pointer_c_memory_address_offset = 8;
+ AOT_PointerBase_data_field_offset = 4;
static constexpr dart::compiler::target::word
- AOT_Pointer_type_arguments_offset = 4;
+ AOT_Pointer_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_entry_point_offset = 8;
static constexpr dart::compiler::target::word
@@ -5609,8 +5607,6 @@
static constexpr dart::compiler::target::word
AOT_TypeArguments_instantiations_offset = 4;
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 12;
-static constexpr dart::compiler::target::word
- AOT_TypedDataBase_data_field_offset = 4;
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
8;
static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
@@ -5803,7 +5799,9 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_count_offset = 32;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_first_named_entry_offset = 48;
+ AOT_ArgumentsDescriptor_size_offset = 40;
+static constexpr dart::compiler::target::word
+ AOT_ArgumentsDescriptor_first_named_entry_offset = 56;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_named_entry_size = 16;
static constexpr dart::compiler::target::word
@@ -5811,7 +5809,7 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_position_offset = 8;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_positional_count_offset = 40;
+ AOT_ArgumentsDescriptor_positional_count_offset = 48;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_type_args_len_offset = 24;
static constexpr dart::compiler::target::word AOT_Array_data_offset = 24;
@@ -5921,9 +5919,9 @@
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
16;
static constexpr dart::compiler::target::word
- AOT_Pointer_c_memory_address_offset = 16;
+ AOT_PointerBase_data_field_offset = 8;
static constexpr dart::compiler::target::word
- AOT_Pointer_type_arguments_offset = 8;
+ AOT_Pointer_type_arguments_offset = 16;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_entry_point_offset = 16;
static constexpr dart::compiler::target::word
@@ -6111,8 +6109,6 @@
static constexpr dart::compiler::target::word
AOT_TypeArguments_instantiations_offset = 8;
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
-static constexpr dart::compiler::target::word
- AOT_TypedDataBase_data_field_offset = 8;
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
16;
static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
@@ -6310,7 +6306,9 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_count_offset = 32;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_first_named_entry_offset = 48;
+ AOT_ArgumentsDescriptor_size_offset = 40;
+static constexpr dart::compiler::target::word
+ AOT_ArgumentsDescriptor_first_named_entry_offset = 56;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_named_entry_size = 16;
static constexpr dart::compiler::target::word
@@ -6318,7 +6316,7 @@
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_position_offset = 8;
static constexpr dart::compiler::target::word
- AOT_ArgumentsDescriptor_positional_count_offset = 40;
+ AOT_ArgumentsDescriptor_positional_count_offset = 48;
static constexpr dart::compiler::target::word
AOT_ArgumentsDescriptor_type_args_len_offset = 24;
static constexpr dart::compiler::target::word AOT_Array_data_offset = 24;
@@ -6428,9 +6426,9 @@
static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
16;
static constexpr dart::compiler::target::word
- AOT_Pointer_c_memory_address_offset = 16;
+ AOT_PointerBase_data_field_offset = 8;
static constexpr dart::compiler::target::word
- AOT_Pointer_type_arguments_offset = 8;
+ AOT_Pointer_type_arguments_offset = 16;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_entry_point_offset = 16;
static constexpr dart::compiler::target::word
@@ -6618,8 +6616,6 @@
static constexpr dart::compiler::target::word
AOT_TypeArguments_instantiations_offset = 8;
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
-static constexpr dart::compiler::target::word
- AOT_TypedDataBase_data_field_offset = 8;
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
16;
static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index a8b30c3..b582be9 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -51,6 +51,7 @@
CONSTANT(SubtypeTestCache, kTestResult) \
FIELD(AbstractType, type_test_stub_entry_point_offset) \
FIELD(ArgumentsDescriptor, count_offset) \
+ FIELD(ArgumentsDescriptor, size_offset) \
FIELD(ArgumentsDescriptor, first_named_entry_offset) \
FIELD(ArgumentsDescriptor, named_entry_size) \
FIELD(ArgumentsDescriptor, name_offset) \
@@ -132,7 +133,7 @@
FIELD(ObjectStore, int_type_offset) \
FIELD(ObjectStore, string_type_offset) \
FIELD(OneByteString, data_offset) \
- FIELD(Pointer, c_memory_address_offset) \
+ FIELD(PointerBase, data_field_offset) \
FIELD(Pointer, type_arguments_offset) \
FIELD(SingleTargetCache, entry_point_offset) \
FIELD(SingleTargetCache, lower_limit_offset) \
@@ -236,7 +237,6 @@
FIELD(Type, nullability_offset) \
FIELD(TypeArguments, instantiations_offset) \
FIELD(TypeRef, type_offset) \
- FIELD(TypedDataBase, data_field_offset) \
FIELD(TypedDataBase, length_offset) \
FIELD(TypedDataView, data_offset) \
FIELD(TypedDataView, offset_in_bytes_offset) \
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 289ae62..956ddd6 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -441,6 +441,7 @@
/*external=*/false,
/*array_cid=*/kArrayCid,
/*index_scale, smi-tagged=*/compiler::target::kWordSize * 2,
+ /*index_unboxed=*/false,
/*array=*/R5,
/*index=*/R4));
__ LoadFieldFromOffset(kWord, R5, R5,
@@ -972,7 +973,7 @@
__ b(call_target_function, NE);
__ EnterStubFrame();
// Load the receiver.
- __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::count_offset()));
+ __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::size_offset()));
__ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi.
__ ldr(R8, Address(IP, target::frame_layout.param_end_from_fp *
target::kWordSize));
@@ -1003,7 +1004,7 @@
__ EnterStubFrame();
// Load the receiver.
- __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::count_offset()));
+ __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::size_offset()));
__ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi.
__ ldr(R8, Address(IP, target::frame_layout.param_end_from_fp *
target::kWordSize));
@@ -1045,106 +1046,106 @@
// R2: array length as Smi (must be preserved).
// The newly allocated object is returned in R0.
void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
- Label slow_case;
- // Compute the size to be allocated, it is based on the array length
- // and is computed as:
- // RoundedAllocationSize(
- // (array_length * kwordSize) + target::Array::header_size()).
- __ mov(R3, Operand(R2)); // Array length.
- // Check that length is a positive Smi.
- __ tst(R3, Operand(kSmiTagMask));
- if (FLAG_use_slow_path) {
- __ b(&slow_case);
- } else {
+ if (!FLAG_use_slow_path) {
+ Label slow_case;
+ // Compute the size to be allocated, it is based on the array length
+ // and is computed as:
+ // RoundedAllocationSize(
+ // (array_length * kwordSize) + target::Array::header_size()).
+ __ mov(R3, Operand(R2)); // Array length.
+ // Check that length is a positive Smi.
+ __ tst(R3, Operand(kSmiTagMask));
__ b(&slow_case, NE);
+
+ __ cmp(R3, Operand(0));
+ __ b(&slow_case, LT);
+
+ // Check for maximum allowed length.
+ const intptr_t max_len =
+ target::ToRawSmi(target::Array::kMaxNewSpaceElements);
+ __ CompareImmediate(R3, max_len);
+ __ b(&slow_case, GT);
+
+ const intptr_t cid = kArrayCid;
+ NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
+ NOT_IN_PRODUCT(__ MaybeTraceAllocation(R4, &slow_case));
+
+ const intptr_t fixed_size_plus_alignment_padding =
+ target::Array::header_size() +
+ target::ObjectAlignment::kObjectAlignment - 1;
+ __ LoadImmediate(R9, fixed_size_plus_alignment_padding);
+ __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi.
+ ASSERT(kSmiTagShift == 1);
+ __ bic(R9, R9, Operand(target::ObjectAlignment::kObjectAlignment - 1));
+
+ // R9: Allocation size.
+ // Potential new object start.
+ __ ldr(R0, Address(THR, target::Thread::top_offset()));
+ __ adds(R3, R0, Operand(R9)); // Potential next object start.
+ __ b(&slow_case, CS); // Branch if unsigned overflow.
+
+ // Check if the allocation fits into the remaining space.
+ // R0: potential new object start.
+ // R3: potential next object start.
+ // R9: allocation size.
+ __ ldr(TMP, Address(THR, target::Thread::end_offset()));
+ __ cmp(R3, Operand(TMP));
+ __ b(&slow_case, CS);
+
+ // Successfully allocated the object(s), now update top to point to
+ // next object start and initialize the object.
+ __ str(R3, Address(THR, target::Thread::top_offset()));
+ __ add(R0, R0, Operand(kHeapObjectTag));
+
+ // Initialize the tags.
+ // R0: new object start as a tagged pointer.
+ // R3: new object end address.
+ // R9: allocation size.
+ {
+ const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+ target::ObjectAlignment::kObjectAlignmentLog2;
+
+ __ CompareImmediate(R9, target::RawObject::kSizeTagMaxSizeTag);
+ __ mov(R8, Operand(R9, LSL, shift), LS);
+ __ mov(R8, Operand(0), HI);
+
+ // Get the class index and insert it into the tags.
+ // R8: size and bit tags.
+ const uint32_t tags =
+ target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+ __ LoadImmediate(TMP, tags);
+ __ orr(R8, R8, Operand(TMP));
+ __ str(R8,
+ FieldAddress(R0, target::Array::tags_offset())); // Store tags.
+ }
+
+ // R0: new object start as a tagged pointer.
+ // R3: new object end address.
+ // Store the type argument field.
+ __ StoreIntoObjectNoBarrier(
+ R0, FieldAddress(R0, target::Array::type_arguments_offset()), R1);
+
+ // Set the length field.
+ __ StoreIntoObjectNoBarrier(
+ R0, FieldAddress(R0, target::Array::length_offset()), R2);
+
+ // Initialize all array elements to raw_null.
+ // R0: new object start as a tagged pointer.
+ // R8, R9: null
+ // R4: iterator which initially points to the start of the variable
+ // data area to be initialized.
+ // R3: new object end address.
+ // R9: allocation size.
+
+ __ LoadObject(R8, NullObject());
+ __ mov(R9, Operand(R8));
+ __ AddImmediate(R4, R0, target::Array::header_size() - kHeapObjectTag);
+ __ InitializeFieldsNoBarrier(R0, R4, R3, R8, R9);
+ __ Ret(); // Returns the newly allocated object in R0.
+ // Unable to allocate the array using the fast inline code, just call
+ // into the runtime.
+ __ Bind(&slow_case);
}
- __ cmp(R3, Operand(0));
- __ b(&slow_case, LT);
-
- // Check for maximum allowed length.
- const intptr_t max_len =
- target::ToRawSmi(target::Array::kMaxNewSpaceElements);
- __ CompareImmediate(R3, max_len);
- __ b(&slow_case, GT);
-
- const intptr_t cid = kArrayCid;
- NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
- NOT_IN_PRODUCT(__ MaybeTraceAllocation(R4, &slow_case));
-
- const intptr_t fixed_size_plus_alignment_padding =
- target::Array::header_size() + target::ObjectAlignment::kObjectAlignment -
- 1;
- __ LoadImmediate(R9, fixed_size_plus_alignment_padding);
- __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi.
- ASSERT(kSmiTagShift == 1);
- __ bic(R9, R9, Operand(target::ObjectAlignment::kObjectAlignment - 1));
-
- // R9: Allocation size.
- // Potential new object start.
- __ ldr(R0, Address(THR, target::Thread::top_offset()));
- __ adds(R3, R0, Operand(R9)); // Potential next object start.
- __ b(&slow_case, CS); // Branch if unsigned overflow.
-
- // Check if the allocation fits into the remaining space.
- // R0: potential new object start.
- // R3: potential next object start.
- // R9: allocation size.
- __ ldr(TMP, Address(THR, target::Thread::end_offset()));
- __ cmp(R3, Operand(TMP));
- __ b(&slow_case, CS);
-
- // Successfully allocated the object(s), now update top to point to
- // next object start and initialize the object.
- __ str(R3, Address(THR, target::Thread::top_offset()));
- __ add(R0, R0, Operand(kHeapObjectTag));
-
- // Initialize the tags.
- // R0: new object start as a tagged pointer.
- // R3: new object end address.
- // R9: allocation size.
- {
- const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
- target::ObjectAlignment::kObjectAlignmentLog2;
-
- __ CompareImmediate(R9, target::RawObject::kSizeTagMaxSizeTag);
- __ mov(R8, Operand(R9, LSL, shift), LS);
- __ mov(R8, Operand(0), HI);
-
- // Get the class index and insert it into the tags.
- // R8: size and bit tags.
- const uint32_t tags =
- target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
- __ LoadImmediate(TMP, tags);
- __ orr(R8, R8, Operand(TMP));
- __ str(R8, FieldAddress(R0, target::Array::tags_offset())); // Store tags.
- }
-
- // R0: new object start as a tagged pointer.
- // R3: new object end address.
- // Store the type argument field.
- __ StoreIntoObjectNoBarrier(
- R0, FieldAddress(R0, target::Array::type_arguments_offset()), R1);
-
- // Set the length field.
- __ StoreIntoObjectNoBarrier(
- R0, FieldAddress(R0, target::Array::length_offset()), R2);
-
- // Initialize all array elements to raw_null.
- // R0: new object start as a tagged pointer.
- // R8, R9: null
- // R4: iterator which initially points to the start of the variable
- // data area to be initialized.
- // R3: new object end address.
- // R9: allocation size.
-
- __ LoadObject(R8, NullObject());
- __ mov(R9, Operand(R8));
- __ AddImmediate(R4, R0, target::Array::header_size() - kHeapObjectTag);
- __ InitializeFieldsNoBarrier(R0, R4, R3, R8, R9);
- __ Ret(); // Returns the newly allocated object in R0.
- // Unable to allocate the array using the fast inline code, just call
- // into the runtime.
- __ Bind(&slow_case);
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
@@ -1512,11 +1513,7 @@
// R3: potential next object start.
__ ldr(IP, Address(THR, target::Thread::end_offset()));
__ cmp(R3, Operand(IP));
- if (FLAG_use_slow_path) {
- __ b(slow_case);
- } else {
- __ b(slow_case, CS); // Branch if unsigned higher or equal.
- }
+ __ b(slow_case, CS); // Branch if unsigned higher or equal.
// Successfully allocated the object, now update top to point to
// next object start and initialize the object.
@@ -1564,7 +1561,7 @@
// Clobbered:
// Potentially any since is can go to runtime.
void StubCodeCompiler::GenerateAllocateContextStub(Assembler* assembler) {
- if (FLAG_inline_alloc) {
+ if (!FLAG_use_slow_path && FLAG_inline_alloc) {
Label slow_case;
GenerateAllocateContext(assembler, &slow_case);
@@ -1916,7 +1913,7 @@
ASSERT(instance_size % target::ObjectAlignment::kObjectAlignment == 0);
__ LoadObject(kNullReg, NullObject());
- if (FLAG_inline_alloc &&
+ if (!FLAG_use_slow_path && FLAG_inline_alloc &&
target::Heap::IsAllocatableInNewSpace(instance_size) &&
!target::Class::TraceAllocation(cls)) {
Label slow_case;
@@ -1929,11 +1926,8 @@
__ ldrd(kInstanceReg, kEndReg, THR, target::Thread::top_offset());
__ AddImmediate(kEndOfInstanceReg, kInstanceReg, instance_size);
__ cmp(kEndOfInstanceReg, Operand(kEndReg));
- if (FLAG_use_slow_path) {
- __ b(&slow_case);
- } else {
- __ b(&slow_case, CS); // Unsigned higher or equal.
- }
+ __ b(&slow_case, CS); // Unsigned higher or equal.
+
__ str(kEndOfInstanceReg, Address(THR, target::Thread::top_offset()));
// Set the tags.
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 70fc396..de4c47a 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -409,6 +409,7 @@
/*external=*/false,
/*array_cid=*/kArrayCid,
/*index, smi-tagged=*/compiler::target::kWordSize * 2,
+ /*index_unboxed=*/false,
/*array=*/R9,
/*index=*/R8,
/*temp=*/TMP));
@@ -1036,7 +1037,7 @@
__ EnterStubFrame();
// Load the receiver.
- __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::count_offset());
+ __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::size_offset());
__ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi.
__ LoadFromOffset(R6, TMP,
target::frame_layout.param_end_from_fp * target::kWordSize);
@@ -1066,7 +1067,7 @@
__ EnterStubFrame();
// Load the receiver.
- __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::count_offset());
+ __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::size_offset());
__ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi.
__ LoadFromOffset(R6, TMP,
target::frame_layout.param_end_from_fp * target::kWordSize);
@@ -1115,124 +1116,124 @@
// NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
// The newly allocated object is returned in R0.
void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
- Label slow_case;
- // Compute the size to be allocated, it is based on the array length
- // and is computed as:
- // RoundedAllocationSize(
- // (array_length * kwordSize) + target::Array::header_size()).
- // Assert that length is a Smi.
- __ tsti(R2, Immediate(kSmiTagMask));
- if (FLAG_use_slow_path) {
- __ b(&slow_case);
- } else {
+ if (!FLAG_use_slow_path) {
+ Label slow_case;
+ // Compute the size to be allocated, it is based on the array length
+ // and is computed as:
+ // RoundedAllocationSize(
+ // (array_length * kwordSize) + target::Array::header_size()).
+ // Assert that length is a Smi.
+ __ tsti(R2, Immediate(kSmiTagMask));
__ b(&slow_case, NE);
+
+ __ cmp(R2, Operand(0));
+ __ b(&slow_case, LT);
+
+ // Check for maximum allowed length.
+ const intptr_t max_len =
+ target::ToRawSmi(target::Array::kMaxNewSpaceElements);
+ __ CompareImmediate(R2, max_len);
+ __ b(&slow_case, GT);
+
+ const intptr_t cid = kArrayCid;
+ NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, R4, &slow_case));
+
+ // Calculate and align allocation size.
+ // Load new object start and calculate next object start.
+ // R1: array element type.
+ // R2: array length as Smi.
+ __ ldr(R0, Address(THR, target::Thread::top_offset()));
+ intptr_t fixed_size_plus_alignment_padding =
+ target::Array::header_size() +
+ target::ObjectAlignment::kObjectAlignment - 1;
+ __ LoadImmediate(R3, fixed_size_plus_alignment_padding);
+ __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi.
+ ASSERT(kSmiTagShift == 1);
+ __ andi(R3, R3,
+ Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
+ // R0: potential new object start.
+ // R3: object size in bytes.
+ __ adds(R7, R3, Operand(R0));
+ __ b(&slow_case, CS); // Branch if unsigned overflow.
+
+ // Check if the allocation fits into the remaining space.
+ // R0: potential new object start.
+ // R1: array element type.
+ // R2: array length as Smi.
+ // R3: array size.
+ // R7: potential next object start.
+ __ LoadFromOffset(TMP, THR, target::Thread::end_offset());
+ __ CompareRegisters(R7, TMP);
+ __ b(&slow_case, CS); // Branch if unsigned higher or equal.
+
+ // Successfully allocated the object(s), now update top to point to
+ // next object start and initialize the object.
+ // R0: potential new object start.
+ // R3: array size.
+ // R7: potential next object start.
+ __ str(R7, Address(THR, target::Thread::top_offset()));
+ __ add(R0, R0, Operand(kHeapObjectTag));
+
+ // R0: new object start as a tagged pointer.
+ // R1: array element type.
+ // R2: array length as Smi.
+ // R3: array size.
+ // R7: new object end address.
+
+ // Store the type argument field.
+ __ StoreIntoObjectOffsetNoBarrier(
+ R0, target::Array::type_arguments_offset(), R1);
+
+ // Set the length field.
+ __ StoreIntoObjectOffsetNoBarrier(R0, target::Array::length_offset(), R2);
+
+ // Calculate the size tag.
+ // R0: new object start as a tagged pointer.
+ // R2: array length as Smi.
+ // R3: array size.
+ // R7: new object end address.
+ const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+ target::ObjectAlignment::kObjectAlignmentLog2;
+ __ CompareImmediate(R3, target::RawObject::kSizeTagMaxSizeTag);
+ // If no size tag overflow, shift R1 left, else set R1 to zero.
+ __ LslImmediate(TMP, R3, shift);
+ __ csel(R1, TMP, R1, LS);
+ __ csel(R1, ZR, R1, HI);
+
+ // Get the class index and insert it into the tags.
+ const uint32_t tags =
+ target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+
+ __ LoadImmediate(TMP, tags);
+ __ orr(R1, R1, Operand(TMP));
+ __ StoreFieldToOffset(R1, R0, target::Array::tags_offset());
+
+ // Initialize all array elements to raw_null.
+ // R0: new object start as a tagged pointer.
+ // R7: new object end address.
+ // R2: array length as Smi.
+ __ AddImmediate(R1, R0, target::Array::data_offset() - kHeapObjectTag);
+ // R1: iterator which initially points to the start of the variable
+ // data area to be initialized.
+ Label loop, done;
+ __ Bind(&loop);
+ // TODO(cshapiro): StoreIntoObjectNoBarrier
+ __ CompareRegisters(R1, R7);
+ __ b(&done, CS);
+ __ str(NULL_REG, Address(R1)); // Store if unsigned lower.
+ __ AddImmediate(R1, target::kWordSize);
+ __ b(&loop); // Loop until R1 == R7.
+ __ Bind(&done);
+
+ // Done allocating and initializing the array.
+ // R0: new object.
+ // R2: array length as Smi (preserved for the caller.)
+ __ ret();
+
+ // Unable to allocate the array using the fast inline code, just call
+ // into the runtime.
+ __ Bind(&slow_case);
}
- __ cmp(R2, Operand(0));
- __ b(&slow_case, LT);
-
- // Check for maximum allowed length.
- const intptr_t max_len =
- target::ToRawSmi(target::Array::kMaxNewSpaceElements);
- __ CompareImmediate(R2, max_len);
- __ b(&slow_case, GT);
-
- const intptr_t cid = kArrayCid;
- NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, R4, &slow_case));
-
- // Calculate and align allocation size.
- // Load new object start and calculate next object start.
- // R1: array element type.
- // R2: array length as Smi.
- __ ldr(R0, Address(THR, target::Thread::top_offset()));
- intptr_t fixed_size_plus_alignment_padding =
- target::Array::header_size() + target::ObjectAlignment::kObjectAlignment -
- 1;
- __ LoadImmediate(R3, fixed_size_plus_alignment_padding);
- __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi.
- ASSERT(kSmiTagShift == 1);
- __ andi(R3, R3, Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
- // R0: potential new object start.
- // R3: object size in bytes.
- __ adds(R7, R3, Operand(R0));
- __ b(&slow_case, CS); // Branch if unsigned overflow.
-
- // Check if the allocation fits into the remaining space.
- // R0: potential new object start.
- // R1: array element type.
- // R2: array length as Smi.
- // R3: array size.
- // R7: potential next object start.
- __ LoadFromOffset(TMP, THR, target::Thread::end_offset());
- __ CompareRegisters(R7, TMP);
- __ b(&slow_case, CS); // Branch if unsigned higher or equal.
-
- // Successfully allocated the object(s), now update top to point to
- // next object start and initialize the object.
- // R0: potential new object start.
- // R3: array size.
- // R7: potential next object start.
- __ str(R7, Address(THR, target::Thread::top_offset()));
- __ add(R0, R0, Operand(kHeapObjectTag));
-
- // R0: new object start as a tagged pointer.
- // R1: array element type.
- // R2: array length as Smi.
- // R3: array size.
- // R7: new object end address.
-
- // Store the type argument field.
- __ StoreIntoObjectOffsetNoBarrier(R0, target::Array::type_arguments_offset(),
- R1);
-
- // Set the length field.
- __ StoreIntoObjectOffsetNoBarrier(R0, target::Array::length_offset(), R2);
-
- // Calculate the size tag.
- // R0: new object start as a tagged pointer.
- // R2: array length as Smi.
- // R3: array size.
- // R7: new object end address.
- const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
- target::ObjectAlignment::kObjectAlignmentLog2;
- __ CompareImmediate(R3, target::RawObject::kSizeTagMaxSizeTag);
- // If no size tag overflow, shift R1 left, else set R1 to zero.
- __ LslImmediate(TMP, R3, shift);
- __ csel(R1, TMP, R1, LS);
- __ csel(R1, ZR, R1, HI);
-
- // Get the class index and insert it into the tags.
- const uint32_t tags =
- target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
-
- __ LoadImmediate(TMP, tags);
- __ orr(R1, R1, Operand(TMP));
- __ StoreFieldToOffset(R1, R0, target::Array::tags_offset());
-
- // Initialize all array elements to raw_null.
- // R0: new object start as a tagged pointer.
- // R7: new object end address.
- // R2: array length as Smi.
- __ AddImmediate(R1, R0, target::Array::data_offset() - kHeapObjectTag);
- // R1: iterator which initially points to the start of the variable
- // data area to be initialized.
- Label loop, done;
- __ Bind(&loop);
- // TODO(cshapiro): StoreIntoObjectNoBarrier
- __ CompareRegisters(R1, R7);
- __ b(&done, CS);
- __ str(NULL_REG, Address(R1)); // Store if unsigned lower.
- __ AddImmediate(R1, target::kWordSize);
- __ b(&loop); // Loop until R1 == R7.
- __ Bind(&done);
-
- // Done allocating and initializing the array.
- // R0: new object.
- // R2: array length as Smi (preserved for the caller.)
- __ ret();
-
- // Unable to allocate the array using the fast inline code, just call
- // into the runtime.
- __ Bind(&slow_case);
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame();
@@ -1612,11 +1613,7 @@
// R3: potential next object start.
__ ldr(TMP, Address(THR, target::Thread::end_offset()));
__ CompareRegisters(R3, TMP);
- if (FLAG_use_slow_path) {
- __ b(slow_case);
- } else {
- __ b(slow_case, CS); // Branch if unsigned higher or equal.
- }
+ __ b(slow_case, CS); // Branch if unsigned higher or equal.
// Successfully allocated the object, now update top to point to
// next object start and initialize the object.
@@ -1662,7 +1659,7 @@
// Clobbered:
// R2, R3, R4, TMP
void StubCodeCompiler::GenerateAllocateContextStub(Assembler* assembler) {
- if (FLAG_inline_alloc) {
+ if (!FLAG_use_slow_path && FLAG_inline_alloc) {
Label slow_case;
GenerateAllocateContextSpaceStub(assembler, &slow_case);
@@ -2105,7 +2102,7 @@
__ EnterStubFrame();
// Load the receiver.
- __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::count_offset());
+ __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::size_offset());
__ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi.
__ LoadFromOffset(R6, TMP,
target::frame_layout.param_end_from_fp * target::kWordSize);
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 92fd2ca..fbf88cc 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -258,6 +258,7 @@
/*external=*/false,
/*array_cid=*/kArrayCid,
/*index, smi-tagged=*/compiler::target::kWordSize * 2,
+ /*index_unboxed=*/false,
/*array=*/ECX,
/*index=*/EAX));
__ movl(ECX, compiler::FieldAddress(
@@ -710,7 +711,7 @@
__ j(NOT_EQUAL, call_target_function);
__ EnterStubFrame();
// Load the receiver.
- __ movl(EDI, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset()));
+ __ movl(EDI, FieldAddress(EDX, target::ArgumentsDescriptor::size_offset()));
__ movl(EAX,
Address(EBP, EDI, TIMES_HALF_WORD_SIZE,
target::frame_layout.param_end_from_fp * target::kWordSize));
@@ -743,7 +744,7 @@
__ EnterStubFrame();
// Load the receiver into EAX. The argument count in the arguments
// descriptor in EDX is a smi.
- __ movl(EAX, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset()));
+ __ movl(EAX, FieldAddress(EDX, target::ArgumentsDescriptor::size_offset()));
// Two words (saved fp, stub's pc marker) in the stack above the return
// address.
__ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * target::kWordSize));
@@ -789,114 +790,113 @@
// Assert that length is a Smi.
__ testl(EDX, Immediate(kSmiTagMask));
- if (FLAG_use_slow_path) {
- __ jmp(&slow_case);
- } else {
+ if (!FLAG_use_slow_path) {
__ j(NOT_ZERO, &slow_case);
- }
- __ cmpl(EDX, Immediate(0));
- __ j(LESS, &slow_case);
- // Check for maximum allowed length.
- const Immediate& max_len =
- Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
- __ cmpl(EDX, max_len);
- __ j(GREATER, &slow_case);
+ __ cmpl(EDX, Immediate(0));
+ __ j(LESS, &slow_case);
- NOT_IN_PRODUCT(
- __ MaybeTraceAllocation(kArrayCid, EAX, &slow_case, Assembler::kFarJump));
+ // Check for maximum allowed length.
+ const Immediate& max_len =
+ Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
+ __ cmpl(EDX, max_len);
+ __ j(GREATER, &slow_case);
- const intptr_t fixed_size_plus_alignment_padding =
- target::Array::header_size() + target::ObjectAlignment::kObjectAlignment -
- 1;
- // EDX is Smi.
- __ leal(EBX, Address(EDX, TIMES_2, fixed_size_plus_alignment_padding));
- ASSERT(kSmiTagShift == 1);
- __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
+ NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, EAX, &slow_case,
+ Assembler::kFarJump));
- // ECX: array element type.
- // EDX: array length as Smi.
- // EBX: allocation size.
+ const intptr_t fixed_size_plus_alignment_padding =
+ target::Array::header_size() +
+ target::ObjectAlignment::kObjectAlignment - 1;
+ // EDX is Smi.
+ __ leal(EBX, Address(EDX, TIMES_2, fixed_size_plus_alignment_padding));
+ ASSERT(kSmiTagShift == 1);
+ __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
- const intptr_t cid = kArrayCid;
- __ movl(EAX, Address(THR, target::Thread::top_offset()));
- __ addl(EBX, EAX);
- __ j(CARRY, &slow_case);
+ // ECX: array element type.
+ // EDX: array length as Smi.
+ // EBX: allocation size.
- // Check if the allocation fits into the remaining space.
- // EAX: potential new object start.
- // EBX: potential next object start.
- // ECX: array element type.
- // EDX: array length as Smi).
- __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
- __ j(ABOVE_EQUAL, &slow_case);
+ const intptr_t cid = kArrayCid;
+ __ movl(EAX, Address(THR, target::Thread::top_offset()));
+ __ addl(EBX, EAX);
+ __ j(CARRY, &slow_case);
- // Successfully allocated the object(s), now update top to point to
- // next object start and initialize the object.
- __ movl(Address(THR, target::Thread::top_offset()), EBX);
- __ subl(EBX, EAX);
- __ addl(EAX, Immediate(kHeapObjectTag));
+ // Check if the allocation fits into the remaining space.
+ // EAX: potential new object start.
+ // EBX: potential next object start.
+ // ECX: array element type.
+ // EDX: array length as Smi).
+ __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
+ __ j(ABOVE_EQUAL, &slow_case);
- // Initialize the tags.
- // EAX: new object start as a tagged pointer.
- // EBX: allocation size.
- // ECX: array element type.
- // EDX: array length as Smi.
- {
- Label size_tag_overflow, done;
- __ movl(EDI, EBX);
- __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
- __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
- target::ObjectAlignment::kObjectAlignmentLog2));
- __ jmp(&done, Assembler::kNearJump);
+ // Successfully allocated the object(s), now update top to point to
+ // next object start and initialize the object.
+ __ movl(Address(THR, target::Thread::top_offset()), EBX);
+ __ subl(EBX, EAX);
+ __ addl(EAX, Immediate(kHeapObjectTag));
- __ Bind(&size_tag_overflow);
- __ movl(EDI, Immediate(0));
+ // Initialize the tags.
+ // EAX: new object start as a tagged pointer.
+ // EBX: allocation size.
+ // ECX: array element type.
+ // EDX: array length as Smi.
+ {
+ Label size_tag_overflow, done;
+ __ movl(EDI, EBX);
+ __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+ __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ target::ObjectAlignment::kObjectAlignmentLog2));
+ __ jmp(&done, Assembler::kNearJump);
+
+ __ Bind(&size_tag_overflow);
+ __ movl(EDI, Immediate(0));
+ __ Bind(&done);
+
+ // Get the class index and insert it into the tags.
+ uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
+ __ orl(EDI, Immediate(tags));
+ __ movl(FieldAddress(EAX, target::Object::tags_offset()), EDI); // Tags.
+ }
+ // EAX: new object start as a tagged pointer.
+ // EBX: allocation size.
+ // ECX: array element type.
+ // EDX: Array length as Smi (preserved).
+ // Store the type argument field.
+ // No generational barrier needed, since we store into a new object.
+ __ StoreIntoObjectNoBarrier(
+ EAX, FieldAddress(EAX, target::Array::type_arguments_offset()), ECX);
+
+ // Set the length field.
+ __ StoreIntoObjectNoBarrier(
+ EAX, FieldAddress(EAX, target::Array::length_offset()), EDX);
+
+ // Initialize all array elements to raw_null.
+ // EAX: new object start as a tagged pointer.
+ // EBX: allocation size.
+ // EDI: iterator which initially points to the start of the variable
+ // data area to be initialized.
+ // ECX: array element type.
+ // EDX: array length as Smi.
+ __ leal(EBX, FieldAddress(EAX, EBX, TIMES_1, 0));
+ __ leal(EDI, FieldAddress(EAX, target::Array::header_size()));
+ Label done;
+ Label init_loop;
+ __ Bind(&init_loop);
+ __ cmpl(EDI, EBX);
+ __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
+ // No generational barrier needed, since we are storing null.
+ __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), NullObject());
+ __ addl(EDI, Immediate(target::kWordSize));
+ __ jmp(&init_loop, Assembler::kNearJump);
__ Bind(&done);
+ __ ret(); // returns the newly allocated object in EAX.
- // Get the class index and insert it into the tags.
- uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
- __ orl(EDI, Immediate(tags));
- __ movl(FieldAddress(EAX, target::Object::tags_offset()), EDI); // Tags.
+ // Unable to allocate the array using the fast inline code, just call
+ // into the runtime.
+ __ Bind(&slow_case);
}
- // EAX: new object start as a tagged pointer.
- // EBX: allocation size.
- // ECX: array element type.
- // EDX: Array length as Smi (preserved).
- // Store the type argument field.
- // No generational barrier needed, since we store into a new object.
- __ StoreIntoObjectNoBarrier(
- EAX, FieldAddress(EAX, target::Array::type_arguments_offset()), ECX);
-
- // Set the length field.
- __ StoreIntoObjectNoBarrier(
- EAX, FieldAddress(EAX, target::Array::length_offset()), EDX);
-
- // Initialize all array elements to raw_null.
- // EAX: new object start as a tagged pointer.
- // EBX: allocation size.
- // EDI: iterator which initially points to the start of the variable
- // data area to be initialized.
- // ECX: array element type.
- // EDX: array length as Smi.
- __ leal(EBX, FieldAddress(EAX, EBX, TIMES_1, 0));
- __ leal(EDI, FieldAddress(EAX, target::Array::header_size()));
- Label done;
- Label init_loop;
- __ Bind(&init_loop);
- __ cmpl(EDI, EBX);
- __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
- // No generational barrier needed, since we are storing null.
- __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), NullObject());
- __ addl(EDI, Immediate(target::kWordSize));
- __ jmp(&init_loop, Assembler::kNearJump);
- __ Bind(&done);
- __ ret(); // returns the newly allocated object in EAX.
-
- // Unable to allocate the array using the fast inline code, just call
- // into the runtime.
- __ Bind(&slow_case);
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame();
@@ -1197,53 +1197,49 @@
// EBX: potential next object start.
// EDX: number of context variables.
__ cmpl(EBX, Address(THR, target::Thread::end_offset()));
- if (FLAG_use_slow_path) {
- __ jmp(slow_case);
- } else {
#if defined(DEBUG)
static const bool kJumpLength = Assembler::kFarJump;
#else
static const bool kJumpLength = Assembler::kNearJump;
#endif // DEBUG
__ j(ABOVE_EQUAL, slow_case, kJumpLength);
- }
- // Successfully allocated the object, now update top to point to
- // next object start and initialize the object.
- // EAX: new object.
- // EBX: next object start.
- // EDX: number of context variables.
- __ movl(Address(THR, target::Thread::top_offset()), EBX);
- // EBX: Size of allocation in bytes.
- __ subl(EBX, EAX);
- __ addl(EAX, Immediate(kHeapObjectTag));
- // Generate isolate-independent code to allow sharing between isolates.
+ // Successfully allocated the object, now update top to point to
+ // next object start and initialize the object.
+ // EAX: new object.
+ // EBX: next object start.
+ // EDX: number of context variables.
+ __ movl(Address(THR, target::Thread::top_offset()), EBX);
+ // EBX: Size of allocation in bytes.
+ __ subl(EBX, EAX);
+ __ addl(EAX, Immediate(kHeapObjectTag));
+ // Generate isolate-independent code to allow sharing between isolates.
- // Calculate the size tag.
- // EAX: new object.
- // EDX: number of context variables.
- {
- Label size_tag_overflow, done;
- __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
- __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
- __ cmpl(EBX, Immediate(target::RawObject::kSizeTagMaxSizeTag));
- __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shll(EBX, Immediate(target::RawObject::kTagBitsSizeTagPos -
- target::ObjectAlignment::kObjectAlignmentLog2));
- __ jmp(&done);
-
- __ Bind(&size_tag_overflow);
- // Set overflow size tag value.
- __ movl(EBX, Immediate(0));
-
- __ Bind(&done);
+ // Calculate the size tag.
// EAX: new object.
// EDX: number of context variables.
- // EBX: size and bit tags.
- uint32_t tags = target::MakeTagWordForNewSpaceObject(kContextCid, 0);
- __ orl(EBX, Immediate(tags));
- __ movl(FieldAddress(EAX, target::Object::tags_offset()), EBX); // Tags.
- }
+ {
+ Label size_tag_overflow, done;
+ __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
+ __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
+ __ cmpl(EBX, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+ __ shll(EBX, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ target::ObjectAlignment::kObjectAlignmentLog2));
+ __ jmp(&done);
+
+ __ Bind(&size_tag_overflow);
+ // Set overflow size tag value.
+ __ movl(EBX, Immediate(0));
+
+ __ Bind(&done);
+ // EAX: new object.
+ // EDX: number of context variables.
+ // EBX: size and bit tags.
+ uint32_t tags = target::MakeTagWordForNewSpaceObject(kContextCid, 0);
+ __ orl(EBX, Immediate(tags));
+ __ movl(FieldAddress(EAX, target::Object::tags_offset()), EBX); // Tags.
+ }
// Setup up number of context variables field.
// EAX: new object.
@@ -1259,7 +1255,7 @@
// Clobbered:
// EBX, EDX
void StubCodeCompiler::GenerateAllocateContextStub(Assembler* assembler) {
- if (FLAG_inline_alloc) {
+ if (!FLAG_use_slow_path && FLAG_inline_alloc) {
Label slow_case;
GenerateAllocateContextSpaceStub(assembler, &slow_case);
@@ -1558,7 +1554,7 @@
static_assert(kAllocationStubTypeArgumentsReg == EDX,
"Adjust register allocation in the AllocationStub");
- if (FLAG_inline_alloc &&
+ if (!FLAG_use_slow_path && FLAG_inline_alloc &&
target::Heap::IsAllocatableInNewSpace(instance_size) &&
!target::Class::TraceAllocation(cls)) {
Label slow_case;
@@ -1571,11 +1567,7 @@
// EAX: potential new object start.
// EBX: potential next object start.
__ cmpl(EBX, Address(THR, target::Thread::end_offset()));
- if (FLAG_use_slow_path) {
- __ jmp(&slow_case);
- } else {
- __ j(ABOVE_EQUAL, &slow_case);
- }
+ __ j(ABOVE_EQUAL, &slow_case);
__ movl(Address(THR, target::Thread::top_offset()), EBX);
// EAX: new object start (untagged).
@@ -1678,7 +1670,7 @@
__ EnterStubFrame();
// Load the receiver.
- __ movl(EDI, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset()));
+ __ movl(EDI, FieldAddress(EDX, target::ArgumentsDescriptor::size_offset()));
__ movl(EAX,
Address(EBP, EDI, TIMES_2,
target::frame_layout.param_end_from_fp * target::kWordSize));
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 78a14c5..64f9f0d 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -342,6 +342,7 @@
/*external=*/false,
/*array_cid=*/kArrayCid,
/*index, smi-tagged=*/compiler::target::kWordSize * 2,
+ /*index_unboxed=*/false,
/*array=*/TMP,
/*index=*/RAX));
__ movq(TMP, compiler::FieldAddress(
@@ -954,7 +955,7 @@
__ j(NOT_EQUAL, call_target_function);
__ EnterStubFrame();
// Load the receiver.
- __ movq(RDI, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+ __ movq(RDI, FieldAddress(R10, target::ArgumentsDescriptor::size_offset()));
__ movq(RAX,
Address(RBP, RDI, TIMES_HALF_WORD_SIZE,
target::frame_layout.param_end_from_fp * target::kWordSize));
@@ -987,7 +988,7 @@
__ EnterStubFrame();
// Load the receiver into RAX. The argument count in the arguments
// descriptor in R10 is a smi.
- __ movq(RAX, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+ __ movq(RAX, FieldAddress(R10, target::ArgumentsDescriptor::size_offset()));
// Three words (saved pp, saved fp, stub's pc marker)
// in the stack above the return address.
__ movq(RAX,
@@ -1029,117 +1030,116 @@
// NOTE: R10 cannot be clobbered here as the caller relies on it being saved.
// The newly allocated object is returned in RAX.
void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
- Label slow_case;
- // Compute the size to be allocated, it is based on the array length
- // and is computed as:
- // RoundedAllocationSize(
- // (array_length * target::kwordSize) + target::Array::header_size()).
- __ movq(RDI, R10); // Array Length.
- // Check that length is a positive Smi.
- __ testq(RDI, Immediate(kSmiTagMask));
- if (FLAG_use_slow_path) {
- __ jmp(&slow_case);
- } else {
+ if (!FLAG_use_slow_path) {
+ Label slow_case;
+ // Compute the size to be allocated, it is based on the array length
+ // and is computed as:
+ // RoundedAllocationSize(
+ // (array_length * target::kwordSize) + target::Array::header_size()).
+ __ movq(RDI, R10); // Array Length.
+ // Check that length is a positive Smi.
+ __ testq(RDI, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &slow_case);
- }
- __ cmpq(RDI, Immediate(0));
- __ j(LESS, &slow_case);
- // Check for maximum allowed length.
- const Immediate& max_len =
- Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
- __ cmpq(RDI, max_len);
- __ j(GREATER, &slow_case);
- // Check for allocation tracing.
- NOT_IN_PRODUCT(
- __ MaybeTraceAllocation(kArrayCid, &slow_case, Assembler::kFarJump));
+ __ cmpq(RDI, Immediate(0));
+ __ j(LESS, &slow_case);
+ // Check for maximum allowed length.
+ const Immediate& max_len =
+ Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
+ __ cmpq(RDI, max_len);
+ __ j(GREATER, &slow_case);
- const intptr_t fixed_size_plus_alignment_padding =
- target::Array::header_size() + target::ObjectAlignment::kObjectAlignment -
- 1;
- // RDI is a Smi.
- __ leaq(RDI, Address(RDI, TIMES_4, fixed_size_plus_alignment_padding));
- ASSERT(kSmiTagShift == 1);
- __ andq(RDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
+ // Check for allocation tracing.
+ NOT_IN_PRODUCT(
+ __ MaybeTraceAllocation(kArrayCid, &slow_case, Assembler::kFarJump));
- const intptr_t cid = kArrayCid;
- __ movq(RAX, Address(THR, target::Thread::top_offset()));
+ const intptr_t fixed_size_plus_alignment_padding =
+ target::Array::header_size() +
+ target::ObjectAlignment::kObjectAlignment - 1;
+ // RDI is a Smi.
+ __ leaq(RDI, Address(RDI, TIMES_4, fixed_size_plus_alignment_padding));
+ ASSERT(kSmiTagShift == 1);
+ __ andq(RDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
- // RDI: allocation size.
- __ movq(RCX, RAX);
- __ addq(RCX, RDI);
- __ j(CARRY, &slow_case);
+ const intptr_t cid = kArrayCid;
+ __ movq(RAX, Address(THR, target::Thread::top_offset()));
- // Check if the allocation fits into the remaining space.
- // RAX: potential new object start.
- // RCX: potential next object start.
- // RDI: allocation size.
- __ cmpq(RCX, Address(THR, target::Thread::end_offset()));
- __ j(ABOVE_EQUAL, &slow_case);
+ // RDI: allocation size.
+ __ movq(RCX, RAX);
+ __ addq(RCX, RDI);
+ __ j(CARRY, &slow_case);
- // Successfully allocated the object(s), now update top to point to
- // next object start and initialize the object.
- __ movq(Address(THR, target::Thread::top_offset()), RCX);
- __ addq(RAX, Immediate(kHeapObjectTag));
+ // Check if the allocation fits into the remaining space.
+ // RAX: potential new object start.
+ // RCX: potential next object start.
+ // RDI: allocation size.
+ __ cmpq(RCX, Address(THR, target::Thread::end_offset()));
+ __ j(ABOVE_EQUAL, &slow_case);
- // Initialize the tags.
- // RAX: new object start as a tagged pointer.
- // RDI: allocation size.
- {
- Label size_tag_overflow, done;
- __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
- __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
- __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
- target::ObjectAlignment::kObjectAlignmentLog2));
- __ jmp(&done, Assembler::kNearJump);
+ // Successfully allocated the object(s), now update top to point to
+ // next object start and initialize the object.
+ __ movq(Address(THR, target::Thread::top_offset()), RCX);
+ __ addq(RAX, Immediate(kHeapObjectTag));
- __ Bind(&size_tag_overflow);
- __ LoadImmediate(RDI, Immediate(0));
- __ Bind(&done);
+ // Initialize the tags.
+ // RAX: new object start as a tagged pointer.
+ // RDI: allocation size.
+ {
+ Label size_tag_overflow, done;
+ __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+ __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+ __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+ target::ObjectAlignment::kObjectAlignmentLog2));
+ __ jmp(&done, Assembler::kNearJump);
- // Get the class index and insert it into the tags.
- uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
- __ orq(RDI, Immediate(tags));
- __ movq(FieldAddress(RAX, target::Array::tags_offset()), RDI); // Tags.
- }
+ __ Bind(&size_tag_overflow);
+ __ LoadImmediate(RDI, Immediate(0));
+ __ Bind(&done);
- // RAX: new object start as a tagged pointer.
- // Store the type argument field.
- // No generational barrier needed, since we store into a new object.
- __ StoreIntoObjectNoBarrier(
- RAX, FieldAddress(RAX, target::Array::type_arguments_offset()), RBX);
+ // Get the class index and insert it into the tags.
+ uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
+ __ orq(RDI, Immediate(tags));
+ __ movq(FieldAddress(RAX, target::Array::tags_offset()), RDI); // Tags.
+ }
- // Set the length field.
- __ StoreIntoObjectNoBarrier(
- RAX, FieldAddress(RAX, target::Array::length_offset()), R10);
+ // RAX: new object start as a tagged pointer.
+ // Store the type argument field.
+ // No generational barrier needed, since we store into a new object.
+ __ StoreIntoObjectNoBarrier(
+ RAX, FieldAddress(RAX, target::Array::type_arguments_offset()), RBX);
- // Initialize all array elements to raw_null.
- // RAX: new object start as a tagged pointer.
- // RCX: new object end address.
- // RDI: iterator which initially points to the start of the variable
- // data area to be initialized.
- __ LoadObject(R12, NullObject());
- __ leaq(RDI, FieldAddress(RAX, target::Array::header_size()));
- Label done;
- Label init_loop;
- __ Bind(&init_loop);
- __ cmpq(RDI, RCX);
+ // Set the length field.
+ __ StoreIntoObjectNoBarrier(
+ RAX, FieldAddress(RAX, target::Array::length_offset()), R10);
+
+ // Initialize all array elements to raw_null.
+ // RAX: new object start as a tagged pointer.
+ // RCX: new object end address.
+ // RDI: iterator which initially points to the start of the variable
+ // data area to be initialized.
+ __ LoadObject(R12, NullObject());
+ __ leaq(RDI, FieldAddress(RAX, target::Array::header_size()));
+ Label done;
+ Label init_loop;
+ __ Bind(&init_loop);
+ __ cmpq(RDI, RCX);
#if defined(DEBUG)
- static const bool kJumpLength = Assembler::kFarJump;
+ static const bool kJumpLength = Assembler::kFarJump;
#else
- static const bool kJumpLength = Assembler::kNearJump;
+ static const bool kJumpLength = Assembler::kNearJump;
#endif // DEBUG
- __ j(ABOVE_EQUAL, &done, kJumpLength);
- // No generational barrier needed, since we are storing null.
- __ StoreIntoObjectNoBarrier(RAX, Address(RDI, 0), R12);
- __ addq(RDI, Immediate(target::kWordSize));
- __ jmp(&init_loop, kJumpLength);
- __ Bind(&done);
- __ ret(); // returns the newly allocated object in RAX.
+ __ j(ABOVE_EQUAL, &done, kJumpLength);
+ // No generational barrier needed, since we are storing null.
+ __ StoreIntoObjectNoBarrier(RAX, Address(RDI, 0), R12);
+ __ addq(RDI, Immediate(target::kWordSize));
+ __ jmp(&init_loop, kJumpLength);
+ __ Bind(&done);
+ __ ret(); // returns the newly allocated object in RAX.
- // Unable to allocate the array using the fast inline code, just call
- // into the runtime.
- __ Bind(&slow_case);
+ // Unable to allocate the array using the fast inline code, just call
+ // into the runtime.
+ __ Bind(&slow_case);
+ }
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame();
@@ -1505,11 +1505,7 @@
// R13: potential next object start.
// R10: number of context variables.
__ cmpq(R13, Address(THR, target::Thread::end_offset()));
- if (FLAG_use_slow_path) {
- __ jmp(slow_case);
- } else {
- __ j(ABOVE_EQUAL, slow_case);
- }
+ __ j(ABOVE_EQUAL, slow_case);
// Successfully allocated the object, now update top to point to
// next object start and initialize the object.
@@ -1563,7 +1559,7 @@
// R9, R13
void StubCodeCompiler::GenerateAllocateContextStub(Assembler* assembler) {
__ LoadObject(R9, NullObject());
- if (FLAG_inline_alloc) {
+ if (!FLAG_use_slow_path && FLAG_inline_alloc) {
Label slow_case;
GenerateAllocateContextSpaceStub(assembler, &slow_case);
@@ -1907,7 +1903,7 @@
static_assert(kAllocationStubTypeArgumentsReg == RDX,
"Adjust register allocation in the AllocationStub");
- if (FLAG_inline_alloc &&
+ if (!FLAG_use_slow_path && FLAG_inline_alloc &&
target::Heap::IsAllocatableInNewSpace(instance_size) &&
!target::Class::TraceAllocation(cls)) {
Label slow_case;
@@ -1920,11 +1916,8 @@
// RAX: potential new object start.
// RBX: potential next object start.
__ cmpq(RBX, Address(THR, target::Thread::end_offset()));
- if (FLAG_use_slow_path) {
- __ jmp(&slow_case);
- } else {
- __ j(ABOVE_EQUAL, &slow_case);
- }
+ __ j(ABOVE_EQUAL, &slow_case);
+
__ movq(Address(THR, target::Thread::top_offset()), RBX);
// RAX: new object start (untagged).
@@ -2031,7 +2024,7 @@
__ EnterStubFrame();
// Load the receiver.
- __ movq(R13, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+ __ movq(R13, FieldAddress(R10, target::ArgumentsDescriptor::size_offset()));
__ movq(RAX,
Address(RBP, R13, TIMES_4,
target::frame_layout.param_end_from_fp * target::kWordSize));
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 4457370..992075f 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -151,6 +151,11 @@
TIMES_2 = 1,
TIMES_4 = 2,
TIMES_8 = 3,
+ // Note that Intel addressing does not support this addressing.
+ // > Scale factor — A value of 2, 4, or 8 that is multiplied by the index
+ // > value.
+ // https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4
+ // 3.7.5 Specifying an Offset
TIMES_16 = 4,
TIMES_HALF_WORD_SIZE = kWordSizeLog2 - 1
};
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 3ee28fd..498e600 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -295,7 +295,7 @@
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 1;
ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
+ Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
const Function& function =
Function::Handle(Resolver::ResolveDynamic(receiver, selector, args_desc));
if (function.IsNull()) {
@@ -312,7 +312,7 @@
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 2;
ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
+ Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
const Function& function =
Function::Handle(Resolver::ResolveDynamic(receiver, selector, args_desc));
if (function.IsNull()) {
@@ -430,6 +430,10 @@
return reinterpret_cast<Dart_Isolate>(isolate);
}
+Dart_IsolateGroup Api::CastIsolateGroup(IsolateGroup* isolate_group) {
+ return reinterpret_cast<Dart_IsolateGroup>(isolate_group);
+}
+
Dart_Handle Api::NewError(const char* format, ...) {
Thread* T = Thread::Current();
CHECK_API_SCOPE(T);
@@ -994,11 +998,12 @@
}
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object) {
- Isolate* isolate = Isolate::Current();
- CHECK_ISOLATE(isolate);
+ IsolateGroup* isolate_group = IsolateGroup::Current();
+ CHECK_ISOLATE_GROUP(isolate_group);
NoSafepointScope no_safepoint_scope;
- ApiState* state = isolate->group()->api_state();
+ ApiState* state = isolate_group->api_state();
ASSERT(state != NULL);
+ ASSERT(state->IsActivePersistentHandle(object));
PersistentHandle* ref = PersistentHandle::Cast(object);
ASSERT(!state->IsProtectedHandle(ref));
if (!state->IsProtectedHandle(ref)) {
@@ -1007,16 +1012,15 @@
}
DART_EXPORT void Dart_DeleteWeakPersistentHandle(
- Dart_Isolate current_isolate,
Dart_WeakPersistentHandle object) {
- Isolate* isolate = reinterpret_cast<Isolate*>(current_isolate);
- CHECK_ISOLATE(isolate);
+ IsolateGroup* isolate_group = IsolateGroup::Current();
+ CHECK_ISOLATE_GROUP(isolate_group);
NoSafepointScope no_safepoint_scope;
- ASSERT(isolate == Isolate::Current());
- ApiState* state = isolate->group()->api_state();
+ ApiState* state = isolate_group->api_state();
ASSERT(state != NULL);
+ ASSERT(state->IsActiveWeakPersistentHandle(object));
auto weak_ref = FinalizablePersistentHandle::Cast(object);
- weak_ref->EnsureFreeExternal(isolate->group());
+ weak_ref->EnsureFreeExternal(isolate_group);
state->FreeWeakPersistentHandle(weak_ref);
}
@@ -1469,11 +1473,15 @@
return reinterpret_cast<Isolate*>(isolate)->init_callback_data();
}
+DART_EXPORT Dart_IsolateGroup Dart_CurrentIsolateGroup() {
+ return Api::CastIsolateGroup(IsolateGroup::Current());
+}
+
DART_EXPORT void* Dart_CurrentIsolateGroupData() {
- Isolate* isolate = Isolate::Current();
- CHECK_ISOLATE(isolate);
+ IsolateGroup* isolate_group = IsolateGroup::Current();
+ CHECK_ISOLATE_GROUP(isolate_group);
NoSafepointScope no_safepoint_scope;
- return isolate->group()->embedder_data();
+ return isolate_group->embedder_data();
}
DART_EXPORT void* Dart_IsolateGroupData(Dart_Isolate isolate) {
@@ -3111,7 +3119,7 @@
const int kTypeArgsLen = 0;
const int kNumArgs = 1;
ArgumentsDescriptor args_desc(
- Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
+ Array::Handle(Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
const Function& function =
Function::Handle(Z, Resolver::ResolveDynamic(instance, name, args_desc));
if (function.IsNull()) {
@@ -3204,7 +3212,7 @@
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 2;
ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
+ Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
const Function& function = Function::Handle(
Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
args_desc));
@@ -3262,7 +3270,7 @@
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 3;
ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
+ Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
const Function& function = Function::Handle(
Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
args_desc));
@@ -3447,7 +3455,7 @@
const int kTypeArgsLen = 0;
const int kNumArgs = 2;
ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
+ Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
const Function& function = Function::Handle(
Z,
Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc));
@@ -3533,8 +3541,8 @@
if (!instance.IsNull()) {
const int kTypeArgsLen = 0;
const int kNumArgs = 3;
- ArgumentsDescriptor args_desc(
- Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs)));
+ ArgumentsDescriptor args_desc(Array::Handle(
+ Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArgs)));
const Function& function = Function::Handle(
Z, Resolver::ResolveDynamic(instance, Symbols::AssignIndexToken(),
args_desc));
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index b9221a3..65ed764 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -28,6 +28,17 @@
#define CURRENT_FUNC CanonicalFunction(__FUNCTION__)
+// Checks that the current isolate group is not NULL.
+#define CHECK_ISOLATE_GROUP(isolate_group) \
+ do { \
+ if ((isolate_group) == NULL) { \
+ FATAL1( \
+ "%s expects there to be a current isolate group. Did you " \
+ "forget to call Dart_CreateIsolateGroup or Dart_EnterIsolate?", \
+ CURRENT_FUNC); \
+ } \
+ } while (0)
+
// Checks that the current isolate is not NULL.
#define CHECK_ISOLATE(isolate) \
do { \
@@ -173,6 +184,10 @@
// Casts the internal Isolate* type to the external Dart_Isolate type.
static Dart_Isolate CastIsolate(Isolate* isolate);
+ // Casts the internal IsolateGroup* type to the external Dart_IsolateGroup
+ // type.
+ static Dart_IsolateGroup CastIsolateGroup(IsolateGroup* isolate);
+
// Gets the handle used to designate successful return.
static Dart_Handle Success() { return Api::True(); }
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 0bcdb74..a756343 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3234,6 +3234,52 @@
Dart_ExitScope();
}
+static Dart_PersistentHandle persistent_handle1;
+static Dart_WeakPersistentHandle weak_persistent_handle2;
+static Dart_WeakPersistentHandle weak_persistent_handle3;
+
+static void WeakPersistentHandlePeerCleanupFinalizer(
+ void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* peer) {
+ Dart_DeletePersistentHandle(persistent_handle1);
+ Dart_DeleteWeakPersistentHandle(weak_persistent_handle2);
+ *static_cast<int*>(peer) = 42;
+}
+
+static void WeakPersistentHandleNoopCallback(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* peer) {}
+
+TEST_CASE(DartAPI_WeakPersistentHandleCleanupFinalizer) {
+ Heap* heap = Isolate::Current()->heap();
+
+ const char* kTestString1 = "Test String1";
+ Dart_EnterScope();
+ CHECK_API_SCOPE(thread);
+ Dart_Handle ref1 = Dart_NewStringFromCString(kTestString1);
+ persistent_handle1 = Dart_NewPersistentHandle(ref1);
+ Dart_Handle ref2 = Dart_NewStringFromCString(kTestString1);
+ int peer2 = 0;
+ weak_persistent_handle2 = Dart_NewWeakPersistentHandle(
+ ref2, &peer2, 0, WeakPersistentHandleNoopCallback);
+ int peer3 = 0;
+ {
+ Dart_EnterScope();
+ Dart_Handle ref3 = Dart_NewStringFromCString(kTestString1);
+ weak_persistent_handle3 = Dart_NewWeakPersistentHandle(
+ ref3, &peer3, 0, WeakPersistentHandlePeerCleanupFinalizer);
+ Dart_ExitScope();
+ }
+ {
+ TransitionNativeToVM transition(thread);
+ GCTestHelper::CollectAllGarbage();
+ EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
+ EXPECT(peer3 == 42);
+ }
+ Dart_ExitScope();
+}
+
static void WeakPersistentHandlePeerFinalizer(void* isolate_callback_data,
Dart_WeakPersistentHandle handle,
void* peer) {
@@ -3275,8 +3321,7 @@
}
// A finalizer is not invoked on a deleted handle. Therefore, the
// peer value should not change after the referent is collected.
- Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
- Dart_DeleteWeakPersistentHandle(isolate, weak_ref);
+ Dart_DeleteWeakPersistentHandle(weak_ref);
EXPECT(peer == 0);
{
TransitionNativeToVM transition(thread);
@@ -3338,9 +3383,6 @@
EXPECT(heap->ExternalInWords(Heap::kNew) == 0);
EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize);
}
- Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
- Dart_DeleteWeakPersistentHandle(isolate, weak1);
- Dart_DeleteWeakPersistentHandle(isolate, weak2);
Dart_DeletePersistentHandle(strong_ref);
{
TransitionNativeToVM transition(thread);
@@ -3350,7 +3392,6 @@
}
TEST_CASE(DartAPI_WeakPersistentHandleExternalAllocationSizeNewspaceGC) {
- Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
Heap* heap = Isolate::Current()->heap();
Dart_WeakPersistentHandle weak1 = NULL;
// Large enough to exceed any new space limit. Not actually allocated.
@@ -3369,7 +3410,7 @@
Dart_WeakPersistentHandle trigger =
Dart_NewWeakPersistentHandle(obj, NULL, 1, NopCallback);
EXPECT_VALID(AsHandle(trigger));
- Dart_DeleteWeakPersistentHandle(isolate, trigger);
+ Dart_DeleteWeakPersistentHandle(trigger);
// After the two scavenges above, 'obj' should now be promoted, hence its
// external size charged to old space.
{
@@ -3384,7 +3425,7 @@
EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak1ExternalSize / kWordSize);
Dart_ExitScope();
}
- Dart_DeleteWeakPersistentHandle(isolate, weak1);
+ Dart_DeleteWeakPersistentHandle(weak1);
{
TransitionNativeToVM transition(thread);
GCTestHelper::CollectOldSpace();
@@ -3457,9 +3498,8 @@
(kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize);
Dart_ExitScope();
}
- Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
- Dart_DeleteWeakPersistentHandle(isolate, weak1);
- Dart_DeleteWeakPersistentHandle(isolate, weak2);
+ Dart_DeleteWeakPersistentHandle(weak1);
+ Dart_DeleteWeakPersistentHandle(weak2);
EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld));
{
TransitionNativeToVM transition(thread);
@@ -3468,50 +3508,6 @@
}
}
-static void AssertingFinalizer(void* isolate_callback_data,
- Dart_WeakPersistentHandle handle,
- void* peer) {
- Dart_Isolate expected_isolate = reinterpret_cast<Dart_Isolate>(peer);
- EXPECT_EQ(expected_isolate, Dart_CurrentIsolate());
-}
-
-// TODO(https://github.com/dart-lang/sdk/issues/40836): Remove.
-TEST_CASE(DartAPI_WeakPersistentHandleFinalizerCurrentIsolate) {
- {
- Dart_EnterScope();
-
- Dart_Handle obj = AllocateNewString("ABC");
- void* peer = Dart_CurrentIsolate();
- EXPECT_NOTNULL(peer);
- intptr_t external_size = 0;
- Dart_NewWeakPersistentHandle(obj, peer, external_size, AssertingFinalizer);
-
- Dart_ExitScope();
- }
-
- {
- TransitionNativeToVM transition(thread);
- GCTestHelper::CollectAllGarbage();
- }
-
- {
- Dart_EnterScope();
-
- Dart_Handle obj = AllocateOldString("ABC");
- void* peer = Dart_CurrentIsolate();
- EXPECT_NOTNULL(peer);
- intptr_t external_size = 0;
- Dart_NewWeakPersistentHandle(obj, peer, external_size, AssertingFinalizer);
-
- Dart_ExitScope();
- }
-
- {
- TransitionNativeToVM transition(thread);
- GCTestHelper::CollectAllGarbage();
- }
-}
-
static Dart_WeakPersistentHandle weak1 = NULL;
static Dart_WeakPersistentHandle weak2 = NULL;
static Dart_WeakPersistentHandle weak3 = NULL;
@@ -3778,19 +3774,38 @@
Dart_Isolate isolate = Dart_CurrentIsolate();
EXPECT_EQ(iso_1, isolate);
Dart_ExitIsolate();
- EXPECT(NULL == Dart_CurrentIsolate());
+ EXPECT_NULLPTR(Dart_CurrentIsolate());
Dart_Isolate iso_2 = TestCase::CreateTestIsolate();
EXPECT_EQ(iso_2, Dart_CurrentIsolate());
Dart_ExitIsolate();
- EXPECT(NULL == Dart_CurrentIsolate());
+ EXPECT_NULLPTR(Dart_CurrentIsolate());
Dart_EnterIsolate(iso_2);
EXPECT_EQ(iso_2, Dart_CurrentIsolate());
Dart_ShutdownIsolate();
- EXPECT(NULL == Dart_CurrentIsolate());
+ EXPECT_NULLPTR(Dart_CurrentIsolate());
Dart_EnterIsolate(iso_1);
EXPECT_EQ(iso_1, Dart_CurrentIsolate());
Dart_ShutdownIsolate();
- EXPECT(NULL == Dart_CurrentIsolate());
+ EXPECT_NULLPTR(Dart_CurrentIsolate());
+}
+
+VM_UNIT_TEST_CASE(DartAPI_IsolateGroups) {
+ Dart_Isolate iso_1 = TestCase::CreateTestIsolate();
+ EXPECT_NOTNULL(Dart_CurrentIsolateGroup());
+ Dart_ExitIsolate();
+ EXPECT_NULLPTR(Dart_CurrentIsolateGroup());
+ Dart_Isolate iso_2 = TestCase::CreateTestIsolate();
+ EXPECT_NOTNULL(Dart_CurrentIsolateGroup());
+ Dart_ExitIsolate();
+ EXPECT_NULLPTR(Dart_CurrentIsolateGroup());
+ Dart_EnterIsolate(iso_2);
+ EXPECT_NOTNULL(Dart_CurrentIsolateGroup());
+ Dart_ShutdownIsolate();
+ EXPECT_NULLPTR(Dart_CurrentIsolateGroup());
+ Dart_EnterIsolate(iso_1);
+ EXPECT_NOTNULL(Dart_CurrentIsolateGroup());
+ Dart_ShutdownIsolate();
+ EXPECT_NULLPTR(Dart_CurrentIsolateGroup());
}
VM_UNIT_TEST_CASE(DartAPI_CurrentIsolateData) {
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index ab11b0c..5d24012 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -31,8 +31,8 @@
const Array& arguments) {
ASSERT(Thread::Current()->IsMutatorThread());
const int kTypeArgsLen = 0; // No support to pass type args to generic func.
- const Array& arguments_descriptor =
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length()));
+ const Array& arguments_descriptor = Array::Handle(
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, arguments.Length()));
return InvokeFunction(function, arguments, arguments_descriptor);
}
@@ -185,8 +185,10 @@
RawObject* DartEntry::InvokeClosure(const Array& arguments) {
const int kTypeArgsLen = 0; // No support to pass type args to generic func.
- const Array& arguments_descriptor =
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length()));
+
+ // Closures always have boxed parameters
+ const Array& arguments_descriptor = Array::Handle(
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, arguments.Length()));
return InvokeClosure(arguments, arguments_descriptor);
}
@@ -289,8 +291,8 @@
// Now use the invocation mirror object and invoke NoSuchMethod.
const int kTypeArgsLen = 0;
const int kNumArguments = 2;
- ArgumentsDescriptor nsm_args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArguments)));
+ ArgumentsDescriptor nsm_args_desc(Array::Handle(
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
Function& function = Function::Handle(Resolver::ResolveDynamic(
receiver, Symbols::NoSuchMethod(), nsm_args_desc));
if (function.IsNull()) {
@@ -319,6 +321,10 @@
return Smi::Value(Smi::RawCast(array_.At(kCountIndex)));
}
+intptr_t ArgumentsDescriptor::Size() const {
+ return Smi::Value(Smi::RawCast(array_.At(kSizeIndex)));
+}
+
intptr_t ArgumentsDescriptor::PositionalCount() const {
return Smi::Value(Smi::RawCast(array_.At(kPositionalCountIndex)));
}
@@ -364,12 +370,14 @@
RawArray* ArgumentsDescriptor::New(intptr_t type_args_len,
intptr_t num_arguments,
+ intptr_t size_arguments,
const Array& optional_arguments_names,
Heap::Space space) {
const intptr_t num_named_args =
optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length();
if (num_named_args == 0) {
- return ArgumentsDescriptor::New(type_args_len, num_arguments, space);
+ return ArgumentsDescriptor::New(type_args_len, num_arguments,
+ size_arguments, space);
}
ASSERT(type_args_len >= 0);
ASSERT(num_arguments >= 0);
@@ -389,6 +397,8 @@
descriptor.SetAt(kTypeArgsLenIndex, Smi::Handle(Smi::New(type_args_len)));
// Set total number of passed arguments.
descriptor.SetAt(kCountIndex, Smi::Handle(Smi::New(num_arguments)));
+ // Set total number of passed arguments.
+ descriptor.SetAt(kSizeIndex, Smi::Handle(Smi::New(size_arguments)));
// Set number of positional arguments.
descriptor.SetAt(kPositionalCountIndex, Smi::Handle(Smi::New(num_pos_args)));
@@ -434,18 +444,22 @@
RawArray* ArgumentsDescriptor::New(intptr_t type_args_len,
intptr_t num_arguments,
+ intptr_t size_arguments,
Heap::Space space) {
ASSERT(type_args_len >= 0);
ASSERT(num_arguments >= 0);
- if ((type_args_len == 0) && (num_arguments < kCachedDescriptorCount)) {
+ if ((type_args_len == 0) && (num_arguments < kCachedDescriptorCount) &&
+ (num_arguments == size_arguments)) {
return cached_args_descriptors_[num_arguments];
}
- return NewNonCached(type_args_len, num_arguments, true, space);
+ return NewNonCached(type_args_len, num_arguments, size_arguments, true,
+ space);
}
RawArray* ArgumentsDescriptor::NewNonCached(intptr_t type_args_len,
intptr_t num_arguments,
+ intptr_t size_arguments,
bool canonicalize,
Heap::Space space) {
// Build the arguments descriptor array, which consists of the length of the
@@ -456,6 +470,7 @@
const intptr_t descriptor_len = LengthFor(0);
Array& descriptor = Array::Handle(zone, Array::New(descriptor_len, space));
const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments));
+ const Smi& arg_size = Smi::Handle(zone, Smi::New(size_arguments));
// Set type argument vector length.
descriptor.SetAt(kTypeArgsLenIndex,
@@ -464,6 +479,9 @@
// Set total number of passed arguments.
descriptor.SetAt(kCountIndex, arg_count);
+ // Set total size of passed arguments.
+ descriptor.SetAt(kSizeIndex, arg_size);
+
// Set number of positional arguments.
descriptor.SetAt(kPositionalCountIndex, arg_count);
@@ -486,7 +504,7 @@
void ArgumentsDescriptor::Init() {
for (int i = 0; i < kCachedDescriptorCount; i++) {
cached_args_descriptors_[i] =
- NewNonCached(/*type_args_len=*/0, i, false, Heap::kOld);
+ NewNonCached(/*type_args_len=*/0, i, i, false, Heap::kOld);
}
}
@@ -532,8 +550,8 @@
RawObject* DartLibraryCalls::ToString(const Instance& receiver) {
const int kTypeArgsLen = 0;
const int kNumArguments = 1; // Receiver.
- ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArguments)));
+ ArgumentsDescriptor args_desc(Array::Handle(
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
const Function& function = Function::Handle(
Resolver::ResolveDynamic(receiver, Symbols::toString(), args_desc));
ASSERT(!function.IsNull());
@@ -548,8 +566,8 @@
RawObject* DartLibraryCalls::HashCode(const Instance& receiver) {
const int kTypeArgsLen = 0;
const int kNumArguments = 1; // Receiver.
- ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArguments)));
+ ArgumentsDescriptor args_desc(Array::Handle(
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
const Function& function = Function::Handle(
Resolver::ResolveDynamic(receiver, Symbols::hashCode(), args_desc));
ASSERT(!function.IsNull());
@@ -565,8 +583,8 @@
const Instance& right) {
const int kTypeArgsLen = 0;
const int kNumArguments = 2;
- ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArguments)));
+ ArgumentsDescriptor args_desc(Array::Handle(
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
const Function& function = Function::Handle(
Resolver::ResolveDynamic(left, Symbols::EqualOperator(), args_desc));
ASSERT(!function.IsNull());
@@ -696,8 +714,8 @@
const Instance& value) {
const int kTypeArgsLen = 0;
const int kNumArguments = 3;
- ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArguments)));
+ ArgumentsDescriptor args_desc(Array::Handle(
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
const Function& function = Function::Handle(
Resolver::ResolveDynamic(map, Symbols::AssignIndexToken(), args_desc));
ASSERT(!function.IsNull());
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 980fcfc..11411de 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -27,10 +27,11 @@
class String;
// An arguments descriptor array consists of the type argument vector length (0
-// if none); total argument count (not counting type argument vector); the
-// positional argument count; a sequence of (name, position) pairs, sorted
-// by name, for each named optional argument; and a terminating null to
-// simplify iterating in generated code.
+// if none); total argument count (not counting type argument vector); total
+// arguments size (not counting type argument vector); the positional argument
+// count; a sequence of (name, position) pairs, sorted by name, for each named
+// optional argument; and a terminating null to simplify iterating in generated
+// code.
class ArgumentsDescriptor : public ValueObject {
public:
explicit ArgumentsDescriptor(const Array& array);
@@ -40,6 +41,8 @@
intptr_t FirstArgIndex() const { return TypeArgsLen() > 0 ? 1 : 0; }
intptr_t CountWithTypeArgs() const { return FirstArgIndex() + Count(); }
intptr_t Count() const; // Excluding type arguments vector.
+ intptr_t Size() const; // Excluding type arguments vector.
+ intptr_t SizeWithTypeArgs() const { return FirstArgIndex() + Size(); }
intptr_t PositionalCount() const; // Excluding type arguments vector.
intptr_t NamedCount() const { return Count() - PositionalCount(); }
RawString* NameAt(intptr_t i) const;
@@ -55,6 +58,8 @@
static intptr_t count_offset() { return Array::element_offset(kCountIndex); }
+ static intptr_t size_offset() { return Array::element_offset(kSizeIndex); }
+
static intptr_t positional_count_offset() {
return Array::element_offset(kPositionalCountIndex);
}
@@ -67,6 +72,20 @@
static intptr_t position_offset() { return kPositionOffset * kWordSize; }
static intptr_t named_entry_size() { return kNamedEntrySize * kWordSize; }
+ // Constructs an argument descriptor where all arguments are boxed and
+ // therefore number of parameters equals parameter size.
+ //
+ // Right now this is for example the case for all closure functions.
+ // Functions marked as entry-points may also be created by NewUnboxed because
+ // we rely that TFA will mark the arguments as nullable for such cases.
+ static RawArray* NewBoxed(intptr_t type_args_len,
+ intptr_t num_arguments,
+ const Array& optional_arguments_names,
+ Heap::Space space = Heap::kOld) {
+ return New(type_args_len, num_arguments, num_arguments,
+ optional_arguments_names, space);
+ }
+
// Allocate and return an arguments descriptor. The first
// (num_arguments - optional_arguments_names.Length()) arguments are
// positional and the remaining ones are named optional arguments.
@@ -74,15 +93,27 @@
// num_arguments) is indicated by a non-zero type_args_len.
static RawArray* New(intptr_t type_args_len,
intptr_t num_arguments,
+ intptr_t size_arguments,
const Array& optional_arguments_names,
Heap::Space space = Heap::kOld);
+ // Constructs an argument descriptor where all arguments are boxed and
+ // therefore number of parameters equals parameter size.
+ //
+ // Right now this is for example the case for all closure functions.
+ static RawArray* NewBoxed(intptr_t type_args_len,
+ intptr_t num_arguments,
+ Heap::Space space = Heap::kOld) {
+ return New(type_args_len, num_arguments, num_arguments, space);
+ }
+
// Allocate and return an arguments descriptor that has no optional
// arguments. All arguments are positional. The presence of a type argument
// vector as first argument (not counted in num_arguments) is indicated
// by a non-zero type_args_len.
static RawArray* New(intptr_t type_args_len,
intptr_t num_arguments,
+ intptr_t size_arguments,
Heap::Space space = Heap::kOld);
// Initialize the preallocated fixed length arguments descriptors cache.
@@ -99,6 +130,7 @@
enum {
kTypeArgsLenIndex,
kCountIndex,
+ kSizeIndex,
kPositionalCountIndex,
kFirstNamedEntryIndex,
};
@@ -122,6 +154,7 @@
static RawArray* NewNonCached(intptr_t type_args_len,
intptr_t num_arguments,
+ intptr_t size_arguments,
bool canonicalize,
Heap::Space space);
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 6ce5c85..40bc68a 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -157,12 +157,12 @@
intptr_t src_lo_slot() const {
ASSERT(source_kind() == SourceKind::kInt64PairSlot);
- return LoSourceSlot::decode(src_);
+ return index_to_pair_slot(LoSourceSlot::decode(src_));
}
intptr_t src_hi_slot() const {
ASSERT(source_kind() == SourceKind::kInt64PairSlot);
- return HiSourceSlot::decode(src_);
+ return index_to_pair_slot(HiSourceSlot::decode(src_));
}
intptr_t dest_slot() const {
@@ -182,8 +182,8 @@
}
static intptr_t EncodePairSource(intptr_t src_lo_slot, intptr_t src_hi_slot) {
- return LoSourceSlot::encode(src_lo_slot) |
- HiSourceSlot::encode(src_hi_slot);
+ return LoSourceSlot::encode(pair_slot_to_index(src_lo_slot)) |
+ HiSourceSlot::encode(pair_slot_to_index(src_hi_slot));
}
bool IsRedundant() const {
@@ -206,6 +206,15 @@
#endif
private:
+ static intptr_t pair_slot_to_index(intptr_t slot) {
+ return (slot < 0) ? -2 * slot : 2 * slot + 1;
+ }
+
+ static intptr_t index_to_pair_slot(intptr_t index) {
+ ASSERT(index >= 0);
+ return ((index & 1) != 0) ? (index >> 1) : -(index >> 1);
+ }
+
CatchEntryMove(int32_t src, int32_t dest_and_kind)
: src_(src), dest_and_kind_(dest_and_kind) {}
diff --git a/runtime/vm/handles_test.cc b/runtime/vm/handles_test.cc
index 142e147..0e6486f 100644
--- a/runtime/vm/handles_test.cc
+++ b/runtime/vm/handles_test.cc
@@ -116,7 +116,6 @@
EXPECT(!Api::IsValid(handle));
// Check validity using persistent handle.
- Isolate* isolate = Isolate::Current();
Dart_Handle scoped_handle;
{
TransitionNativeToVM transition(thread);
@@ -137,7 +136,6 @@
EXPECT_VALID(handle);
Dart_DeleteWeakPersistentHandle(
- reinterpret_cast<Dart_Isolate>(isolate),
reinterpret_cast<Dart_WeakPersistentHandle>(handle));
EXPECT(!Api::IsValid(handle));
}
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index a04108b..59abade 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -52,24 +52,6 @@
Isolate* saved_isolate_;
};
-RunFinalizersScope::RunFinalizersScope(Thread* thread) : thread_(thread) {
- if (!FLAG_enable_isolate_groups) {
- ASSERT(thread->IsAtSafepoint() ||
- (thread->task_kind() == Thread::kMarkerTask));
- IsolateGroup* isolate_group = thread->isolate_group();
- Isolate* isolate = isolate_group->isolates_.First();
- ASSERT(isolate == isolate_group->isolates_.Last());
- saved_isolate_ = thread->isolate_;
- thread->isolate_ = isolate;
- }
-}
-
-RunFinalizersScope::~RunFinalizersScope() {
- if (!FLAG_enable_isolate_groups) {
- thread_->isolate_ = saved_isolate_;
- }
-}
-
Heap::Heap(IsolateGroup* isolate_group,
intptr_t max_new_gen_semi_words,
intptr_t max_old_gen_words)
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index f72472e..34ab784 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -30,20 +30,6 @@
class TimelineEventScope;
class VirtualMemory;
-// Temporarily enter the only isolate in the group before running weak handle
-// finalizers to keep existing embedder code working. Remove once embedders
-// are updated to think in terms of isolate groups.
-// TODO(https://github.com/dart-lang/sdk/issues/40836): Remove.
-class RunFinalizersScope {
- public:
- explicit RunFinalizersScope(Thread* thread);
- ~RunFinalizersScope();
-
- private:
- Thread* thread_;
- Isolate* saved_isolate_;
-};
-
class Heap {
public:
enum Space {
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 75bc357..d353296 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -465,12 +465,9 @@
void GCMarker::ProcessWeakHandles(Thread* thread) {
TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessWeakHandles");
-
MarkingWeakVisitor visitor(thread);
ApiState* state = isolate_group_->api_state();
ASSERT(state != NULL);
-
- RunFinalizersScope tcis(thread);
isolate_group_->VisitWeakPersistentHandles(&visitor);
}
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index aef253f..0461261 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -1038,8 +1038,10 @@
const int64_t pre_wait_for_sweepers = OS::GetCurrentMonotonicMicros();
// Wait for pending tasks to complete and then account for the driver task.
+ Phase waited_for;
{
MonitorLocker locker(tasks_lock());
+ waited_for = phase();
if (!finalize &&
(phase() == kMarking || phase() == kAwaitingFinalization)) {
// Concurrent mark is already running.
@@ -1054,6 +1056,16 @@
}
const int64_t pre_safe_point = OS::GetCurrentMonotonicMicros();
+ if (FLAG_verbose_gc) {
+ const int64_t wait = pre_safe_point - pre_wait_for_sweepers;
+ if (waited_for == kMarking) {
+ THR_Print("Waited %" Pd64 " us for concurrent marking to finish.\n",
+ wait);
+ } else if (waited_for == kSweepingRegular || waited_for == kSweepingLarge) {
+ THR_Print("Waited %" Pd64 " us for concurrent sweeping to finish.\n",
+ wait);
+ }
+ }
// Ensure that all threads for this isolate are at a safepoint (either
// stopped or in native code). We have guards around Newgen GC and oldgen GC
@@ -1483,9 +1495,8 @@
heap_growth_max_(heap_growth_max),
garbage_collection_time_ratio_(garbage_collection_time_ratio),
idle_gc_threshold_in_words_(0) {
- intptr_t grow_heap = heap_growth_max / 2;
- gc_threshold_in_words_ =
- last_usage_.capacity_in_words + (kPageSizeInWords * grow_heap);
+ const intptr_t growth_in_pages = heap_growth_max / 2;
+ RecordUpdate(last_usage_, last_usage_, growth_in_pages, "initial");
}
PageSpaceController::~PageSpaceController() {}
@@ -1497,12 +1508,7 @@
if (heap_growth_ratio_ == 100) {
return false;
}
-#if defined(TARGET_ARCH_IA32)
- intptr_t headroom = 0;
-#else
- intptr_t headroom = heap_->new_space()->CapacityInWords();
-#endif
- return after.CombinedUsedInWords() > (gc_threshold_in_words_ + headroom);
+ return after.CombinedUsedInWords() > hard_gc_threshold_in_words_;
}
bool PageSpaceController::AlmostNeedsGarbageCollection(SpaceUsage after) const {
@@ -1512,7 +1518,7 @@
if (heap_growth_ratio_ == 100) {
return false;
}
- return after.CombinedUsedInWords() > gc_threshold_in_words_;
+ return after.CombinedUsedInWords() > soft_gc_threshold_in_words_;
}
bool PageSpaceController::NeedsIdleGarbageCollection(SpaceUsage current) const {
@@ -1613,15 +1619,7 @@
heap_->RecordData(PageSpace::kAllowedGrowth, grow_heap);
last_usage_ = after;
- // Save final threshold compared before growing.
- gc_threshold_in_words_ =
- after.CombinedUsedInWords() + (kPageSizeInWords * grow_heap);
-
- // Set a tight idle threshold.
- idle_gc_threshold_in_words_ =
- after.CombinedUsedInWords() + (2 * kPageSizeInWords);
-
- RecordUpdate(before, after, "gc");
+ RecordUpdate(before, after, grow_heap, "gc");
}
void PageSpaceController::EvaluateAfterLoading(SpaceUsage after) {
@@ -1637,38 +1635,57 @@
growth_in_pages =
Utils::Minimum(static_cast<intptr_t>(heap_growth_max_), growth_in_pages);
+ RecordUpdate(after, after, growth_in_pages, "loaded");
+}
+
+void PageSpaceController::RecordUpdate(SpaceUsage before,
+ SpaceUsage after,
+ intptr_t growth_in_pages,
+ const char* reason) {
// Save final threshold compared before growing.
- gc_threshold_in_words_ =
+ hard_gc_threshold_in_words_ =
after.CombinedUsedInWords() + (kPageSizeInWords * growth_in_pages);
+ // Start concurrent marking when old-space has less than half of new-space
+ // available or less than 5% available.
+#if defined(TARGET_ARCH_IA32)
+ const intptr_t headroom = 0; // No concurrent marking.
+#else
+ // Note that heap_ can be null in some unit tests.
+ const intptr_t new_space =
+ heap_ == nullptr ? 0 : heap_->new_space()->CapacityInWords();
+ const intptr_t headroom =
+ Utils::Maximum(new_space / 2, hard_gc_threshold_in_words_ / 20);
+#endif
+ soft_gc_threshold_in_words_ = hard_gc_threshold_in_words_ - headroom;
+
// Set a tight idle threshold.
idle_gc_threshold_in_words_ =
after.CombinedUsedInWords() + (2 * kPageSizeInWords);
- RecordUpdate(after, after, "loaded");
-}
-
-void PageSpaceController::RecordUpdate(SpaceUsage before,
- SpaceUsage after,
- const char* reason) {
#if defined(SUPPORT_TIMELINE)
- TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "UpdateGrowthLimit");
- tbes.SetNumArguments(5);
- tbes.CopyArgument(0, "Reason", reason);
- tbes.FormatArgument(1, "Before.CombinedUsed (kB)", "%" Pd "",
- RoundWordsToKB(before.CombinedUsedInWords()));
- tbes.FormatArgument(2, "After.CombinedUsed (kB)", "%" Pd "",
- RoundWordsToKB(after.CombinedUsedInWords()));
- tbes.FormatArgument(3, "Threshold (kB)", "%" Pd "",
- RoundWordsToKB(gc_threshold_in_words_));
- tbes.FormatArgument(4, "Idle Threshold (kB)", "%" Pd "",
- RoundWordsToKB(idle_gc_threshold_in_words_));
+ Thread* thread = Thread::Current();
+ if (thread != nullptr) {
+ TIMELINE_FUNCTION_GC_DURATION(thread, "UpdateGrowthLimit");
+ tbes.SetNumArguments(6);
+ tbes.CopyArgument(0, "Reason", reason);
+ tbes.FormatArgument(1, "Before.CombinedUsed (kB)", "%" Pd "",
+ RoundWordsToKB(before.CombinedUsedInWords()));
+ tbes.FormatArgument(2, "After.CombinedUsed (kB)", "%" Pd "",
+ RoundWordsToKB(after.CombinedUsedInWords()));
+ tbes.FormatArgument(3, "Hard Threshold (kB)", "%" Pd "",
+ RoundWordsToKB(hard_gc_threshold_in_words_));
+ tbes.FormatArgument(4, "Soft Threshold (kB)", "%" Pd "",
+ RoundWordsToKB(soft_gc_threshold_in_words_));
+ tbes.FormatArgument(5, "Idle Threshold (kB)", "%" Pd "",
+ RoundWordsToKB(idle_gc_threshold_in_words_));
+ }
#endif
if (FLAG_log_growth) {
THR_Print("%s: threshold=%" Pd "kB, idle_threshold=%" Pd "kB, reason=%s\n",
heap_->isolate_group()->source()->name,
- gc_threshold_in_words_ / KBInWords,
+ hard_gc_threshold_in_words_ / KBInWords,
idle_gc_threshold_in_words_ / KBInWords, reason);
}
}
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index a8ef135..d51e697 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -242,6 +242,11 @@
void RecordUpdate(SpaceUsage before, SpaceUsage after, const char* reason);
void MergeOtherPageSpaceController(PageSpaceController* other);
+ void RecordUpdate(SpaceUsage before,
+ SpaceUsage after,
+ intptr_t growth_in_pages,
+ const char* reason);
+
Heap* heap_;
bool is_enabled_;
@@ -264,10 +269,13 @@
// we grow the heap more aggressively.
const int garbage_collection_time_ratio_;
- // Perform a GC when capacity exceeds this amount.
- intptr_t gc_threshold_in_words_;
+ // Perform a stop-the-world GC when usage exceeds this amount.
+ intptr_t hard_gc_threshold_in_words_;
- // Start considering idle GC when capacity exceeds this amount.
+ // Begin concurrent marking when usage exceeds this amount.
+ intptr_t soft_gc_threshold_in_words_;
+
+ // Run idle GC if time permits when usage exceeds this amount.
intptr_t idle_gc_threshold_in_words_;
PageSpaceGarbageCollectionHistory history_;
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index f1d4b2a..d3c20b2 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -772,7 +772,6 @@
void Scavenger::IterateWeakRoots(IsolateGroup* isolate_group,
HandleVisitor* visitor) {
- RunFinalizersScope tcis(Thread::Current());
isolate_group->VisitWeakPersistentHandles(visitor);
}
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 3c99bbb..cb8c0e3 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -167,6 +167,12 @@
Array::element_offset(ArgumentsDescriptor::kCountIndex)));
}
+ DART_FORCE_INLINE static intptr_t ArgDescArgSize(RawArray* argdesc) {
+ return Smi::Value(*reinterpret_cast<RawSmi**>(
+ reinterpret_cast<uword>(argdesc->ptr()) +
+ Array::element_offset(ArgumentsDescriptor::kSizeIndex)));
+ }
+
DART_FORCE_INLINE static intptr_t ArgDescPosCount(RawArray* argdesc) {
return Smi::Value(*reinterpret_cast<RawSmi**>(
reinterpret_cast<uword>(argdesc->ptr()) +
@@ -2122,7 +2128,7 @@
SP[0] = Smi::New(0); // Patch null length with zero length.
SP[1] = thread->isolate()->object_store()->growable_list_factory();
// Change the ArgumentsDescriptor of the call with a new cached one.
- argdesc_ = ArgumentsDescriptor::New(
+ argdesc_ = ArgumentsDescriptor::NewBoxed(
0, KernelBytecode::kNativeCallToGrowableListArgc);
// Replace PC to the return trampoline so ReturnTOS would see
// a call bytecode at return address and will be able to get argc
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 4b3e5e5..84927d1 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -2407,6 +2407,12 @@
visitor->VisitPointer(
reinterpret_cast<RawObject**>(&deoptimized_code_array_));
visitor->VisitPointer(reinterpret_cast<RawObject**>(&sticky_error_));
+ if (isolate_group_ != nullptr) {
+ if (isolate_group_->source()->hot_reload_blobs_ != nullptr) {
+ visitor->VisitPointer(reinterpret_cast<RawObject**>(
+ &(isolate_group_->source()->hot_reload_blobs_)));
+ }
+ }
#if !defined(PRODUCT)
visitor->VisitPointer(
reinterpret_cast<RawObject**>(&pending_service_extension_calls_));
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index f2389bb..5ee8098 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -198,7 +198,9 @@
kernel_buffer_size(kernel_buffer_size),
flags(flags),
script_kernel_buffer(nullptr),
- script_kernel_size(-1) {}
+ script_kernel_size(-1),
+ hot_reload_blobs_(nullptr),
+ num_hot_reloads_(0) {}
~IsolateGroupSource() { free(name); }
// The arguments used for spawning in
@@ -219,6 +221,10 @@
// invoking the "main" script.
// Any newly spawned isolates need to use this permutation map.
std::unique_ptr<intptr_t[]> cid_permutation_map;
+
+ // List of weak pointers to external typed data for hot reload blobs.
+ RawArray* hot_reload_blobs_;
+ intptr_t num_hot_reloads_;
};
// Tracks idle time and notifies heap when idle time expired.
@@ -476,7 +482,6 @@
private:
friend class Heap;
friend class StackFrame; // For `[isolates_].First()`.
- friend class RunFinalizersScope; // For `[isolates_].First()`.
#define ISOLATE_GROUP_FLAG_BITS(V) V(CompactionInProgress)
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 700154e..5652c1a 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -628,6 +628,62 @@
kernel_program = kernel::Program::ReadFromTypedData(typed_data);
}
+ ExternalTypedData& external_typed_data =
+ ExternalTypedData::Handle(Z, kernel_program.get()->typed_data()->raw());
+ IsolateGroupSource* source = Isolate::Current()->source();
+ Array& hot_reload_blobs = Array::Handle();
+ bool saved_external_typed_data = false;
+ if (source->hot_reload_blobs_ != nullptr) {
+ hot_reload_blobs = source->hot_reload_blobs_;
+
+ // Walk the array, and (if stuff was removed) compact and reuse the space.
+ // Note that the space has to be compacted as the ordering is important.
+ WeakProperty& weak_property = WeakProperty::Handle();
+ WeakProperty& weak_property_tmp = WeakProperty::Handle();
+ ExternalTypedData& existing_entry = ExternalTypedData::Handle(Z);
+ intptr_t next_entry_index = 0;
+ for (intptr_t i = 0; i < hot_reload_blobs.Length(); i++) {
+ weak_property ^= hot_reload_blobs.At(i);
+ if (weak_property.key() != ExternalTypedData::null()) {
+ if (i != next_entry_index) {
+ existing_entry = ExternalTypedData::RawCast(weak_property.key());
+ weak_property_tmp ^= hot_reload_blobs.At(next_entry_index);
+ weak_property_tmp.set_key(existing_entry);
+ }
+ next_entry_index++;
+ }
+ }
+ if (next_entry_index < hot_reload_blobs.Length()) {
+ // There's now space to re-use.
+ weak_property ^= hot_reload_blobs.At(next_entry_index);
+ weak_property.set_key(external_typed_data);
+ next_entry_index++;
+ saved_external_typed_data = true;
+ }
+ if (next_entry_index < hot_reload_blobs.Length()) {
+ ExternalTypedData& nullExternalTypedData = ExternalTypedData::Handle(Z);
+ while (next_entry_index < hot_reload_blobs.Length()) {
+ // Null out any extra spaces.
+ weak_property ^= hot_reload_blobs.At(next_entry_index);
+ weak_property.set_key(nullExternalTypedData);
+ next_entry_index++;
+ }
+ }
+ }
+ if (!saved_external_typed_data) {
+ const WeakProperty& weak_property =
+ WeakProperty::Handle(WeakProperty::New(Heap::kOld));
+ weak_property.set_key(external_typed_data);
+
+ intptr_t length =
+ hot_reload_blobs.IsNull() ? 0 : hot_reload_blobs.Length();
+ Array& new_array =
+ Array::Handle(Array::Grow(hot_reload_blobs, length + 1, Heap::kOld));
+ new_array.SetAt(length, weak_property);
+ source->hot_reload_blobs_ = new_array.raw();
+ }
+ source->num_hot_reloads_++;
+
modified_libs_ = new (Z) BitVector(Z, num_old_libs_);
kernel::KernelLoader::FindModifiedLibraries(
kernel_program.get(), first_isolate_, modified_libs_, force_reload,
@@ -888,23 +944,18 @@
success = false;
}
- // Once we --enable-isolate-groups in JIT again, we have to ensure unwind
- // errors will be propagated to all isolates.
- if (result.IsUnwindError()) {
- const auto& error = Error::Cast(result);
- if (thread->top_exit_frame_info() == 0) {
- // We can only propagate errors when there are Dart frames on the stack.
- // In this case there are no Dart frames on the stack and we set the
- // thread's sticky error. This error will be returned to the message
- // handler.
- thread->set_sticky_error(error);
- } else {
- // If the tag handler returns with an UnwindError error, propagate it and
- // give up.
- Exceptions::PropagateError(error);
- UNREACHABLE();
+ // Re-queue any shutdown requests so they can inform each isolate's own thread
+ // to shut down.
+ isolateIndex = 0;
+ ForEachIsolate([&](Isolate* isolate) {
+ tmp = results.At(isolateIndex);
+ if (tmp.IsUnwindError()) {
+ Isolate::KillIfExists(isolate, UnwindError::Cast(tmp).is_user_initiated()
+ ? Isolate::kKillMsg
+ : Isolate::kInternalKillMsg);
}
- }
+ isolateIndex++;
+ });
return success;
}
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index c1103d1..fe02d0b 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -181,29 +181,16 @@
const String& uri = String::Handle(String::New(script_uri));
const Object& ret = Object::Handle(
isolate->CallTagHandler(Dart_kKernelTag, Object::null_object(), uri));
- Api::Scope api_scope(thread);
- Dart_Handle retval = Api::NewHandle(thread, ret.raw());
- {
- TransitionVMToNative transition(thread);
- if (!Dart_IsError(retval)) {
- Dart_TypedData_Type data_type;
- uint8_t* data;
- ASSERT(Dart_IsTypedData(retval));
-
- uint8_t* kernel_buffer;
- intptr_t kernel_buffer_size;
- Dart_Handle val = Dart_TypedDataAcquireData(
- retval, &data_type, reinterpret_cast<void**>(&data),
- &kernel_buffer_size);
- ASSERT(!Dart_IsError(val));
- ASSERT(data_type == Dart_TypedData_kUint8);
- kernel_buffer = reinterpret_cast<uint8_t*>(malloc(kernel_buffer_size));
- memmove(kernel_buffer, data, kernel_buffer_size);
- Dart_TypedDataReleaseData(retval);
-
- kernel_program = kernel::Program::ReadFromBuffer(
- kernel_buffer, kernel_buffer_size, error);
- } else if (error != nullptr) {
+ if (ret.IsExternalTypedData()) {
+ const auto& typed_data = ExternalTypedData::Handle(
+ thread->zone(), ExternalTypedData::RawCast(ret.raw()));
+ kernel_program = kernel::Program::ReadFromTypedData(typed_data);
+ return kernel_program;
+ } else if (error != nullptr) {
+ Api::Scope api_scope(thread);
+ Dart_Handle retval = Api::NewHandle(thread, ret.raw());
+ {
+ TransitionVMToNative transition(thread);
*error = Dart_GetError(retval);
}
}
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 46e3efc..845d10e 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -439,6 +439,27 @@
Dart_CloseNativePort(port_);
}
+ intptr_t setDillData(Dart_CObject** dills_array,
+ intptr_t dill_num,
+ const uint8_t* buffer,
+ intptr_t buffer_size) {
+ if (buffer != nullptr) {
+ dills_array[dill_num] = new Dart_CObject;
+ dills_array[dill_num]->type = Dart_CObject_kExternalTypedData;
+ dills_array[dill_num]->value.as_external_typed_data.type =
+ Dart_TypedData_kUint8;
+ dills_array[dill_num]->value.as_external_typed_data.length = buffer_size;
+ dills_array[dill_num]->value.as_external_typed_data.data =
+ const_cast<uint8_t*>(buffer);
+ dills_array[dill_num]->value.as_external_typed_data.peer =
+ const_cast<uint8_t*>(buffer);
+ dills_array[dill_num]->value.as_external_typed_data.callback =
+ PassThroughFinalizer;
+ dill_num++;
+ }
+ return dill_num;
+ }
+
Dart_KernelCompilationResult SendAndWaitForResponse(
Dart_Port kernel_port,
const char* expression,
@@ -517,6 +538,86 @@
isolate_id.value.as_int64 =
isolate != NULL ? static_cast<int64_t>(isolate->main_port()) : 0;
+ IsolateGroupSource* source = Isolate::Current()->source();
+ intptr_t num_dills = 0;
+ if (source->kernel_buffer != nullptr) {
+ num_dills++;
+ }
+ if (source->script_kernel_buffer != nullptr) {
+ num_dills++;
+ }
+ Array& hot_reload_blobs = Array::Handle();
+ if (source->hot_reload_blobs_ != nullptr) {
+ hot_reload_blobs = source->hot_reload_blobs_;
+ WeakProperty& weak_property = WeakProperty::Handle();
+ for (intptr_t i = 0; i < hot_reload_blobs.Length(); i++) {
+ weak_property ^= hot_reload_blobs.At(i);
+ if (weak_property.key() != ExternalTypedData::null()) {
+ num_dills++;
+ }
+ }
+ }
+ // TODO(jensj): Get the platform somehow. Currently the dart side simply
+ // loads the dill from file.
+
+ Dart_CObject dills_object;
+ dills_object.type = Dart_CObject_kArray;
+ dills_object.value.as_array.length = num_dills;
+
+ Dart_CObject** dills_array = new Dart_CObject*[num_dills];
+ intptr_t dill_num = 0;
+ dill_num = setDillData(dills_array, dill_num, source->kernel_buffer,
+ source->kernel_buffer_size);
+ dill_num = setDillData(dills_array, dill_num, source->script_kernel_buffer,
+ source->script_kernel_size);
+ if (!hot_reload_blobs.IsNull()) {
+ WeakProperty& weak_property = WeakProperty::Handle();
+ for (intptr_t i = 0; i < hot_reload_blobs.Length(); i++) {
+ weak_property ^= hot_reload_blobs.At(i);
+ if (weak_property.key() != ExternalTypedData::null()) {
+ ExternalTypedData& externalTypedData = ExternalTypedData::Handle(
+ thread->zone(), ExternalTypedData::RawCast(weak_property.key()));
+ NoSafepointScope no_safepoint(thread);
+ const uint8_t* data = const_cast<uint8_t*>(
+ reinterpret_cast<uint8_t*>(externalTypedData.DataAddr(0)));
+ dill_num = setDillData(dills_array, dill_num, data,
+ externalTypedData.Length());
+ }
+ }
+ }
+ dills_object.value.as_array.values = dills_array;
+
+ Dart_CObject hot_reload_count;
+ hot_reload_count.type = Dart_CObject_kInt64;
+ hot_reload_count.value.as_int64 = source->num_hot_reloads_;
+
+ Dart_CObject suppress_warnings;
+ suppress_warnings.type = Dart_CObject_kBool;
+ suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings;
+
+ Dart_CObject enable_asserts;
+ enable_asserts.type = Dart_CObject_kBool;
+ enable_asserts.value.as_bool =
+ isolate != NULL ? isolate->asserts() : FLAG_enable_asserts;
+
+ intptr_t num_experimental_flags = experimental_flags->length();
+ Dart_CObject** experimental_flags_array =
+ new Dart_CObject*[num_experimental_flags];
+ for (intptr_t i = 0; i < num_experimental_flags; ++i) {
+ experimental_flags_array[i] = new Dart_CObject;
+ experimental_flags_array[i]->type = Dart_CObject_kString;
+ experimental_flags_array[i]->value.as_string = (*experimental_flags)[i];
+ }
+ Dart_CObject experimental_flags_object;
+ experimental_flags_object.type = Dart_CObject_kArray;
+ experimental_flags_object.value.as_array.values = experimental_flags_array;
+ experimental_flags_object.value.as_array.length = num_experimental_flags;
+
+ Dart_CObject bytecode;
+ bytecode.type = Dart_CObject_kBool;
+ bytecode.value.as_bool =
+ FLAG_enable_interpreter || FLAG_use_bytecode_compiler;
+
Dart_CObject message;
message.type = Dart_CObject_kArray;
Dart_CObject* message_arr[] = {&tag,
@@ -527,7 +628,13 @@
&type_definitions_object,
&library_uri_object,
&class_object,
- &is_static_object};
+ &is_static_object,
+ &dills_object,
+ &hot_reload_count,
+ &suppress_warnings,
+ &enable_asserts,
+ &experimental_flags_object,
+ &bytecode};
message.value.as_array.values = message_arr;
message.value.as_array.length = ARRAY_SIZE(message_arr);
@@ -555,6 +662,16 @@
}
delete[] type_definitions_array;
+ for (intptr_t i = 0; i < num_dills; ++i) {
+ delete dills_array[i];
+ }
+ delete[] dills_array;
+
+ for (intptr_t i = 0; i < num_experimental_flags; ++i) {
+ delete experimental_flags_array[i];
+ }
+ delete[] experimental_flags_array;
+
return result_;
}
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index eedc433..88bed84 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -204,8 +204,11 @@
program_->kernel_data(),
program_->kernel_data_size(),
0),
- type_translator_(&helper_, &active_class_, /* finalize= */ false),
constant_reader_(&helper_, &active_class_),
+ type_translator_(&helper_,
+ &constant_reader_,
+ &active_class_,
+ /* finalize= */ false),
inferred_type_metadata_helper_(&helper_, &constant_reader_),
bytecode_metadata_helper_(&helper_, &active_class_),
external_name_class_(Class::Handle(Z)),
@@ -453,8 +456,11 @@
KernelProgramInfo::ZoneHandle(zone_, script.kernel_program_info())),
translation_helper_(this, thread_, Heap::kOld),
helper_(zone_, &translation_helper_, script, kernel_data, 0),
- type_translator_(&helper_, &active_class_, /* finalize= */ false),
constant_reader_(&helper_, &active_class_),
+ type_translator_(&helper_,
+ &constant_reader_,
+ &active_class_,
+ /* finalize= */ false),
inferred_type_metadata_helper_(&helper_, &constant_reader_),
bytecode_metadata_helper_(&helper_, &active_class_),
external_name_class_(Class::Handle(Z)),
@@ -942,7 +948,8 @@
void KernelLoader::ReadInferredType(const Field& field,
intptr_t kernel_offset) {
const InferredTypeMetadata type =
- inferred_type_metadata_helper_.GetInferredType(kernel_offset);
+ inferred_type_metadata_helper_.GetInferredType(kernel_offset,
+ /*read_constant=*/false);
if (type.IsTrivial()) {
return;
}
@@ -1021,8 +1028,22 @@
if (library.Loaded()) return library.raw();
library.set_is_nnbd(library_helper.IsNonNullableByDefault());
- library.set_nnbd_compiled_mode(
- library_helper.GetNonNullableByDefaultCompiledMode());
+ const NNBDCompiledMode mode =
+ library_helper.GetNonNullableByDefaultCompiledMode();
+ if (!FLAG_null_safety && mode == NNBDCompiledMode::kStrong) {
+ H.ReportError(
+ "Library '%s' was compiled with null safety (in strong mode) and it "
+ "requires --null-safety option at runtime",
+ String::Handle(library.url()).ToCString());
+ }
+ if (FLAG_null_safety && (mode == NNBDCompiledMode::kWeak ||
+ mode == NNBDCompiledMode::kDisabled)) {
+ H.ReportError(
+ "Library '%s' was compiled without null safety (in weak mode) and it "
+ "cannot be used with --null-safety at runtime",
+ String::Handle(library.url()).ToCString());
+ }
+ library.set_nnbd_compiled_mode(mode);
library_kernel_data_ = helper_.reader_.ExternalDataFromTo(
library_kernel_offset_, library_kernel_offset_ + library_size);
@@ -1660,6 +1681,7 @@
true, // is_method
false, // is_closure
&function_node_helper);
+ T.SetupUnboxingInfoMetadata(function, library_kernel_offset_);
if (library.is_dart_scheme() &&
H.IsPrivate(constructor_helper.canonical_name_)) {
@@ -2004,6 +2026,7 @@
T.SetupFunctionParameters(owner, function, is_method,
false, // is_closure
&function_node_helper);
+ T.SetupUnboxingInfoMetadata(function, library_kernel_offset_);
// Everything else is skipped implicitly, and procedure_helper and
// function_node_helper are no longer used.
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index b3b42a1..3298101 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -406,8 +406,8 @@
KernelProgramInfo& kernel_program_info_;
BuildingTranslationHelper translation_helper_;
KernelReaderHelper helper_;
- TypeTranslator type_translator_;
ConstantReader constant_reader_;
+ TypeTranslator type_translator_;
InferredTypeMetadataHelper inferred_type_metadata_helper_;
BytecodeMetadataHelper bytecode_metadata_helper_;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8cb7b81..d15e41e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3593,6 +3593,8 @@
Function& forwarder = Function::Handle(zone);
forwarder ^= Object::Clone(*this, Heap::kOld);
+ forwarder.reset_unboxed_parameters_and_return();
+
forwarder.set_name(mangled_name);
forwarder.set_is_native(false);
// TODO(dartbug.com/37737): Currently, we intentionally keep the recognized
@@ -4037,15 +4039,15 @@
}
call_args.SetAt(0, getter_result);
const Array& call_args_descriptor_array = Array::Handle(
- zone, ArgumentsDescriptor::New(kTypeArgsLen, call_args.Length(),
- arg_names, Heap::kNew));
+ zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, call_args.Length(),
+ arg_names, Heap::kNew));
// Call the closure.
return DartEntry::InvokeClosure(call_args, call_args_descriptor_array);
}
}
- const Array& args_descriptor_array =
- Array::Handle(zone, ArgumentsDescriptor::New(kTypeArgsLen, args.Length(),
- arg_names, Heap::kNew));
+ const Array& args_descriptor_array = Array::Handle(
+ zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length(),
+ arg_names, Heap::kNew));
ArgumentsDescriptor args_descriptor(args_descriptor_array);
const TypeArguments& type_args = Object::null_type_arguments();
if (function.IsNull() || !function.AreValidArguments(args_descriptor, NULL) ||
@@ -7405,7 +7407,7 @@
intptr_t num_arguments,
const Array& argument_names,
String* error_message) const {
- const Array& args_desc_array = Array::Handle(ArgumentsDescriptor::New(
+ const Array& args_desc_array = Array::Handle(ArgumentsDescriptor::NewBoxed(
num_type_arguments, num_arguments, argument_names, Heap::kNew));
ArgumentsDescriptor args_desc(args_desc_array);
return AreValidArguments(args_desc, error_message);
@@ -8000,6 +8002,7 @@
result.set_is_optimizable(is_native ? false : true);
result.set_is_background_optimizable(is_native ? false : true);
result.set_is_inlinable(true);
+ result.reset_unboxed_parameters_and_return();
result.SetInstructionsSafe(StubCode::LazyCompile());
if (kind == RawFunction::kClosureFunction ||
kind == RawFunction::kImplicitClosureFunction) {
@@ -12133,15 +12136,16 @@
}
call_args.SetAt(0, getter_result);
const Array& call_args_descriptor_array =
- Array::Handle(ArgumentsDescriptor::New(
+ Array::Handle(ArgumentsDescriptor::NewBoxed(
kTypeArgsLen, call_args.Length(), arg_names, Heap::kNew));
// Call closure.
return DartEntry::InvokeClosure(call_args, call_args_descriptor_array);
}
}
- const Array& args_descriptor_array = Array::Handle(ArgumentsDescriptor::New(
- kTypeArgsLen, args.Length(), arg_names, Heap::kNew));
+ const Array& args_descriptor_array =
+ Array::Handle(ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length(),
+ arg_names, Heap::kNew));
ArgumentsDescriptor args_descriptor(args_descriptor_array);
const TypeArguments& type_args = Object::null_type_arguments();
if (function.IsNull() || !function.AreValidArguments(args_descriptor, NULL) ||
@@ -12270,7 +12274,7 @@
}
const Array& args_desc =
- Array::Handle(zone, ArgumentsDescriptor::New(
+ Array::Handle(zone, ArgumentsDescriptor::NewBoxed(
num_type_args, arguments.Length(), Heap::kNew));
result = DartEntry::InvokeFunction(callee, real_arguments, args_desc);
}
@@ -14145,6 +14149,16 @@
return args_desc.Count();
}
+intptr_t ICData::SizeWithoutTypeArgs() const {
+ ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor()));
+ return args_desc.Size();
+}
+
+intptr_t ICData::SizeWithTypeArgs() const {
+ ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor()));
+ return args_desc.SizeWithTypeArgs();
+}
+
uint32_t ICData::DeoptReasons() const {
return DeoptReasonBits::decode(raw_ptr()->state_bits_);
}
@@ -17039,7 +17053,8 @@
const Array& args = Array::Handle(zone, Array::New(kNumArgs));
args.SetAt(0, *this);
const Array& args_descriptor = Array::Handle(
- zone, ArgumentsDescriptor::New(kTypeArgsLen, args.Length(), Heap::kNew));
+ zone,
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length(), Heap::kNew));
return InvokeInstanceFunction(*this, function, internal_getter_name, args,
args_descriptor, respect_reflectable,
@@ -17085,7 +17100,8 @@
args.SetAt(0, *this);
args.SetAt(1, value);
const Array& args_descriptor = Array::Handle(
- zone, ArgumentsDescriptor::New(kTypeArgsLen, args.Length(), Heap::kNew));
+ zone,
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length(), Heap::kNew));
return InvokeInstanceFunction(*this, setter, internal_setter_name, args,
args_descriptor, respect_reflectable,
@@ -17110,9 +17126,9 @@
// TODO(regis): Support invocation of generic functions with type arguments.
const int kTypeArgsLen = 0;
- const Array& args_descriptor =
- Array::Handle(zone, ArgumentsDescriptor::New(kTypeArgsLen, args.Length(),
- arg_names, Heap::kNew));
+ const Array& args_descriptor = Array::Handle(
+ zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length(),
+ arg_names, Heap::kNew));
TypeArguments& type_args = TypeArguments::Handle(zone);
if (klass.NumTypeArguments() > 0) {
@@ -17134,8 +17150,8 @@
const Array& getter_args = Array::Handle(zone, Array::New(kNumArgs));
getter_args.SetAt(0, *this);
const Array& getter_args_descriptor = Array::Handle(
- zone, ArgumentsDescriptor::New(kTypeArgsLen, getter_args.Length(),
- Heap::kNew));
+ zone, ArgumentsDescriptor::NewBoxed(
+ kTypeArgsLen, getter_args.Length(), Heap::kNew));
const Object& getter_result = Object::Handle(
zone, InvokeInstanceFunction(*this, function, getter_name,
getter_args, getter_args_descriptor,
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index d5cde96..bed47a7 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1951,6 +1951,10 @@
intptr_t CountWithoutTypeArgs() const;
+ intptr_t SizeWithoutTypeArgs() const;
+
+ intptr_t SizeWithTypeArgs() const;
+
intptr_t deopt_id() const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
@@ -2756,7 +2760,8 @@
}
bool HasThisParameter() const {
- return IsDynamicFunction() || IsGenerativeConstructor();
+ return IsDynamicFunction(/*allow_abstract=*/true) ||
+ IsGenerativeConstructor();
}
bool IsDynamicFunction(bool allow_abstract = false) const {
@@ -3072,6 +3077,118 @@
const char* ToQualifiedCString() const;
+ static constexpr intptr_t maximum_unboxed_parameter_count() {
+ // Subtracts one that represents the return value
+ return RawFunction::UnboxedParameterBitmap::kCapacity - 1;
+ }
+
+ void reset_unboxed_parameters_and_return() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ StoreNonPointer(&raw_ptr()->unboxed_parameters_info_,
+ RawFunction::UnboxedParameterBitmap());
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ void set_unboxed_integer_parameter_at(intptr_t index) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ ASSERT(index >= 0 && index < maximum_unboxed_parameter_count());
+ index++; // position 0 is reserved for the return value
+ const_cast<RawFunction::UnboxedParameterBitmap*>(
+ &raw_ptr()->unboxed_parameters_info_)
+ ->SetUnboxedInteger(index);
+#else
+ UNREACHABLE();
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ void set_unboxed_double_parameter_at(intptr_t index) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ ASSERT(index >= 0 && index < maximum_unboxed_parameter_count());
+ index++; // position 0 is reserved for the return value
+ const_cast<RawFunction::UnboxedParameterBitmap*>(
+ &raw_ptr()->unboxed_parameters_info_)
+ ->SetUnboxedDouble(index);
+
+#else
+ UNREACHABLE();
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ void set_unboxed_integer_return() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ const_cast<RawFunction::UnboxedParameterBitmap*>(
+ &raw_ptr()->unboxed_parameters_info_)
+ ->SetUnboxedInteger(0);
+#else
+ UNREACHABLE();
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ void set_unboxed_double_return() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ const_cast<RawFunction::UnboxedParameterBitmap*>(
+ &raw_ptr()->unboxed_parameters_info_)
+ ->SetUnboxedDouble(0);
+
+#else
+ UNREACHABLE();
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ bool is_unboxed_parameter_at(intptr_t index) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ ASSERT(index >= 0);
+ index++; // position 0 is reserved for the return value
+ return raw_ptr()->unboxed_parameters_info_.IsUnboxed(index);
+#else
+ return false;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ bool is_unboxed_integer_parameter_at(intptr_t index) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ ASSERT(index >= 0);
+ index++; // position 0 is reserved for the return value
+ return raw_ptr()->unboxed_parameters_info_.IsUnboxedInteger(index);
+#else
+ return false;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ bool is_unboxed_double_parameter_at(intptr_t index) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ ASSERT(index >= 0);
+ index++; // position 0 is reserved for the return value
+ return raw_ptr()->unboxed_parameters_info_.IsUnboxedDouble(index);
+#else
+ return false;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ bool has_unboxed_return() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ return raw_ptr()->unboxed_parameters_info_.IsUnboxed(0);
+#else
+ return false;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ bool has_unboxed_integer_return() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ return raw_ptr()->unboxed_parameters_info_.IsUnboxedInteger(0);
+#else
+ return false;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ bool has_unboxed_double_return() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ return raw_ptr()->unboxed_parameters_info_.IsUnboxedDouble(0);
+#else
+ return false;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
// Returns true if the type of this function is a subtype of the type of
// the other function.
bool IsSubtypeOf(const Function& other, Heap::Space space) const;
@@ -9376,16 +9493,19 @@
friend class Class;
};
-class TypedDataBase : public Instance {
+class PointerBase : public Instance {
+ public:
+ static intptr_t data_field_offset() {
+ return OFFSET_OF(RawPointerBase, data_);
+ }
+};
+
+class TypedDataBase : public PointerBase {
public:
static intptr_t length_offset() {
return OFFSET_OF(RawTypedDataBase, length_);
}
- static intptr_t data_field_offset() {
- return OFFSET_OF(RawTypedDataBase, data_);
- }
-
RawSmi* length() const { return raw_ptr()->length_; }
intptr_t Length() const {
@@ -9457,7 +9577,7 @@
(kTypedDataFloat64x2ArrayCid - kTypedDataInt8ArrayCid) / 3 + 1;
static const intptr_t element_size_table[kNumElementSizes];
- HEAP_OBJECT_IMPLEMENTATION(TypedDataBase, Instance);
+ HEAP_OBJECT_IMPLEMENTATION(TypedDataBase, PointerBase);
};
class TypedData : public TypedDataBase {
@@ -9790,23 +9910,18 @@
static bool IsPointer(const Instance& obj);
size_t NativeAddress() const {
- return Integer::Handle(raw_ptr()->c_memory_address_).AsInt64Value();
+ return reinterpret_cast<size_t>(raw_ptr()->data_);
}
void SetNativeAddress(size_t address) const {
- const auto& address_boxed = Integer::Handle(Integer::New(address));
- NoSafepointScope no_safepoint_scope;
- StorePointer(&raw_ptr()->c_memory_address_, address_boxed.raw());
+ uint8_t* value = reinterpret_cast<uint8_t*>(address);
+ StoreNonPointer(&raw_ptr()->data_, value);
}
static intptr_t type_arguments_offset() {
return OFFSET_OF(RawPointer, type_arguments_);
}
- static intptr_t c_memory_address_offset() {
- return OFFSET_OF(RawPointer, c_memory_address_);
- }
-
static intptr_t NextFieldOffset() { return sizeof(RawPointer); }
static const intptr_t kNativeTypeArgPos = 0;
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index c5b6f67..b371eb6 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -186,8 +186,7 @@
// Delete the weak persistent handle. GC root should now be local handle.
{
TransitionVMToNative transition(thread);
- Dart_DeleteWeakPersistentHandle(Api::CastIsolate(thread->isolate()),
- weak_persistent_handle);
+ Dart_DeleteWeakPersistentHandle(weak_persistent_handle);
weak_persistent_handle = NULL;
}
result = graph.RetainingPath(&path, path);
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index a1359fe..8834c9e 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2903,8 +2903,8 @@
const String& target_name = String::Handle(Symbols::New(thread, "Thun"));
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgs = 1;
- const Array& args_descriptor = Array::Handle(
- ArgumentsDescriptor::New(kTypeArgsLen, kNumArgs, Object::null_array()));
+ const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
+ kTypeArgsLen, kNumArgs, Object::null_array()));
ICData& o1 = ICData::Handle();
o1 = ICData::New(function, target_name, args_descriptor, id, num_args_tested,
ICData::kInstance);
@@ -3706,7 +3706,7 @@
// Add invocation dispatcher.
const String& invocation_dispatcher_name =
String::Handle(Symbols::New(thread, "myMethod"));
- const Array& args_desc = Array::Handle(ArgumentsDescriptor::New(0, 1));
+ const Array& args_desc = Array::Handle(ArgumentsDescriptor::NewBoxed(0, 1));
Function& invocation_dispatcher = Function::Handle();
invocation_dispatcher ^= cls.GetInvocationDispatcher(
invocation_dispatcher_name, args_desc,
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 4092129..93ac60e 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1008,6 +1008,63 @@
kAsyncGen = kAsyncBit | kGeneratorBit,
};
+ // Wraps a 64-bit integer to represent the bitmap for unboxed parameters and
+ // return value. Two bits are used for each of them - the first one indicates
+ // whether this value is unboxed or not, and the second one says whether it is
+ // an integer or a double. It includes the two bits for the receiver, even
+ // though currently we do not have information from TFA that allows the
+ // receiver to be unboxed.
+ class UnboxedParameterBitmap {
+ public:
+ static constexpr intptr_t kBitsPerParameter = 2;
+ static constexpr intptr_t kCapacity =
+ (kBitsPerByte * sizeof(uint64_t)) / kBitsPerParameter;
+
+ UnboxedParameterBitmap() : bitmap_(0) {}
+ explicit UnboxedParameterBitmap(uint64_t bitmap) : bitmap_(bitmap) {}
+ UnboxedParameterBitmap(const UnboxedParameterBitmap&) = default;
+ UnboxedParameterBitmap& operator=(const UnboxedParameterBitmap&) = default;
+
+ DART_FORCE_INLINE bool IsUnboxed(intptr_t position) const {
+ if (position >= kCapacity) {
+ return false;
+ }
+ ASSERT(Utils::TestBit(bitmap_, 2 * position) ||
+ !Utils::TestBit(bitmap_, 2 * position + 1));
+ return Utils::TestBit(bitmap_, 2 * position);
+ }
+ DART_FORCE_INLINE bool IsUnboxedInteger(intptr_t position) const {
+ if (position >= kCapacity) {
+ return false;
+ }
+ return Utils::TestBit(bitmap_, 2 * position) &&
+ !Utils::TestBit(bitmap_, 2 * position + 1);
+ }
+ DART_FORCE_INLINE bool IsUnboxedDouble(intptr_t position) const {
+ if (position >= kCapacity) {
+ return false;
+ }
+ return Utils::TestBit(bitmap_, 2 * position) &&
+ Utils::TestBit(bitmap_, 2 * position + 1);
+ }
+ DART_FORCE_INLINE void SetUnboxedInteger(intptr_t position) {
+ ASSERT(position < kCapacity);
+ bitmap_ |= Utils::Bit<decltype(bitmap_)>(2 * position);
+ ASSERT(!Utils::TestBit(bitmap_, 2 * position + 1));
+ }
+ DART_FORCE_INLINE void SetUnboxedDouble(intptr_t position) {
+ ASSERT(position < kCapacity);
+ bitmap_ |= Utils::Bit<decltype(bitmap_)>(2 * position);
+ bitmap_ |= Utils::Bit<decltype(bitmap_)>(2 * position + 1);
+ }
+ DART_FORCE_INLINE uint64_t Value() const { return bitmap_; }
+ DART_FORCE_INLINE bool IsEmpty() const { return bitmap_ == 0; }
+ DART_FORCE_INLINE void Reset() { bitmap_ = 0; }
+
+ private:
+ uint64_t bitmap_;
+ };
+
static constexpr intptr_t kMaxFixedParametersBits = 15;
static constexpr intptr_t kMaxOptionalParametersBits = 14;
@@ -1102,6 +1159,8 @@
#undef DECLARE
#endif // !defined(DART_PRECOMPILED_RUNTIME)
+
+ NOT_IN_PRECOMPILED(UnboxedParameterBitmap unboxed_parameters_info_);
};
class RawClosureData : public RawObject {
@@ -2392,8 +2451,12 @@
friend class String;
};
-// Abstract base class for RawTypedData/RawExternalTypedData/RawTypedDataView.
-class RawTypedDataBase : public RawInstance {
+// Abstract base class for RawTypedData/RawExternalTypedData/RawTypedDataView/
+// Pointer.
+//
+// TypedData extends this with a length field, while Pointer extends this with
+// TypeArguments field.
+class RawPointerBase : public RawInstance {
protected:
// The contents of [data_] depends on what concrete subclass is used:
//
@@ -2401,12 +2464,20 @@
// - RawExternalTypedData: Start of the C-heap payload.
// - RawTypedDataView: The [data_] field of the backing store for the view
// plus the [offset_in_bytes_] the view has.
+ // - RawPointer: Pointer into C memory (no length specified).
//
// During allocation or snapshot reading the [data_] can be temporarily
// nullptr (which is the case for views which just got created but haven't
// gotten the backing store set).
uint8_t* data_;
+ private:
+ RAW_HEAP_OBJECT_IMPLEMENTATION(PointerBase);
+};
+
+// Abstract base class for RawTypedData/RawExternalTypedData/RawTypedDataView.
+class RawTypedDataBase : public RawPointerBase {
+ protected:
// The length of the view in element sizes (obtainable via
// [TypedDataBase::ElementSizeInBytes]).
RawSmi* length_;
@@ -2671,12 +2742,12 @@
friend class RawBytecode;
};
-class RawPointer : public RawInstance {
+class RawPointer : public RawPointerBase {
RAW_HEAP_OBJECT_IMPLEMENTATION(Pointer);
+
VISIT_FROM(RawCompressed, type_arguments_)
RawTypeArguments* type_arguments_;
- RawInteger* c_memory_address_;
- VISIT_TO(RawCompressed, c_memory_address_)
+ VISIT_TO(RawCompressed, type_arguments_)
friend class Pointer;
};
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 178152b..7c8cb2d 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -193,14 +193,13 @@
F(WeakProperty, value_) \
F(MirrorReference, referent_) \
F(UserTag, label_) \
+ F(PointerBase, data_) \
F(Pointer, type_arguments_) \
- F(Pointer, c_memory_address_) \
F(DynamicLibrary, handle_) \
F(FfiTrampolineData, signature_type_) \
F(FfiTrampolineData, c_signature_) \
F(FfiTrampolineData, callback_target_) \
F(FfiTrampolineData, callback_exceptional_return_) \
- F(TypedDataBase, data_) \
F(TypedDataBase, length_) \
F(TypedDataView, typed_data_) \
F(TypedDataView, offset_in_bytes_) \
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 63b0aca..e9c7db7 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -509,7 +509,7 @@
const int kTypeArgsLen = 0;
const int kNumArguments = 1;
ArgumentsDescriptor args_desc(Array::Handle(
- zone, ArgumentsDescriptor::New(kTypeArgsLen, kNumArguments)));
+ zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
const Function& getter =
Function::Handle(zone, Resolver::ResolveDynamicForReceiverClass(
receiver_class, getter_name, args_desc));
@@ -1055,8 +1055,8 @@
const String& getter_name = String::Handle(Field::GetterName(target_name));
const int kTypeArgsLen = 0;
const int kNumArguments = 1;
- ArgumentsDescriptor args_desc(
- Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArguments)));
+ ArgumentsDescriptor args_desc(Array::Handle(
+ ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments)));
const Function& getter =
Function::Handle(Resolver::ResolveDynamicForReceiverClass(
receiver_class, getter_name, args_desc));
@@ -1323,6 +1323,7 @@
DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) {
const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(1));
+ RELEASE_ASSERT(!FLAG_precompiled_mode);
GrowableArray<const Instance*> args(1);
args.Add(&receiver);
const Function& result =
@@ -1340,6 +1341,7 @@
const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
const Instance& other = Instance::CheckedHandle(zone, arguments.ArgAt(1));
const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(2));
+ RELEASE_ASSERT(!FLAG_precompiled_mode);
GrowableArray<const Instance*> args(2);
args.Add(&receiver);
args.Add(&other);
@@ -1456,8 +1458,10 @@
ASSERT(!old_target.HasOptionalParameters());
ASSERT(!old_target.IsGeneric());
const int kTypeArgsLen = 0;
+ // TODO(dartbug.com/33549): Update this code to use the size of the parameters
+ // when supporting calls to non-static methods with unboxed parameters.
const Array& descriptor =
- Array::Handle(zone, ArgumentsDescriptor::New(
+ Array::Handle(zone, ArgumentsDescriptor::NewBoxed(
kTypeArgsLen, old_target.num_fixed_parameters()));
const ICData& ic_data =
ICData::Handle(zone, ICData::New(caller_function, name, descriptor,
@@ -1775,8 +1779,11 @@
const int kTypeArgsLen = 0;
name = old_target.name();
- descriptor = ArgumentsDescriptor::New(kTypeArgsLen,
- old_target.num_fixed_parameters());
+ // TODO(dartbug.com/33549): Update this code to use the size of the
+ // parameters when supporting calls to non-static methods with
+ // unboxed parameters.
+ descriptor = ArgumentsDescriptor::NewBoxed(
+ kTypeArgsLen, old_target.num_fixed_parameters());
}
const ICData& ic_data =
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 2a129ba..72ce179 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2808,7 +2808,7 @@
return true;
}
- if (!KernelIsolate::IsRunning()) {
+ if (!KernelIsolate::IsRunning() && !KernelIsolate::Start()) {
// Assume we are in dart1 mode where separate compilation is not required.
// 0-length kernelBytes signals that we should evaluate expression in dart1
// mode.
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 7ba614a..47f6060 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -547,8 +547,7 @@
{
TransitionVMToNative transition(thread);
Dart_DeletePersistentHandle(persistent_handle);
- Dart_DeleteWeakPersistentHandle(Dart_CurrentIsolate(),
- weak_persistent_handle);
+ Dart_DeleteWeakPersistentHandle(weak_persistent_handle);
}
// Get persistent handles (again).
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 70fde68..cf563c4 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -1036,7 +1036,6 @@
friend Isolate* CreateWithinExistingIsolateGroup(IsolateGroup*,
const char*,
char**);
- friend class RunFinalizersScope;
DISALLOW_COPY_AND_ASSIGN(Thread);
};
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 748103e..70a4da9 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -488,7 +488,7 @@
Function& owner = *CreateFunction("DummyFunction");
String& name = String::Handle(String::New("foo"));
const Array& args_desc =
- Array::Handle(ArgumentsDescriptor::New(0, 0, Object::empty_array()));
+ Array::Handle(ArgumentsDescriptor::NewBoxed(0, 0, Object::empty_array()));
for (intptr_t i = 0; i < kNumICData; i++) {
ic_data = ICData::New(owner, name, args_desc, /*deopt_id=*/0,
/*num_args_tested=*/1, ICData::kInstance,
diff --git a/samples/ffi/async/sample_async_callback.dart b/samples/ffi/async/sample_async_callback.dart
index 697693b..f9d8ea4 100644
--- a/samples/ffi/async/sample_async_callback.dart
+++ b/samples/ffi/async/sample_async_callback.dart
@@ -26,7 +26,7 @@
print("C T2 = Some C thread executing C.");
print("C = C T1 or C T2.");
print("Dart: Setup.");
- registerDart_PostCObject(NativeApi.nativeApiPostCObject);
+ registerDart_PostCObject(NativeApi.postCObject);
final interactiveCppRequests = ReceivePort()..listen(requestExecuteCallback);
final int nativePort = interactiveCppRequests.sendPort.nativePort;
diff --git a/samples/ffi/async/sample_native_port_call.dart b/samples/ffi/async/sample_native_port_call.dart
index 661d509..1e654ef 100644
--- a/samples/ffi/async/sample_native_port_call.dart
+++ b/samples/ffi/async/sample_native_port_call.dart
@@ -35,9 +35,9 @@
print("C T2 = Some C thread executing C.");
print("C = C T1 or C T2.");
print("Dart: Setup.");
- registerDart_PostCObject(NativeApi.nativeApiPostCObject);
- registerDart_NewNativePort(NativeApi.nativeApiNewNativePort);
- registerDart_CloseNativePort(NativeApi.nativeApiCloseNativePort);
+ registerDart_PostCObject(NativeApi.postCObject);
+ registerDart_NewNativePort(NativeApi.newNativePort);
+ registerDart_CloseNativePort(NativeApi.closeNativePort);
final interactiveCppRequests = ReceivePort()..listen(handleCppRequests);
final int nativePort = interactiveCppRequests.sendPort.nativePort;
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
index 9bec143..862dd7e 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
@@ -287,11 +287,6 @@
if (setters != null) {
var type = JS('', '#[#]', setters, name);
if (type != null) {
- if (JS('!', '# instanceof Array', type)) {
- // The type has metadata attached. Pull out just the type.
- // TODO(jmesserly): remove when we remove mirrors
- return JS('', '#[0]', type);
- }
return type;
}
}
@@ -556,6 +551,11 @@
cast);
}
+/// Pre-initializes types with empty type caches.
+///
+/// Required for the null-safe SDK. Stubbed here.
+addTypeCaches(type) => null;
+
// TODO(jmesserly): should we do this for all interfaces?
/// The well known symbol for testing `is Future`
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index f057e90..2bd044b 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -282,10 +282,6 @@
return $f.apply($obj, $args);
}
- // TODO(vsm): Remove when we no longer need mirrors metadata.
- // An array is used to encode annotations attached to the type.
- if ($ftype instanceof Array) $ftype = $ftype[0];
-
// Apply type arguments
if ($ftype instanceof $GenericFunctionType) {
let formalCount = $ftype.formalCount;
@@ -701,7 +697,7 @@
Future loadLibrary() => Future.value();
/// Defines lazy statics.
-void defineLazy(to, from) {
+void defineLazy(to, from, bool checkCycles) {
for (var name in getOwnNamesAndSymbols(from)) {
defineLazyField(to, name, getOwnPropertyDescriptor(from, name));
}
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
index c691cfd..5d5a251 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
@@ -53,9 +53,13 @@
return JS('', '#.concat(#)', names, symbols);
}
+/// Returns the value of field `name` on `obj`.
+///
+/// We use this instead of obj[name] since obj[name] checks the entire
+/// prototype chain instead of just `obj`.
safeGetOwnProperty(obj, name) {
- var desc = getOwnPropertyDescriptor(obj, name);
- if (desc != null) return JS('', '#.value', desc);
+ if (JS<bool>('!', '#.hasOwnProperty(#)', obj, name))
+ return JS<Object>('', '#[#]', obj, name);
}
/// Defines a lazy static field.
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 5a80b9b..2148886 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -106,7 +106,7 @@
Expando([String name])
: this.name = name,
_jsWeakMapOrKey = JS('bool', 'typeof WeakMap == "function"')
- ? JS('=Object|Null', 'new WeakMap()')
+ ? JS('=Object', 'new WeakMap()')
: _createKey();
@patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 548286b..113d7c9 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -8,6 +8,7 @@
import 'dart:_js_embedded_names'
show
+ ARRAY_RTI_PROPERTY,
CURRENT_SCRIPT,
DEFERRED_LIBRARY_PARTS,
DEFERRED_PART_URIS,
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index 056e267..1ab9ce3 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -98,12 +98,15 @@
Object setRuntimeTypeInfo(Object target, var rti) {
if (JS_GET_FLAG('USE_NEW_RTI')) {
assert(rti != null);
+ var rtiProperty = JS_EMBEDDED_GLOBAL('', ARRAY_RTI_PROPERTY);
+ JS('var', r'#[#] = #', target, rtiProperty, rti);
+ return target;
} else {
assert(rti == null || isJsArray(rti));
+ String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
+ JS('var', r'#[#] = #', target, rtiName, rti);
+ return target;
}
- String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
- JS('var', r'#[#] = #', target, rtiName, rti);
- return target;
}
/// Returns the runtime type information of [target]. The returned value is a
diff --git a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
index 8a77b19..c9a52ea 100644
--- a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
+++ b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
@@ -313,8 +313,7 @@
class NativeTypedData implements TypedData {
/// Returns the byte buffer associated with this object.
@Creates('NativeByteBuffer')
- // May be Null for IE's CanvasPixelArray.
- @Returns('NativeByteBuffer|Null')
+ @Returns('NativeByteBuffer')
final ByteBuffer buffer;
/// Returns the length of this view, in bytes.
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index a0ee070..3676147 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -30,6 +30,7 @@
JsBuiltin,
JsGetName,
RtiUniverseFieldNames,
+ ARRAY_RTI_PROPERTY,
CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME,
RTI_UNIVERSE,
TYPES;
@@ -685,7 +686,7 @@
// IE11 we would have to synthesise a String property-name with almost zero
// chance of conflict.
- var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+ var rti = JS('', r'#[#]', object, JS_EMBEDDED_GLOBAL('', ARRAY_RTI_PROPERTY));
var defaultRti = getJSArrayInteropRti();
// Case 3.
@@ -770,12 +771,19 @@
Type createRuntimeType(Rti rti) {
_Type type = Rti._getCachedRuntimeType(rti);
if (type != null) return type;
- // TODO(fishythefish, https://github.com/dart-lang/language/issues/428) For
- // NNBD transition, canonicalization may be needed. It might be possible to
- // generate a star-free recipe from the canonical recipe and evaluate that.
- type = _Type(rti);
- Rti._setCachedRuntimeType(rti, type);
- return type;
+ if (JS_GET_FLAG('PRINT_LEGACY_STARS')) {
+ return _Type(rti);
+ } else {
+ String recipe = Rti._getCanonicalRecipe(rti);
+ String starErasedRecipe = JS('String', '#.replace(/\\*/g, "")', recipe);
+ if (starErasedRecipe == recipe) {
+ return _Type(rti);
+ }
+ Rti starErasedRti = _Universe.eval(_theUniverse(), starErasedRecipe, true);
+ type = Rti._getCachedRuntimeType(starErasedRti) ?? _Type(starErasedRti);
+ Rti._setCachedRuntimeType(rti, type);
+ return type;
+ }
}
/// Called from generated code in the constant pool.
@@ -786,15 +794,9 @@
/// Implementation of [Type] based on Rti.
class _Type implements Type {
final Rti _rti;
- int _hashCode;
- _Type(this._rti);
-
- int get hashCode => _hashCode ??= Rti._getCanonicalRecipe(_rti).hashCode;
-
- @pragma('dart2js:noInline')
- bool operator ==(other) {
- return (other is _Type) && identical(_rti, other._rti);
+ _Type(this._rti) : assert(Rti._getCachedRuntimeType(_rti) == null) {
+ Rti._setCachedRuntimeType(_rti, this);
}
@override
@@ -818,38 +820,36 @@
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- int kind = Rti._getKind(testRti);
var isFn = RAW_DART_FUNCTION_REF(_generalIsTestImplementation);
- if (isTopType(testRti)) {
+ if (isObjectType(testRti)) {
+ isFn = RAW_DART_FUNCTION_REF(_isObject);
+ Rti._setAsCheckFunction(testRti, RAW_DART_FUNCTION_REF(_asObject));
+ Rti._setTypeCheckFunction(testRti, RAW_DART_FUNCTION_REF(_checkObject));
+ } else if (isTopType(testRti)) {
isFn = RAW_DART_FUNCTION_REF(_isTop);
var asFn = RAW_DART_FUNCTION_REF(_asTop);
Rti._setAsCheckFunction(testRti, asFn);
Rti._setTypeCheckFunction(testRti, asFn);
- } else if (kind == Rti.kindInterface) {
- String key = Rti._getCanonicalRecipe(testRti);
-
- if (JS_GET_NAME(JsGetName.INT_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isInt);
- } else if (JS_GET_NAME(JsGetName.DOUBLE_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isNum);
- } else if (JS_GET_NAME(JsGetName.NUM_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isNum);
- } else if (JS_GET_NAME(JsGetName.STRING_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isString);
- } else if (JS_GET_NAME(JsGetName.BOOL_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isBool);
- } else {
- String name = Rti._getInterfaceName(testRti);
- var arguments = Rti._getInterfaceTypeArguments(testRti);
- if (JS(
- 'bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) {
- String propertyName =
- '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}';
- Rti._setSpecializedTestResource(testRti, propertyName);
- isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty);
- }
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<int>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isInt);
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<double>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isNum);
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<num>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isNum);
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<String>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isString);
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<bool>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isBool);
+ } else if (Rti._getKind(testRti) == Rti.kindInterface) {
+ String name = Rti._getInterfaceName(testRti);
+ var arguments = Rti._getInterfaceTypeArguments(testRti);
+ if (JS('bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) {
+ String propertyName =
+ '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}';
+ Rti._setSpecializedTestResource(testRti, propertyName);
+ isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty);
}
}
@@ -857,11 +857,23 @@
return Rti._isCheck(testRti, object);
}
+bool _nullIs(Rti testRti) {
+ int kind = Rti._getKind(testRti);
+ return isTopType(testRti) ||
+ kind == Rti.kindStar &&
+ Rti._getKind(Rti._getStarArgument(testRti)) == Rti.kindNever ||
+ kind == Rti.kindQuestion ||
+ isNullType(testRti);
+}
+
/// Called from generated code.
bool _generalIsTestImplementation(object) {
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
+ if (JS_GET_FLAG('NNBD') && object == null) {
+ return _nullIs(testRti);
+ }
Rti objectRti = instanceOrFunctionType(object, testRti);
return isSubtype(_theUniverse(), objectRti, testRti);
}
@@ -871,6 +883,9 @@
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
+ if (JS_GET_FLAG('NNBD') && object == null) {
+ return _nullIs(testRti);
+ }
var tag = Rti._getSpecializedTestResource(testRti);
// This test is redundant with getInterceptor below, but getInterceptor does
@@ -886,11 +901,14 @@
/// Called from generated code.
_generalAsCheckImplementation(object) {
- if (object == null) return object;
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- if (Rti._isCheck(testRti, object)) return object;
+ if (object == null) {
+ if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object;
+ } else {
+ if (Rti._isCheck(testRti, object)) return object;
+ }
Rti objectRti = instanceOrFunctionType(object, testRti);
String message =
@@ -900,11 +918,14 @@
/// Called from generated code.
_generalTypeCheckImplementation(object) {
- if (object == null) return object;
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- if (Rti._isCheck(testRti, object)) return object;
+ if (object == null) {
+ if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object;
+ } else {
+ if (Rti._isCheck(testRti, object)) return object;
+ }
Rti objectRti = instanceOrFunctionType(object, testRti);
String message =
@@ -963,6 +984,26 @@
// Specializations can be placed on Rti objects as the _as, _check and _is
// 'methods'. They can also be called directly called from generated code.
+/// Specialization for 'is Object'.
+/// Called from generated code via Rti `_is` method.
+bool _isObject(object) {
+ return !JS_GET_FLAG('NNBD') || object != null;
+}
+
+/// Specialization for 'as Object'.
+/// Called from generated code via Rti `_as` method.
+dynamic _asObject(object) {
+ if (JS_GET_FLAG('LEGACY') || object != null) return object;
+ throw _CastError.forType(object, 'Object');
+}
+
+/// Specialization for check on 'Object'.
+/// Called from generated code via Rti `_check` method.
+dynamic _checkObject(object) {
+ if (JS_GET_FLAG('LEGACY') || object != null) return object;
+ throw _TypeError.forType(object, 'Object');
+}
+
/// Specialization for 'is dynamic' and other top types.
/// Called from generated code via Rti `_is` method.
bool _isTop(object) {
@@ -1196,12 +1237,16 @@
if (kind == Rti.kindStar) {
Rti starArgument = Rti._getStarArgument(rti);
String s = _rtiToString(starArgument, genericContext);
- int argumentKind = Rti._getKind(starArgument);
- if (argumentKind == Rti.kindFunction ||
- argumentKind == Rti.kindGenericFunction) {
- s = '(' + s + ')';
+ if (JS_GET_FLAG('PRINT_LEGACY_STARS')) {
+ int argumentKind = Rti._getKind(starArgument);
+ if (argumentKind == Rti.kindFunction ||
+ argumentKind == Rti.kindGenericFunction) {
+ s = '(' + s + ')';
+ }
+ return s + '*';
+ } else {
+ return s;
}
- return s + '*';
}
if (kind == Rti.kindQuestion) {
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index d93006b..24c2a08 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -123,6 +123,11 @@
// [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
const ISOLATE_TAG = 'isolateTag';
+/// An embedded global that contains the property used to store type information
+/// on JavaScript Array instances. This is a Symbol (except for IE11, where is
+/// is a String).
+const ARRAY_RTI_PROPERTY = 'arrayRti';
+
/// This embedded global (a function) returns the isolate-specific dispatch-tag
/// that is used to accelerate interceptor calls.
const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
@@ -335,21 +340,6 @@
/// String representation of the type of the JavaScriptFunction class.
JS_FUNCTION_CLASS_TYPE_NAME,
- /// String recipe for the [bool] type.
- BOOL_RECIPE,
-
- /// String recipe for the [double] type.
- DOUBLE_RECIPE,
-
- /// String recipe for the [int] type.
- INT_RECIPE,
-
- /// String recipe for the [num] type.
- NUM_RECIPE,
-
- /// String recipe for the [String] type.
- STRING_RECIPE,
-
/// Property name for Rti._is field.
RTI_FIELD_IS,
}
diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart
index 4d21fb2..726f619 100644
--- a/sdk/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart
@@ -456,10 +456,10 @@
int _nativeApiFunctionPointer(String symbol) native "NativeApiFunctionPointer";
@patch
-class NativeApi {
+abstract class NativeApi {
@patch
static Pointer<NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>>
- get nativeApiPostCObject =>
+ get postCObject =>
Pointer.fromAddress(_nativeApiFunctionPointer("Dart_PostCObject"));
@patch
@@ -468,11 +468,10 @@
Int64 Function(
Pointer<Uint8>,
Pointer<NativeFunction<Dart_NativeMessageHandler>>,
- Int8)>> get nativeApiNewNativePort =>
+ Int8)>> get newNativePort =>
Pointer.fromAddress(_nativeApiFunctionPointer("Dart_NewNativePort"));
@patch
- static Pointer<NativeFunction<Int8 Function(Int64)>>
- get nativeApiCloseNativePort => Pointer.fromAddress(
- _nativeApiFunctionPointer("Dart_CloseNativePort"));
+ static Pointer<NativeFunction<Int8 Function(Int64)>> get closeNativePort =>
+ Pointer.fromAddress(_nativeApiFunctionPointer("Dart_CloseNativePort"));
}
diff --git a/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart b/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart
index 05d0d81..cfa7a6d 100644
--- a/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart
+++ b/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart
@@ -35,8 +35,9 @@
// ArgumentsDescriptor layout. Keep in sync with enum in dart_entry.h.
static const int _TYPE_ARGS_LEN = 0;
static const int _COUNT = 1;
- static const int _POSITIONAL_COUNT = 2;
- static const int _FIRST_NAMED_ENTRY = 3;
+ static const int _SIZE = 2;
+ static const int _POSITIONAL_COUNT = 3;
+ static const int _FIRST_NAMED_ENTRY = 4;
// Internal representation of the invocation mirror.
String _functionName;
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index cdb8211..ed95a05 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -689,7 +689,7 @@
}
/**
- * Applies [streamTransformer] to this stream.
+ * Applies [streamTransformer] to this stream.
*
* Returns the transformed stream,
* that is, the result of `streamTransformer.bind(this)`.
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index a834a9e..1fa356d 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -181,6 +181,9 @@
}
/// This class converts JSON objects to strings.
+///
+/// When used as a [StreamTransformer], this converter does not promise
+/// that the input object is emitted as a single string event.
class JsonEncoder extends Converter<Object, String> {
/// The string used for indention.
///
@@ -470,7 +473,14 @@
}
}
-/// This class parses JSON strings and builds the corresponding objects.
+/// This class parses JSON strings and builds the corresponding value.
+///
+/// A JSON input must be the JSON encoding of a single JSON value,
+/// which can be a list or map containing other values.
+///
+/// When used as a [StreamTransformer], the input stream may emit
+/// multiple strings. The concatenation of all of these strings must
+/// be a valid JSON encoding of a single JSON value.
class JsonDecoder extends Converter<String, Object> {
final Function(Object key, Object value) _reviver;
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index dedc8d4..89f5fb5 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -361,8 +361,8 @@
* 1.toStringAsFixed(3); // 1.000
* (4321.12345678).toStringAsFixed(3); // 4321.123
* (4321.12345678).toStringAsFixed(5); // 4321.12346
- * 123456789012345678901.toStringAsFixed(3); // 123456789012345683968.000
- * 1000000000000000000000.toStringAsFixed(3); // 1e+21
+ * 123456789012345.toStringAsFixed(3); // 123456789012345.000
+ * 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000
* 5.25.toStringAsFixed(0); // 5
*/
String toStringAsFixed(int fractionDigits);
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 26f5ff6..f9f0f63 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -629,13 +629,13 @@
typedef Dart_NativeMessageHandler = Void Function(Int64, Pointer<Dart_CObject>);
/// Exposes function pointers to functions in `dart_native_api.h`.
-class NativeApi {
+abstract class NativeApi {
/// A function pointer to
/// `bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message)`
/// in `dart_native_api.h`.
external static Pointer<
NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>>
- get nativeApiPostCObject;
+ get postCObject;
/// A function pointer to
/// ```
@@ -649,11 +649,11 @@
Int64 Function(
Pointer<Uint8>,
Pointer<NativeFunction<Dart_NativeMessageHandler>>,
- Int8)>> get nativeApiNewNativePort;
+ Int8)>> get newNativePort;
/// A function pointer to
/// `bool Dart_CloseNativePort(Dart_Port native_port_id)`
/// in `dart_native_api.h`.
external static Pointer<NativeFunction<Int8 Function(Int64)>>
- get nativeApiCloseNativePort;
+ get closeNativePort;
}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
index 273c38d..9b20059 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -563,6 +563,17 @@
}
@patch
+ factory List.generate(int length, E generator(int index),
+ {bool growable = true}) {
+ final result = JSArray<E>.of(JS('', 'new Array(#)', length));
+ if (!growable) JSArray.markFixedList(result);
+ for (int i = 0; i < length; i++) {
+ result[i] = generator(i);
+ }
+ return result;
+ }
+
+ @patch
factory List.unmodifiable(Iterable elements) {
var list = List<E>.from(elements);
JSArray.markUnmodifiableList(list);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
index 36fb157..86c0b65 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
@@ -142,17 +142,17 @@
// FutureOr<dynamic|void|Object?|Object*> --> dynamic|void|Object?|Object*
if (_isTop(typeArg) ||
- (_isLegacy(typeArg) &&
+ (_jsInstanceOf(typeArg, LegacyType) &&
JS<bool>('!', '#.type === #', typeArg, Object))) {
return typeArg;
}
// FutureOr<Never> --> Future<Never>
- if (typeArg == never_) {
+ if (_equalType(typeArg, Never)) {
return JS('!', '#(#)', getGenericClass(Future), typeArg);
}
// FutureOr<Null> --> Future<Null>?
- if (typeArg == unwrapType(Null)) {
+ if (_equalType(typeArg, Null)) {
return nullable(JS('!', '#(#)', getGenericClass(Future), typeArg));
}
// Otherwise, create the FutureOr<T> type as a normal generic type.
@@ -161,6 +161,7 @@
// this method. This ensures that the we can test a type value returned here
// as a FutureOr because it is equal to 'async.FutureOr` (in the JS).
JS('!', '#[#] = #', genericType, _originalDeclaration, normalize);
+ JS('!', '#(#)', addTypeCaches, genericType);
return genericType;
}
@@ -216,6 +217,7 @@
return value;
}
makeGenericType[$_genericTypeCtor] = $typeConstructor;
+ $addTypeCaches(makeGenericType);
return makeGenericType;
})()''');
@@ -284,7 +286,7 @@
// Note that it is still possible to call typed JS interop methods on
// extension types but the calls must be statically typed.
if (JS('!', '#[#] != null', obj, _extensionType)) return false;
- return JS('!', '!($obj instanceof $Object)');
+ return !_jsInstanceOf(obj, Object);
}
/// Get the type of a method from a type using the stored signature
@@ -299,11 +301,6 @@
if (setters != null) {
var type = JS('', '#[#]', setters, name);
if (type != null) {
- if (JS('!', '# instanceof Array', type)) {
- // The type has metadata attached. Pull out just the type.
- // TODO(jmesserly): remove when we remove mirrors
- return JS('', '#[0]', type);
- }
return type;
}
}
@@ -568,6 +565,16 @@
cast);
}
+/// Pre-initializes types with empty type caches.
+///
+/// Allows us to perform faster lookups on local caches without having to
+/// filter out the prototype chain. Also allows types to remain relatively
+/// monomorphic, which results in faster execution in V8.
+addTypeCaches(type) {
+ JS('', '#[#] = void 0', type, _cachedLegacy);
+ JS('', '#[#] = void 0', type, _cachedNullable);
+}
+
// TODO(jmesserly): should we do this for all interfaces?
/// The well known symbol for testing `is Future`
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index ca682cf..12a41a0 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -300,12 +300,8 @@
return $f.apply($obj, $args);
}
- // TODO(vsm): Remove when we no longer need mirrors metadata.
- // An array is used to encode annotations attached to the type.
- if ($ftype instanceof Array) $ftype = $ftype[0];
-
// Apply type arguments
- if ($ftype instanceof $GenericFunctionType) {
+ if (${_jsInstanceOf(ftype, GenericFunctionType)}) {
let formalCount = $ftype.formalCount;
if ($typeArgs == null) {
@@ -409,39 +405,40 @@
dsetindex(obj, index, value) =>
callMethod(obj, '_set', null, [index, value], null, '[]=');
+/// General implementation of the Dart `is` operator.
+///
+/// Some basic cases are handled directly by the `.is` methods that are attached
+/// directly on types, but any query that requires checking subtyping relations
+/// is handled here.
@notNull
@JSExportName('is')
bool instanceOf(obj, type) {
if (obj == null) {
- return identical(type, unwrapType(Null)) ||
+ return _equalType(type, Null) ||
_isTop(type) ||
- _isNullable(type);
+ _jsInstanceOf(type, NullableType);
}
return isSubtypeOf(getReifiedType(obj), type);
}
+/// General implementation of the Dart `as` operator.
+///
+/// Some basic cases are handled directly by the `.as` methods that are attached
+/// directly on types, but any query that requires checking subtyping relations
+/// is handled here.
@JSExportName('as')
cast(obj, type, @notNull bool isImplicit) {
// We hoist the common case where null is checked against another type here
// for better performance.
- if (obj == null) {
- if (_isLegacy(type) ||
- _isNullType(type) ||
- _isTop(type) ||
- _isNullable(type)) {
- return obj;
- }
- if (_strictSubtypeChecks) {
- return castError(obj, type, isImplicit);
- }
+ if (obj == null && !_strictSubtypeChecks) {
// Check the null comparison cache to avoid emitting repeated warnings.
_nullWarnOnType(type);
return obj;
+ } else {
+ var actual = getReifiedType(obj);
+ if (isSubtypeOf(actual, type)) return obj;
}
- var actual = getReifiedType(obj);
- if (isSubtypeOf(actual, type)) {
- return obj;
- }
+
return castError(obj, type, isImplicit);
}
@@ -754,8 +751,89 @@
Future loadLibrary() => Future.value();
/// Defines lazy statics.
-void defineLazy(to, from) {
+///
+/// TODO: Remove useOldSemantics when non-null-safe late static field behavior is
+/// deprecated.
+void defineLazy(to, from, bool useOldSemantics) {
for (var name in getOwnNamesAndSymbols(from)) {
- defineLazyField(to, name, getOwnPropertyDescriptor(from, name));
+ if (useOldSemantics) {
+ defineLazyFieldOld(to, name, getOwnPropertyDescriptor(from, name));
+ } else {
+ defineLazyField(to, name, getOwnPropertyDescriptor(from, name));
+ }
}
}
+
+/// Defines a lazy static field.
+/// After initial get or set, it will replace itself with a value property.
+// TODO(jmesserly): reusing descriptor objects has been shown to improve
+// performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
+defineLazyField(to, name, desc) => JS('', '''(() => {
+ const initializer = $desc.get;
+ let init = initializer;
+ let value = null;
+ let executed = false;
+ $desc.get = function() {
+ if (init == null) return value;
+ if (!executed) {
+ // Record the field on first execution so we can reset it later if
+ // needed (hot restart).
+ $_resetFields.push(() => {
+ init = initializer;
+ value = null;
+ });
+ executed = true;
+ }
+ value = init();
+ init = null;
+ return value;
+ };
+ $desc.configurable = true;
+ if ($desc.set != null) {
+ $desc.set = function(x) {
+ init = null;
+ value = x;
+ };
+ }
+ return ${defineProperty(to, name, desc)};
+})()''');
+
+/// Defines a lazy static field with pre-null-safety semantics.
+defineLazyFieldOld(to, name, desc) => JS('', '''(() => {
+ const initializer = $desc.get;
+ let init = initializer;
+ let value = null;
+ $desc.get = function() {
+ if (init == null) return value;
+ let f = init;
+ init = $throwCyclicInitializationError;
+ if (f === init) f($name); // throw cycle error
+
+ // On the first (non-cyclic) execution, record the field so we can reset it
+ // later if needed (hot restart).
+ $_resetFields.push(() => {
+ init = initializer;
+ value = null;
+ });
+
+ // Try to evaluate the field, using try+catch to ensure we implement the
+ // correct Dart error semantics.
+ try {
+ value = f();
+ init = null;
+ return value;
+ } catch (e) {
+ init = null;
+ value = null;
+ throw e;
+ }
+ };
+ $desc.configurable = true;
+ if ($desc.set != null) {
+ $desc.set = function(x) {
+ init = null;
+ value = x;
+ };
+ }
+ return ${defineProperty(to, name, desc)};
+})()''');
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
index 0e86859..1f362a8 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
@@ -88,7 +88,7 @@
switch (JS<String>('!', 'typeof #', obj)) {
case "object":
if (obj == null) return JS('', '#', Null);
- if (JS('!', '# instanceof #', obj, Object)) {
+ if (_jsInstanceOf(obj, Object)) {
return JS('', '#.constructor', obj);
}
var result = JS('', '#[#]', obj, _extensionType);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
index 45efd17..4867462 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
@@ -170,7 +170,7 @@
///
/// This is used by [hotRestart] to ensure we don't leak types from previous
/// libraries.
-/// Results made against Null are cached in _nullComparisonMap and must be
+/// Results made against Null are cached in _nullComparisonSet and must be
/// cleared separately.
@notNull
final List<Object> _cacheMaps = JS('!', '[]');
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 54253e1..4f5a6e2 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -5,6 +5,7 @@
/// This library defines the representation of runtime types.
part of dart._runtime;
+@notNull
bool _strictSubtypeChecks = false;
/// Sets the mode of the runtime subtype checks.
@@ -74,19 +75,25 @@
@JSExportName('_check')
check_T(object) => cast(object, this, true);
+
+ DartType() {
+ // Every instance of a DartType requires a set of type caches.
+ JS('', '#(this)', addTypeCaches);
+ }
}
class DynamicType extends DartType {
toString() => 'dynamic';
+ @notNull
@JSExportName('is')
bool is_T(object) => true;
@JSExportName('as')
- as_T(object) => object;
+ Object? as_T(Object? object) => object;
@JSExportName('_check')
- check_T(object) => object;
+ Object? check_T(Object? object) => object;
}
@notNull
@@ -273,28 +280,37 @@
/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@notNull
Object nullable(type) {
- if (_isNullable(type) ||
- _isTop(type) ||
- _isNullType(type) ||
- // Normalize FutureOr<T?>? --> FutureOr<T?>
- // All other runtime FutureOr normalization is in `normalizeFutureOr()`.
- (_isFutureOr(type)) &&
- _isNullable(JS<Object>('!', '#[0]', getGenericArgs(type)))) {
- return type;
- }
- if (type == never_) return unwrapType(Null);
- if (_isLegacy(type)) type = JS<Object>('', '#.type', type);
-
// Check if a nullable version of this type has already been created.
- if (JS<bool>('!', '#.hasOwnProperty(#)', type, _cachedNullable)) {
- return JS<NullableType>('!', '#[#]', type, _cachedNullable);
+ var cached = JS<Object>('', '#[#]', type, _cachedNullable);
+ if (JS<bool>('!', '# !== void 0', cached)) {
+ return cached;
}
+
// Cache a canonical nullable version of this type on this type.
- var cachedType = NullableType(JS<Type>('!', '#', type));
+ Object cachedType = _computeNullable(type);
JS('', '#[#] = #', type, _cachedNullable, cachedType);
return cachedType;
}
+Object _computeNullable(type) {
+ // *? normalizes to ?.
+ if (_jsInstanceOf(type, LegacyType)) {
+ return nullable(JS<Object>('!', '#.type', type));
+ }
+ if (_jsInstanceOf(type, NullableType) ||
+ _isTop(type) ||
+ _equalType(type, Null) ||
+ // Normalize FutureOr<T?>? --> FutureOr<T?>
+ // All other runtime FutureOr normalization is in `normalizeFutureOr()`.
+ ((_isFutureOr(type)) &&
+ _jsInstanceOf(
+ JS<Object>('!', '#[0]', getGenericArgs(type)), NullableType))) {
+ return type;
+ }
+ if (_equalType(type, Never)) return unwrapType(Null);
+ return NullableType(type);
+}
+
/// Returns a legacy (star, *) version of [type].
///
/// The resulting type returned in a normalized form based on the rules from the
@@ -302,19 +318,29 @@
/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@notNull
Object legacy(type) {
- if (_isLegacy(type) || _isNullable(type) || _isTop(type) || _isNullType(type))
- return type;
-
// Check if a legacy version of this type has already been created.
- if (JS<bool>('!', '#.hasOwnProperty(#)', type, _cachedLegacy)) {
- return JS<LegacyType>('!', '#[#]', type, _cachedLegacy);
+ var cached = JS<Object>('', '#[#]', type, _cachedLegacy);
+ if (JS<bool>('!', '# !== void 0', cached)) {
+ return cached;
}
+
// Cache a canonical legacy version of this type on this type.
- var cachedType = LegacyType(JS<Type>('!', '#', type));
+ Object cachedType = _computeLegacy(type);
JS('', '#[#] = #', type, _cachedLegacy, cachedType);
return cachedType;
}
+Object _computeLegacy(type) {
+ // Note: ?* normalizes to ?, so we cache type? at type?[_cachedLegacy].
+ if (_jsInstanceOf(type, LegacyType) ||
+ _jsInstanceOf(type, NullableType) ||
+ _isTop(type) ||
+ _equalType(type, Null)) {
+ return type;
+ }
+ return LegacyType(JS<Type>('!', '#', type));
+}
+
/// A wrapper to identify a nullable (question, ?) type of the form [type]?.
class NullableType extends DartType {
final Type type;
@@ -358,7 +384,7 @@
if (obj == null) {
// Object and Never are the only legacy types that should return true if
// obj is `null`.
- return JS<bool>('!', '# === # || # === #', type, Object, type, never_);
+ return _equalType(type, Object) || _equalType(type, Never);
}
return JS<bool>('!', '#.is(#)', type, obj);
}
@@ -388,6 +414,16 @@
class VoidType extends DartType {
toString() => 'void';
+
+ @notNull
+ @JSExportName('is')
+ bool is_T(object) => true;
+
+ @JSExportName('as')
+ Object? as_T(Object? object) => object;
+
+ @JSExportName('_check')
+ Object? check_T(Object? object) => object;
}
@JSExportName('void')
@@ -427,7 +463,7 @@
///
/// [isNormalized] is true when [type] is known to be in a canonicalized
/// normal form, so the algorithm can directly wrap and return the value.
-Type wrapType(type, {isNormalized = false}) {
+Type wrapType(type, [@notNull bool isNormalized = false]) {
// If we've already wrapped this type once, use the previous wrapper. This
// way, multiple references to the same type return an identical Type.
if (JS('!', '#.hasOwnProperty(#)', type, _typeObject)) {
@@ -435,8 +471,8 @@
}
var result = isNormalized
? _Type(type)
- : (_isLegacy(type)
- ? wrapType(type.type)
+ : (_jsInstanceOf(type, LegacyType)
+ ? wrapType(JS<Object>('!', '#.type', type))
: _canonicalizeNormalizedTypeObject(type));
JS('', '#[#] = #', type, _typeObject, result);
return result;
@@ -447,7 +483,7 @@
/// Used for type object identity. Normalization requires us to return a
/// canonicalized version of the input with all legacy wrappers removed.
Type _canonicalizeNormalizedTypeObject(type) {
- assert(!_isLegacy(type));
+ assert(!_jsInstanceOf(type, LegacyType));
// We don't call _canonicalizeNormalizedTypeObject recursively but call wrap
// + unwrap to handle legacy types automatically and force caching the
// canonicalized type under the _typeObject cache property directly. This
@@ -456,10 +492,10 @@
Object normalizeHelper(a) => unwrapType(wrapType(a));
// GenericFunctionTypeIdentifiers are implicitly normalized.
- if (JS<bool>('!', '# instanceof #', type, GenericFunctionTypeIdentifier)) {
- return wrapType(type, isNormalized: true);
+ if (_jsInstanceOf(type, GenericFunctionTypeIdentifier)) {
+ return wrapType(type, true);
}
- if (JS<bool>('!', '# instanceof #', type, FunctionType)) {
+ if (_jsInstanceOf(type, FunctionType)) {
var normReturnType = normalizeHelper(type.returnType);
var normArgs = type.args.map(normalizeHelper).toList();
if (JS<bool>('!', '#.Object.keys(#).length === 0', global_, type.named) &&
@@ -467,11 +503,11 @@
type.requiredNamed)) {
if (type.optionals.isEmpty) {
var normType = fnType(normReturnType, normArgs);
- return wrapType(normType, isNormalized: true);
+ return wrapType(normType, true);
}
var normOptionals = type.optionals.map(normalizeHelper).toList();
var normType = fnType(normReturnType, normArgs, normOptionals);
- return wrapType(normType, isNormalized: true);
+ return wrapType(normType, true);
}
var normNamed = JS('', '{}');
_transformJSObject(type.named, normNamed, normalizeHelper);
@@ -479,9 +515,9 @@
_transformJSObject(type.requiredNamed, normRequiredNamed, normalizeHelper);
var normType =
fnType(normReturnType, normArgs, normNamed, normRequiredNamed);
- return wrapType(normType, isNormalized: true);
+ return wrapType(normType, true);
}
- if (JS<bool>('!', '# instanceof #', type, GenericFunctionType)) {
+ if (_jsInstanceOf(type, GenericFunctionType)) {
var formals = _getCanonicalTypeFormals(type.typeFormals.length);
var normBounds =
type.instantiateTypeBounds(formals).map(normalizeHelper).toList();
@@ -492,7 +528,7 @@
JS('', '#.push(#)', typeObjectIdKey, normFunc);
var memoizedId = _memoizeArray(_gFnTypeTypeMap, typeObjectIdKey,
() => GenericFunctionTypeIdentifier(formals, normBounds, normFunc));
- return wrapType(memoizedId, isNormalized: true);
+ return wrapType(memoizedId, true);
}
var args = getGenericArgs(type);
var normType;
@@ -503,7 +539,7 @@
var normArgs = args.map(normalizeHelper).toList();
normType = JS('!', '#(...#)', genericClass, normArgs);
}
- return wrapType(normType, isNormalized: true);
+ return wrapType(normType, true);
}
/// Generates new values by applying [transform] to the values of [srcObject],
@@ -947,8 +983,8 @@
bool hasFreeFormal(t) {
// Ignore nullability wrappers.
- if (_isLegacy(t) || _isNullable(t)) {
- return hasFreeFormal(JS<Type>('', '#.type', t));
+ if (_jsInstanceOf(t, LegacyType) || _jsInstanceOf(t, NullableType)) {
+ return hasFreeFormal(JS<Object>('!', '#.type', t));
}
if (partials.containsKey(t)) return true;
// Generic classes and typedefs.
@@ -1076,7 +1112,7 @@
if ($type === void 0) return "undefined type";
if ($type === null) return "null type";
// Non-instance types
- if ($type instanceof $DartType) {
+ if (${_jsInstanceOf(type, DartType)}) {
return $type.toString();
}
@@ -1210,8 +1246,8 @@
bool result = JS('', '#.get(#)', map, t2);
if (JS('!', '# !== void 0', result)) return result;
}
- var validSubtype = _isSubtype(t1, t2, true);
+ var validSubtype = _isSubtype(t1, t2, true);
if (!validSubtype && !_strictSubtypeChecks) {
validSubtype = _isSubtype(t1, t2, false);
if (validSubtype) {
@@ -1228,27 +1264,39 @@
final _subtypeCache = JS('', 'Symbol("_subtypeCache")');
@notNull
-bool _isBottom(type, strictMode) => JS(
- '!', '# === # || (!# && # === #)', type, never_, strictMode, type, bottom);
+bool _isBottom(type, @notNull bool strictMode) =>
+ _equalType(type, Never) || (!strictMode && _equalType(type, Null));
@notNull
bool _isTop(type) {
- if (_isNullable(type)) return JS('!', '# === #', type.type, Object);
+ if (_jsInstanceOf(type, NullableType))
+ return JS('!', '#.type === #', type, Object);
- return JS('!', '# === # || # === #', type, dynamic, type, void_);
+ return _equalType(type, dynamic) || JS('!', '# === #', type, void_);
}
-/// Returns `true` if [type] represents a nullable (question, ?) type.
+/// Wraps the JavaScript `instanceof` operator returning `true` if [type] is an
+/// instance of [cls].
+///
+/// This method is equivalent to:
+///
+/// JS<bool>('!', '# instanceof #', type, cls);
+///
+/// but the code is generated by the compiler directly (a low-tech way of
+/// inlining).
@notNull
-bool _isNullable(type) => JS<bool>('!', '# instanceof #', type, NullableType);
+external bool _jsInstanceOf(type, cls);
-/// Returns `true` if [type] represents a legacy (star, *) type.
+/// Returns `true` if [type] is [cls].
+///
+/// This method is equivalent to:
+///
+/// JS<bool>('!', '# === #', type, unwrapType(cls));
+///
+/// but the code is generated by the compiler directly (a low-tech way of
+/// inlining).
@notNull
-bool _isLegacy(type) => JS<bool>('!', '# instanceof #', type, LegacyType);
-
-/// Returns `true` if [type] is the [Null] type.
-@notNull
-bool _isNullType(type) => JS<bool>('!', '# === #', type, unwrapType(Null));
+external bool _equalType(type, cls);
@notNull
bool _isFutureOr(type) {
@@ -1257,14 +1305,15 @@
getGenericClass(FutureOr));
}
-bool _isSubtype(t1, t2, bool strictMode) => JS('bool', '''(() => {
+@notNull
+bool _isSubtype(t1, t2, bool strictMode) => JS<bool>('!', '''(() => {
if (!$strictMode) {
// Strip nullable types when performing check in weak mode.
// TODO(nshahan) Investigate stripping off legacy types as well.
- if (${_isNullable(t1)}) {
+ if (${_jsInstanceOf(t1, NullableType)}) {
t1 = t1.type;
}
- if (${_isNullable(t2)}) {
+ if (${_jsInstanceOf(t2, NullableType)}) {
t2 = t2.type;
}
}
@@ -1278,12 +1327,12 @@
}
// "Left Top".
- if ($t1 == $dynamic || $t1 == $void_) {
+ if (${_equalType(t1, dynamic)} || $t1 === $void_) {
return $_isSubtype($nullable($Object), $t2, $strictMode);
}
// "Right Object".
- if ($t2 == $Object) {
+ if (${_equalType(t2, Object)}) {
// TODO(nshahan) Need to handle type variables.
// https://github.com/dart-lang/sdk/issues/38816
if (${_isFutureOr(t1)}) {
@@ -1291,11 +1340,11 @@
return $_isSubtype(t1TypeArg, $Object, $strictMode);
}
- if (${_isLegacy(t1)}) {
+ if (${_jsInstanceOf(t1, LegacyType)}) {
return $_isSubtype(t1.type, t2, $strictMode);
}
- if (${_isNullType(t1)} || ${_isNullable(t1)}) {
+ if (${_equalType(t1, Null)} || ${_jsInstanceOf(t1, NullableType)}) {
// Checks for t1 is dynamic or void already performed in "Left Top" test.
return false;
}
@@ -1303,7 +1352,7 @@
}
// "Left Null".
- if ($t1 == $Null) {
+ if (${_equalType(t1, Null)}) {
// TODO(nshahan) Need to handle type variables.
// https://github.com/dart-lang/sdk/issues/38816
if (${_isFutureOr(t2)}) {
@@ -1311,16 +1360,17 @@
return $_isSubtype($Null, t2TypeArg, $strictMode);
}
- return $t2 == $Null || ${_isLegacy(t2)} || ${_isNullable(t2)};
+ return ${_equalType(t2, Null)} || ${_jsInstanceOf(t2, LegacyType)} ||
+ ${_jsInstanceOf(t2, NullableType)};
}
// "Left Legacy".
- if (${_isLegacy(t1)}) {
+ if (${_jsInstanceOf(t1, LegacyType)}) {
return $_isSubtype(t1.type, t2, $strictMode);
}
// "Right Legacy".
- if (${_isLegacy(t2)}) {
+ if (${_jsInstanceOf(t2, LegacyType)}) {
return $_isSubtype(t1, $nullable(t2.type), $strictMode);
}
@@ -1339,11 +1389,12 @@
// (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
let t1Future = ${getGenericClass(Future)}(t1TypeArg);
// Known to handle the case FutureOr<Null> <: Future<Null>.
- return $_isSubtype(t1Future, $t2, $strictMode) && $_isSubtype(t1TypeArg, $t2, $strictMode);
+ return $_isSubtype(t1Future, $t2, $strictMode) &&
+ $_isSubtype(t1TypeArg, $t2, $strictMode);
}
// "Left Nullable".
- if (${_isNullable(t1)}) {
+ if (${_jsInstanceOf(t1, NullableType)}) {
// TODO(nshahan) Need to handle type variables.
// https://github.com/dart-lang/sdk/issues/38816
return $_isSubtype(t1.type, t2, $strictMode) && $_isSubtype($Null, t2, $strictMode);
@@ -1360,7 +1411,7 @@
}
// "Right Nullable".
- if (${_isNullable(t2)}) {
+ if (${_jsInstanceOf(t2, NullableType)}) {
// TODO(nshahan) Need to handle type variables.
// https://github.com/dart-lang/sdk/issues/38816
return $_isSubtype(t1, t2.type, $strictMode) || $_isSubtype(t1, $Null, $strictMode);
@@ -1369,17 +1420,17 @@
// "Traditional" name-based subtype check. Avoid passing
// function types to the class subtype checks, since we don't
// currently distinguish between generic typedefs and classes.
- if (!($t2 instanceof $AbstractFunctionType)) {
+ if (!${_jsInstanceOf(t2, AbstractFunctionType)}) {
// t2 is an interface type.
- if ($t1 instanceof $AbstractFunctionType) {
+ if (${_jsInstanceOf(t1, AbstractFunctionType)}) {
// Function types are only subtypes of interface types `Function` (and top
// types, handled already above).
- return $t2 === $Function;
+ return ${_equalType(t2, Function)};
}
// All JS types are subtypes of anonymous JS types.
- if ($t1 === $jsobject && $t2 instanceof $AnonymousJSType) {
+ if ($t1 === $jsobject && ${_jsInstanceOf(t2, AnonymousJSType)}) {
return true;
}
@@ -1388,13 +1439,13 @@
}
// Function subtyping.
- if (!($t1 instanceof $AbstractFunctionType)) {
+ if (!${_jsInstanceOf(t1, AbstractFunctionType)}) {
return false;
}
// Handle generic functions.
- if ($t1 instanceof $GenericFunctionType) {
- if (!($t2 instanceof $GenericFunctionType)) {
+ if (${_jsInstanceOf(t1, GenericFunctionType)}) {
+ if (!${_jsInstanceOf(t2, GenericFunctionType)}) {
return false;
}
@@ -1438,7 +1489,7 @@
$t1 = $t1.instantiate(fresh);
$t2 = $t2.instantiate(fresh);
- } else if ($t2 instanceof $GenericFunctionType) {
+ } else if (${_jsInstanceOf(t2, GenericFunctionType)}) {
return false;
}
@@ -1449,24 +1500,24 @@
bool _isInterfaceSubtype(t1, t2, strictMode) => JS('', '''(() => {
// If we have lazy JS types, unwrap them. This will effectively
// reduce to a prototype check below.
- if ($t1 instanceof $LazyJSType) $t1 = $t1.rawJSTypeForCheck();
- if ($t2 instanceof $LazyJSType) $t2 = $t2.rawJSTypeForCheck();
+ if (${_jsInstanceOf(t1, LazyJSType)}) $t1 = $t1.rawJSTypeForCheck();
+ if (${_jsInstanceOf(t2, LazyJSType)}) $t2 = $t2.rawJSTypeForCheck();
if ($t1 === $t2) {
return true;
}
- if ($t1 === $Object) {
+ if (${_equalType(t1, Object)}) {
return false;
}
// Classes cannot subtype `Function` or vice versa.
- if ($t1 === $Function || $t2 === $Function) {
+ if (${_equalType(t1, Function)} || ${_equalType(t2, Function)}) {
return false;
}
// If t1 is a JS Object, we may not hit core.Object.
if ($t1 == null) {
- return $t2 == $Object || $t2 == $dynamic;
+ return ${_equalType(t2, Object)} || ${_equalType(t2, dynamic)};
}
// Check if t1 and t2 have the same raw type. If so, check covariance on
@@ -1733,7 +1784,7 @@
if (_isTop(supertype)) return true;
// `Null` is a subtype match for any type `Q` under no constraints.
// Note that nullable types will change this.
- if (_isNullType(subtype)) return true;
+ if (_equalType(subtype, Null)) return true;
// Handle FutureOr<T> union type.
if (_isFutureOr(subtype)) {
@@ -1840,8 +1891,7 @@
// TODO(paulberry): implement this case.
if (subtype is FunctionType) {
if (supertype is! FunctionType) {
- if (identical(supertype, unwrapType(Function)) ||
- identical(supertype, unwrapType(Object))) {
+ if (_equalType(supertype, Function) || _equalType(supertype, Object)) {
return true;
} else {
return false;
@@ -1857,7 +1907,7 @@
bool _isTop(Object type) =>
identical(type, _dynamic) ||
identical(type, void_) ||
- identical(type, unwrapType(Object));
+ _equalType(type, Object);
}
/// A constraint on a type parameter that we're inferring.
@@ -1907,7 +1957,7 @@
/// contain different generic type arguments.
Object? _getMatchingSupertype(Object? subtype, Object supertype) {
if (identical(subtype, supertype)) return supertype;
- if (subtype == null || subtype == unwrapType(Object)) return null;
+ if (subtype == null || _equalType(subtype, Object)) return null;
var subclass = getGenericClass(subtype);
var superclass = getGenericClass(supertype);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
index c763ada..07a2faa 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
@@ -51,54 +51,15 @@
return JS('', '#.concat(#)', names, symbols);
}
+/// Returns the value of field `name` on `obj`.
+///
+/// We use this instead of obj[name] since obj[name] checks the entire
+/// prototype chain instead of just `obj`.
safeGetOwnProperty(obj, name) {
- var desc = getOwnPropertyDescriptor(obj, name);
- if (desc != null) return JS('', '#.value', desc);
+ if (JS<bool>('!', '#.hasOwnProperty(#)', obj, name))
+ return JS<Object>('', '#[#]', obj, name);
}
-/// Defines a lazy static field.
-/// After initial get or set, it will replace itself with a value property.
-// TODO(jmesserly): reusing descriptor objects has been shown to improve
-// performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
-defineLazyField(to, name, desc) => JS('', '''(() => {
- const initializer = $desc.get;
- let init = initializer;
- let value = null;
- $desc.get = function() {
- if (init == null) return value;
- let f = init;
- init = $throwCyclicInitializationError;
- if (f === init) f($name); // throw cycle error
-
- // On the first (non-cyclic) execution, record the field so we can reset it
- // later if needed (hot restart).
- $_resetFields.push(() => {
- init = initializer;
- value = null;
- });
-
- // Try to evaluate the field, using try+catch to ensure we implement the
- // correct Dart error semantics.
- try {
- value = f();
- init = null;
- return value;
- } catch (e) {
- init = null;
- value = null;
- throw e;
- }
- };
- $desc.configurable = true;
- if ($desc.set != null) {
- $desc.set = function(x) {
- init = null;
- value = x;
- };
- }
- return ${defineProperty(to, name, desc)};
-})()''');
-
copyTheseProperties(to, from, names) {
for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
var name = JS('', '#[#]', names, i);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
index 3e28657..3a7f409 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
@@ -311,8 +311,7 @@
class NativeTypedData implements TypedData {
/// Returns the byte buffer associated with this object.
@Creates('NativeByteBuffer')
- // May be Null for IE's CanvasPixelArray.
- @Returns('NativeByteBuffer|Null')
+ @Returns('NativeByteBuffer')
external ByteBuffer get buffer;
/// Returns the length of this view, in bytes.
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart
index 9076ef2..347b20b 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart
@@ -194,7 +194,7 @@
// We cannot create the backing map on creation since hashCode interceptors
// have not been defined when constants are created.
Map<K, V> _getMap() {
- LinkedHashMap<K, V> backingMap = JS('LinkedHashMap|Null', r'#.$map', this);
+ LinkedHashMap<K, V>? backingMap = JS('LinkedHashMap|Null', r'#.$map', this);
if (backingMap == null) {
backingMap = new JsLinkedHashMap<K, V>();
fillLiteralMap(_jsData, backingMap);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
index fa12afb..10418cf 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
@@ -45,7 +45,7 @@
}
@patch
-int identityHashCode(Object object) => objectHashCode(object);
+int identityHashCode(Object? object) => objectHashCode(object);
// Patch for Object implementation.
@patch
@@ -105,7 +105,7 @@
Expando([String? name])
: this.name = name,
_jsWeakMapOrKey = JS('bool', 'typeof WeakMap == "function"')
- ? JS('=Object|Null', 'new WeakMap()')
+ ? JS('=Object', 'new WeakMap()')
: _createKey();
@patch
@@ -451,6 +451,18 @@
}
@patch
+ factory List.generate(int length, E generator(int index),
+ {bool growable = true}) {
+ final result = growable
+ ? new JSArray<E>.growable(length)
+ : new JSArray<E>.fixed(length);
+ for (int i = 0; i < length; i++) {
+ result[i] = generator(i);
+ }
+ return result;
+ }
+
+ @patch
factory List.unmodifiable(Iterable elements) {
var result = List<E>.from(elements, growable: false);
return makeFixedListUnmodifiable(result);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
index 70ca49e..808be98 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
@@ -110,7 +110,7 @@
dispatchRecordInterceptor(record) => JS('', '#.i', record);
dispatchRecordProto(record) => JS('', '#.p', record);
dispatchRecordExtension(record) => JS('', '#.e', record);
-dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record);
+bool? dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record);
/// Returns the interceptor for a native class instance. Used by
/// [getInterceptor].
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
index ca5caab..8c81b95 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
@@ -6,6 +6,7 @@
import 'dart:_js_embedded_names'
show
+ ARRAY_RTI_PROPERTY,
CURRENT_SCRIPT,
DEFERRED_LIBRARY_PARTS,
DEFERRED_PART_URIS,
@@ -128,8 +129,8 @@
/// Given a raw constructor name, return the unminified name, if available,
/// otherwise tag the name with `minified:`.
String unminifyOrTag(String rawClassName) {
- String preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName);
- if (preserved is String) return preserved;
+ String? preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName);
+ if (preserved != null) return preserved;
if (JS_GET_FLAG('MINIFIED')) return 'minified:${rawClassName}';
return rawClassName;
}
@@ -398,7 +399,7 @@
class Primitives {
static int objectHashCode(object) {
- int hash = JS('int|Null', r'#.$identityHash', object);
+ int? hash = JS('int|Null', r'#.$identityHash', object);
if (hash == null) {
hash = JS('int', '(Math.random() * 0x3fffffff) | 0');
JS('void', r'#.$identityHash = #', object, hash);
@@ -786,7 +787,7 @@
// Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
// We extract this name using a regexp.
var d = lazyAsJsDate(receiver);
- List match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d);
+ List? match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d);
if (match != null) return match[1];
// Internet Explorer 10+ emits the zone name without parenthesis:
@@ -1575,7 +1576,7 @@
// Look for the special pattern \$camelCase\$ (all the $ symbols
// have been escaped already), as we will soon be inserting
// regular expression syntax that we want interpreted by RegExp.
- List<String> match =
+ List<String>? match =
JS('JSExtendableArray|Null', r'#.match(/\\\$[a-zA-Z]+\\\$/g)', message);
if (match == null) match = [];
@@ -1926,7 +1927,7 @@
return ex;
}
-String tryStringifyException(ex) {
+String? tryStringifyException(ex) {
// Since this function is called from [unwrapException] which is called from
// code injected into a catch-clause, use JavaScript try-catch to avoid a
// potential loop if stringifying crashes.
@@ -1950,7 +1951,7 @@
return exception.stackTrace;
}
if (exception == null) return new _StackTrace(exception);
- _StackTrace trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception);
+ _StackTrace? trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception);
if (trace != null) return trace;
trace = new _StackTrace(exception);
return JS('_StackTrace', r'#.$cachedTrace = #', exception, trace);
@@ -2095,7 +2096,7 @@
static fromTearOff(
receiver,
List functions,
- int applyTrampolineIndex,
+ int? applyTrampolineIndex,
var reflectionInfo,
bool isStatic,
bool isIntercepted,
@@ -2116,8 +2117,8 @@
// TODO(ahe): All the place below using \$ should be rewritten to go
// through the namer.
var function = JS('', '#[#]', functions, 0);
- String name = JS('String|Null', '#.\$stubName', function);
- String callName = JS('String|Null', '#[#]', function,
+ String? name = JS('String|Null', '#.\$stubName', function);
+ String? callName = JS('String|Null', '#[#]', function,
JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY));
// This variable holds either an index into the types-table, or a function
@@ -2301,7 +2302,7 @@
}
static cspForwardCall(
- int arity, bool isSuperCall, String stubName, function) {
+ int arity, bool isSuperCall, String? stubName, function) {
var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf);
// Handle intercepted stub-names with the default slow case.
if (isSuperCall) arity = -1;
@@ -2383,7 +2384,7 @@
static forwardCallTo(receiver, function, bool isIntercepted) {
if (isIntercepted) return forwardInterceptedCallTo(receiver, function);
- String stubName = JS('String|Null', '#.\$stubName', function);
+ String? stubName = JS('String|Null', '#.\$stubName', function);
int arity = JS('int', '#.length', function);
var lookedUpFunction = JS('', '#[#]', receiver, stubName);
// The receiver[stubName] may not be equal to the function if we try to
@@ -2420,7 +2421,7 @@
}
static cspForwardInterceptedCall(
- int arity, bool isSuperCall, String name, function) {
+ int arity, bool isSuperCall, String? name, function) {
var getSelf = RAW_DART_FUNCTION_REF(BoundClosure.selfOf);
var getReceiver = RAW_DART_FUNCTION_REF(BoundClosure.receiverOf);
// Handle intercepted stub-names with the default slow case.
@@ -2515,7 +2516,7 @@
static forwardInterceptedCallTo(receiver, function) {
String selfField = BoundClosure.selfFieldName();
String receiverField = BoundClosure.receiverFieldName();
- String stubName = JS('String|Null', '#.\$stubName', function);
+ String? stubName = JS('String|Null', '#.\$stubName', function);
int arity = JS('int', '#.length', function);
bool isCsp = JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');
var lookedUpFunction = JS('', '#[#]', receiver, stubName);
@@ -2587,7 +2588,7 @@
class StaticClosure extends TearOffClosure {
String toString() {
- String name =
+ String? name =
JS('String|Null', '#[#]', this, STATIC_FUNCTION_NAME_PROPERTY_NAME);
if (name == null) return 'Closure of unknown static method';
return "Closure '${unminifyOrTag(name)}'";
@@ -3241,7 +3242,7 @@
// by an index. There are two arrays, one that maps the index into a Uri and
// another that maps the index to a hash.
var partsMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_PARTS);
- List indexes = JS('JSExtendableArray|Null', '#[#]', partsMap, loadId);
+ List? indexes = JS('JSExtendableArray|Null', '#[#]', partsMap, loadId);
if (indexes == null) return new Future.value(null);
List<String> uris = <String>[];
List<String> hashes = <String>[];
@@ -3323,7 +3324,7 @@
String? _computeCspNonce() {
var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
if (currentScript == null) return null;
- String nonce = JS('String|Null', '#.nonce', currentScript);
+ String? nonce = JS('String|Null', '#.nonce', currentScript);
return (nonce != null && nonce != '')
? nonce
: JS('String|Null', '#.getAttribute("nonce")', currentScript);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart
index 0342836..10efacf 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart
@@ -148,7 +148,7 @@
/// This is used, for example, to return unmangled names from TypeImpl.toString
/// *if* names are being preserved for other reasons (use of dart:mirrors, for
/// example).
-String unmangleGlobalNameIfPreservedAnyways(String name) {
+String? unmangleGlobalNameIfPreservedAnyways(String name) {
var names = JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES);
return JS('String|Null', '#', JsCache.fetch(names, name));
}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
index 1af8d71..d484342 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
@@ -96,12 +96,15 @@
Object setRuntimeTypeInfo(Object target, var rti) {
if (JS_GET_FLAG('USE_NEW_RTI')) {
assert(rti != null);
+ var rtiProperty = JS_EMBEDDED_GLOBAL('', ARRAY_RTI_PROPERTY);
+ JS('var', r'#[#] = #', target, rtiProperty, rti);
+ return target;
} else {
assert(rti == null || isJsArray(rti));
+ String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
+ JS('var', r'#[#] = #', target, rtiName, rti);
+ return target;
}
- String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
- JS('var', r'#[#] = #', target, rtiName, rti);
- return target;
}
/// Returns the runtime type information of [target]. The returned value is a
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
index e73a040..39d527b 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
@@ -311,8 +311,7 @@
class NativeTypedData implements TypedData {
/// Returns the byte buffer associated with this object.
@Creates('NativeByteBuffer')
- // May be Null for IE's CanvasPixelArray.
- @Returns('NativeByteBuffer|Null')
+ @Returns('NativeByteBuffer')
ByteBuffer get buffer native;
/// Returns the length of this view, in bytes.
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart
index af0611b..9560250 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart
@@ -110,7 +110,7 @@
}
RegExpMatch? firstMatch(String string) {
- JSArray m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp,
+ JSArray? m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp,
checkString(string));
if (m == null) return null;
return new _MatchImplementation(this, m);
@@ -138,7 +138,7 @@
RegExpMatch? _execGlobal(String string, int start) {
Object regexp = _nativeGlobalVersion;
JS('void', '#.lastIndex = #', regexp, start);
- JSArray match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string);
+ JSArray? match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string);
if (match == null) return null;
return new _MatchImplementation(this, match);
}
@@ -146,7 +146,7 @@
RegExpMatch? _execAnchored(String string, int start) {
Object regexp = _nativeAnchoredVersion;
JS('void', '#.lastIndex = #', regexp, start);
- JSArray match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string);
+ JSArray? match = JS('JSExtendableArray|Null', '#.exec(#)', regexp, string);
if (match == null) return null;
// If the last capture group participated, the original regexp did not
// match at the start position.
@@ -194,14 +194,14 @@
// The JS below changes the static type to avoid an implicit cast.
// TODO(sra): Find a nicer way to do this, e.g. unsafeCast.
- String group(int index) => JS('String|Null', '#', _match[index]);
+ String? group(int index) => JS('String|Null', '#', _match[index]);
- String operator [](int index) => group(index);
+ String? operator [](int index) => group(index);
int get groupCount => _match.length - 1;
- List<String> groups(List<int> groups) {
- List<String> out = [];
+ List<String?> groups(List<int> groups) {
+ List<String?> out = [];
for (int i in groups) {
out.add(group(i));
}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
index 67f8325..ddbade4 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -28,6 +28,7 @@
JsBuiltin,
JsGetName,
RtiUniverseFieldNames,
+ ARRAY_RTI_PROPERTY,
CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME,
RTI_UNIVERSE,
TYPES;
@@ -110,7 +111,7 @@
@pragma('dart2js:noElision')
dynamic _precomputed1;
- static Object _getPrecomputed1(Rti rti) => rti._precomputed1;
+ static Object? _getPrecomputed1(Rti rti) => rti._precomputed1;
static void _setPrecomputed1(Rti rti, precomputed) {
rti._precomputed1 = precomputed;
@@ -118,7 +119,7 @@
static Rti _getQuestionFromStar(universe, Rti rti) {
assert(_getKind(rti) == kindStar);
- Rti question = _castToRtiOrNull(_getPrecomputed1(rti));
+ Rti? question = _castToRtiOrNull(_getPrecomputed1(rti));
if (question == null) {
question =
_Universe._lookupQuestionRti(universe, _getStarArgument(rti), true);
@@ -129,7 +130,7 @@
static Rti _getFutureFromFutureOr(universe, Rti rti) {
assert(_getKind(rti) == kindFutureOr);
- Rti future = _castToRtiOrNull(_getPrecomputed1(rti));
+ Rti? future = _castToRtiOrNull(_getPrecomputed1(rti));
if (future == null) {
future = _Universe._lookupFutureRti(universe, _getFutureOrArgument(rti));
Rti._setPrecomputed1(rti, future);
@@ -155,7 +156,7 @@
// The Type object corresponding to this Rti.
Object? _cachedRuntimeType;
- static _Type _getCachedRuntimeType(Rti rti) =>
+ static _Type? _getCachedRuntimeType(Rti rti) =>
JS('_Type|Null', '#', rti._cachedRuntimeType);
static void _setCachedRuntimeType(Rti rti, _Type type) {
rti._cachedRuntimeType = type;
@@ -426,7 +427,7 @@
/// Called from generated code.
@pragma('dart2js:noInline')
Rti? instantiatedGenericFunctionType(
- Rti genericFunctionRti, Rti instantiationRti) {
+ Rti? genericFunctionRti, Rti instantiationRti) {
// If --lax-runtime-type-to-string is enabled and we never check the function
// type, then the function won't have a signature, so its RTI will be null. In
// this case, there is nothing to instantiate, so we return `null` and the
@@ -444,7 +445,7 @@
String key = Rti._getCanonicalRecipe(instantiationRti);
var probe = _Utils.mapGet(cache, key);
if (probe != null) return _castToRti(probe);
- Rti? rti = _instantiate(_theUniverse(),
+ Rti rti = _instantiate(_theUniverse(),
Rti._getGenericFunctionBase(genericFunctionRti), typeArguments, 0);
_Utils.mapSet(cache, key, rti);
return rti;
@@ -458,7 +459,7 @@
/// [depth] is the number of subsequent generic function parameters that are in
/// scope. This is subtracted off the de Bruijn index for the type parameter to
/// arrive at an potential index into [typeArguments].
-Rti? _instantiate(universe, Rti rti, Object typeArguments, int depth) {
+Rti _instantiate(universe, Rti rti, Object typeArguments, int depth) {
int kind = Rti._getKind(rti);
switch (kind) {
case Rti.kindErased:
@@ -470,19 +471,19 @@
case Rti.kindStar:
Rti baseType = _castToRti(Rti._getPrimary(rti));
Rti instantiatedBaseType =
- _instantiate(universe, baseType, typeArguments, depth)!;
+ _instantiate(universe, baseType, typeArguments, depth);
if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
return _Universe._lookupStarRti(universe, instantiatedBaseType, true);
case Rti.kindQuestion:
Rti baseType = _castToRti(Rti._getPrimary(rti));
Rti instantiatedBaseType =
- _instantiate(universe, baseType, typeArguments, depth)!;
+ _instantiate(universe, baseType, typeArguments, depth);
if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
return _Universe._lookupQuestionRti(universe, instantiatedBaseType, true);
case Rti.kindFutureOr:
Rti baseType = _castToRti(Rti._getPrimary(rti));
Rti instantiatedBaseType =
- _instantiate(universe, baseType, typeArguments, depth)!;
+ _instantiate(universe, baseType, typeArguments, depth);
if (_Utils.isIdentical(instantiatedBaseType, baseType)) return rti;
return _Universe._lookupFutureOrRti(universe, instantiatedBaseType, true);
case Rti.kindInterface:
@@ -496,8 +497,7 @@
instantiatedInterfaceTypeArguments);
case Rti.kindBinding:
Rti base = Rti._getBindingBase(rti);
- Rti instantiatedBase =
- _instantiate(universe, base, typeArguments, depth)!;
+ Rti instantiatedBase = _instantiate(universe, base, typeArguments, depth);
Object arguments = Rti._getBindingArguments(rti);
Object instantiatedArguments =
_instantiateArray(universe, arguments, typeArguments, depth);
@@ -508,7 +508,7 @@
case Rti.kindFunction:
Rti returnType = Rti._getReturnType(rti);
Rti instantiatedReturnType =
- _instantiate(universe, returnType, typeArguments, depth)!;
+ _instantiate(universe, returnType, typeArguments, depth);
_FunctionParameters functionParameters = Rti._getFunctionParameters(rti);
_FunctionParameters instantiatedFunctionParameters =
_instantiateFunctionParameters(
@@ -524,15 +524,17 @@
Object instantiatedBounds =
_instantiateArray(universe, bounds, typeArguments, depth);
Rti base = Rti._getGenericFunctionBase(rti);
- Rti instantiatedBase =
- _instantiate(universe, base, typeArguments, depth)!;
+ Rti instantiatedBase = _instantiate(universe, base, typeArguments, depth);
if (_Utils.isIdentical(instantiatedBounds, bounds) &&
_Utils.isIdentical(instantiatedBase, base)) return rti;
return _Universe._lookupGenericFunctionRti(
universe, instantiatedBase, instantiatedBounds);
case Rti.kindGenericFunctionParameter:
int index = Rti._getGenericFunctionParameterIndex(rti);
- if (index < depth) return null;
+ if (index < depth) {
+ throw AssertionError(
+ 'Unexpected index $index at instantiation depth $depth');
+ }
return _castToRti(_Utils.arrayAt(typeArguments, index - depth));
default:
throw AssertionError(
@@ -547,7 +549,7 @@
Object result = JS('', '[]');
for (int i = 0; i < length; i++) {
Rti rti = _castToRti(_Utils.arrayAt(rtiArray, i));
- Rti instantiatedRti = _instantiate(universe, rti, typeArguments, depth)!;
+ Rti instantiatedRti = _instantiate(universe, rti, typeArguments, depth);
if (_Utils.isNotIdentical(instantiatedRti, rti)) {
changed = true;
}
@@ -565,7 +567,7 @@
for (int i = 0; i < length; i += 2) {
String name = _Utils.asString(_Utils.arrayAt(namedArray, i));
Rti rti = _castToRti(_Utils.arrayAt(namedArray, i + 1));
- Rti? instantiatedRti = _instantiate(universe, rti, typeArguments, depth);
+ Rti instantiatedRti = _instantiate(universe, rti, typeArguments, depth);
if (_Utils.isNotIdentical(instantiatedRti, rti)) {
changed = true;
}
@@ -685,7 +687,7 @@
// IE11 we would have to synthesise a String property-name with almost zero
// chance of conflict.
- var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+ var rti = JS('', r'#[#]', object, JS_EMBEDDED_GLOBAL('', ARRAY_RTI_PROPERTY));
var defaultRti = getJSArrayInteropRti();
// Case 3.
@@ -768,14 +770,21 @@
/// Called from generated code.
Type createRuntimeType(Rti rti) {
- _Type type = Rti._getCachedRuntimeType(rti);
+ _Type? type = Rti._getCachedRuntimeType(rti);
if (type != null) return type;
- // TODO(fishythefish, https://github.com/dart-lang/language/issues/428) For
- // NNBD transition, canonicalization may be needed. It might be possible to
- // generate a star-free recipe from the canonical recipe and evaluate that.
- type = _Type(rti);
- Rti._setCachedRuntimeType(rti, type);
- return type;
+ if (JS_GET_FLAG('PRINT_LEGACY_STARS')) {
+ return _Type(rti);
+ } else {
+ String recipe = Rti._getCanonicalRecipe(rti);
+ String starErasedRecipe = JS('String', '#.replace(/\\*/g, "")', recipe);
+ if (starErasedRecipe == recipe) {
+ return _Type(rti);
+ }
+ Rti starErasedRti = _Universe.eval(_theUniverse(), starErasedRecipe, true);
+ type = Rti._getCachedRuntimeType(starErasedRti) ?? _Type(starErasedRti);
+ Rti._setCachedRuntimeType(rti, type);
+ return type;
+ }
}
/// Called from generated code in the constant pool.
@@ -786,15 +795,9 @@
/// Implementation of [Type] based on Rti.
class _Type implements Type {
final Rti _rti;
- int? _hashCode;
- _Type(this._rti);
-
- int get hashCode => _hashCode ??= Rti._getCanonicalRecipe(_rti).hashCode;
-
- @pragma('dart2js:noInline')
- bool operator ==(other) {
- return (other is _Type) && identical(_rti, other._rti);
+ _Type(this._rti) : assert(Rti._getCachedRuntimeType(_rti) == null) {
+ Rti._setCachedRuntimeType(_rti, this);
}
@override
@@ -818,38 +821,36 @@
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- int kind = Rti._getKind(testRti);
var isFn = RAW_DART_FUNCTION_REF(_generalIsTestImplementation);
- if (isTopType(testRti)) {
+ if (isObjectType(testRti)) {
+ isFn = RAW_DART_FUNCTION_REF(_isObject);
+ Rti._setAsCheckFunction(testRti, RAW_DART_FUNCTION_REF(_asObject));
+ Rti._setTypeCheckFunction(testRti, RAW_DART_FUNCTION_REF(_checkObject));
+ } else if (isTopType(testRti)) {
isFn = RAW_DART_FUNCTION_REF(_isTop);
var asFn = RAW_DART_FUNCTION_REF(_asTop);
Rti._setAsCheckFunction(testRti, asFn);
Rti._setTypeCheckFunction(testRti, asFn);
- } else if (kind == Rti.kindInterface) {
- String key = Rti._getCanonicalRecipe(testRti);
-
- if (JS_GET_NAME(JsGetName.INT_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isInt);
- } else if (JS_GET_NAME(JsGetName.DOUBLE_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isNum);
- } else if (JS_GET_NAME(JsGetName.NUM_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isNum);
- } else if (JS_GET_NAME(JsGetName.STRING_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isString);
- } else if (JS_GET_NAME(JsGetName.BOOL_RECIPE) == key) {
- isFn = RAW_DART_FUNCTION_REF(_isBool);
- } else {
- String name = Rti._getInterfaceName(testRti);
- var arguments = Rti._getInterfaceTypeArguments(testRti);
- if (JS(
- 'bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) {
- String propertyName =
- '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}';
- Rti._setSpecializedTestResource(testRti, propertyName);
- isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty);
- }
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<int>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isInt);
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<double>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isNum);
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<num>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isNum);
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<String>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isString);
+ } else if (_Utils.isIdentical(testRti, TYPE_REF<bool>())) {
+ isFn = RAW_DART_FUNCTION_REF(_isBool);
+ } else if (Rti._getKind(testRti) == Rti.kindInterface) {
+ String name = Rti._getInterfaceName(testRti);
+ var arguments = Rti._getInterfaceTypeArguments(testRti);
+ if (JS('bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) {
+ String propertyName =
+ '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}';
+ Rti._setSpecializedTestResource(testRti, propertyName);
+ isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty);
}
}
@@ -857,11 +858,22 @@
return Rti._isCheck(testRti, object);
}
+bool _nullIs(Rti testRti) {
+ int kind = Rti._getKind(testRti);
+ return isTopType(testRti) ||
+ _Utils.isIdentical(testRti, LEGACY_TYPE_REF<Never>()) ||
+ kind == Rti.kindQuestion ||
+ isNullType(testRti);
+}
+
/// Called from generated code.
bool _generalIsTestImplementation(object) {
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
+ if (JS_GET_FLAG('NNBD') && object == null) {
+ return _nullIs(testRti);
+ }
Rti objectRti = instanceOrFunctionType(object, testRti);
return isSubtype(_theUniverse(), objectRti, testRti);
}
@@ -871,6 +883,9 @@
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
+ if (JS_GET_FLAG('NNBD') && object == null) {
+ return _nullIs(testRti);
+ }
var tag = Rti._getSpecializedTestResource(testRti);
// This test is redundant with getInterceptor below, but getInterceptor does
@@ -886,11 +901,14 @@
/// Called from generated code.
_generalAsCheckImplementation(object) {
- if (object == null) return object;
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- if (Rti._isCheck(testRti, object)) return object;
+ if (object == null) {
+ if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object;
+ } else {
+ if (Rti._isCheck(testRti, object)) return object;
+ }
Rti objectRti = instanceOrFunctionType(object, testRti);
String message =
@@ -900,11 +918,14 @@
/// Called from generated code.
_generalTypeCheckImplementation(object) {
- if (object == null) return object;
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- if (Rti._isCheck(testRti, object)) return object;
+ if (object == null) {
+ if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object;
+ } else {
+ if (Rti._isCheck(testRti, object)) return object;
+ }
Rti objectRti = instanceOrFunctionType(object, testRti);
String message =
@@ -963,6 +984,26 @@
// Specializations can be placed on Rti objects as the _as, _check and _is
// 'methods'. They can also be called directly called from generated code.
+/// Specialization for 'is Object'.
+/// Called from generated code via Rti `_is` method.
+bool _isObject(object) {
+ return !JS_GET_FLAG('NNBD') || object != null;
+}
+
+/// Specialization for 'as Object'.
+/// Called from generated code via Rti `_as` method.
+dynamic _asObject(object) {
+ if (JS_GET_FLAG('LEGACY') || object != null) return object;
+ throw _CastError.forType(object, 'Object');
+}
+
+/// Specialization for check on 'Object'.
+/// Called from generated code via Rti `_check` method.
+dynamic _checkObject(object) {
+ if (JS_GET_FLAG('LEGACY') || object != null) return object;
+ throw _TypeError.forType(object, 'Object');
+}
+
/// Specialization for 'is dynamic' and other top types.
/// Called from generated code via Rti `_is` method.
bool _isTop(object) {
@@ -983,7 +1024,7 @@
/// Specialization for 'as bool?'.
/// Called from generated code.
-bool /*?*/ _asBoolNullable(object) {
+bool? _asBoolNullable(object) {
if (_isBool(object)) return _Utils.asBool(object);
if (object == null) return object;
throw _CastError.forType(object, 'bool');
@@ -991,7 +1032,7 @@
/// Specialization for check on 'bool?'.
/// Called from generated code.
-bool /*?*/ _checkBoolNullable(object) {
+bool? _checkBoolNullable(object) {
if (_isBool(object)) return _Utils.asBool(object);
if (object == null) return object;
throw _TypeError.forType(object, 'bool');
@@ -999,7 +1040,7 @@
/// Specialization for 'as double?'.
/// Called from generated code.
-double /*?*/ _asDoubleNullable(object) {
+double? _asDoubleNullable(object) {
if (_isNum(object)) return _Utils.asDouble(object);
if (object == null) return object;
throw _CastError.forType(object, 'double');
@@ -1007,7 +1048,7 @@
/// Specialization for check on 'double?'.
/// Called from generated code.
-double /*?*/ _checkDoubleNullable(object) {
+double? _checkDoubleNullable(object) {
if (_isNum(object)) return _Utils.asDouble(object);
if (object == null) return object;
throw _TypeError.forType(object, 'double');
@@ -1022,7 +1063,7 @@
/// Specialization for 'as int?'.
/// Called from generated code.
-int /*?*/ _asIntNullable(object) {
+int? _asIntNullable(object) {
if (_isInt(object)) return _Utils.asInt(object);
if (object == null) return object;
throw _CastError.forType(object, 'int');
@@ -1030,7 +1071,7 @@
/// Specialization for check on 'int?'.
/// Called from generated code.
-int /*?*/ _checkIntNullable(object) {
+int? _checkIntNullable(object) {
if (_isInt(object)) return _Utils.asInt(object);
if (object == null) return object;
throw _TypeError.forType(object, 'int');
@@ -1044,7 +1085,7 @@
/// Specialization for 'as num?'.
/// Called from generated code.
-num /*?*/ _asNumNullable(object) {
+num? _asNumNullable(object) {
if (_isNum(object)) return _Utils.asNum(object);
if (object == null) return object;
throw _CastError.forType(object, 'num');
@@ -1052,7 +1093,7 @@
/// Specialization for check on 'num?'.
/// Called from generated code.
-num /*?*/ _checkNumNullable(object) {
+num? _checkNumNullable(object) {
if (_isNum(object)) return _Utils.asNum(object);
if (object == null) return object;
throw _TypeError.forType(object, 'num');
@@ -1066,7 +1107,7 @@
/// Specialization for 'as String?'.
/// Called from generated code.
-String /*?*/ _asStringNullable(object) {
+String? _asStringNullable(object) {
if (_isString(object)) return _Utils.asString(object);
if (object == null) return object;
throw _CastError.forType(object, 'String');
@@ -1074,7 +1115,7 @@
/// Specialization for check on 'String?'.
/// Called from generated code.
-String /*?*/ _checkStringNullable(object) {
+String? _checkStringNullable(object) {
if (_isString(object)) return _Utils.asString(object);
if (object == null) return object;
throw _TypeError.forType(object, 'String');
@@ -1174,7 +1215,7 @@
if (outerContextLength != null) {
// Pop all of the generic type parameters.
- JS('', '#.length = #', genericContext, outerContextLength);
+ JS('', '#.length = #', genericContext!, outerContextLength);
}
// TODO(fishythefish): Below is the same format as the VM. Change to:
@@ -1196,12 +1237,16 @@
if (kind == Rti.kindStar) {
Rti starArgument = Rti._getStarArgument(rti);
String s = _rtiToString(starArgument, genericContext);
- int argumentKind = Rti._getKind(starArgument);
- if (argumentKind == Rti.kindFunction ||
- argumentKind == Rti.kindGenericFunction) {
- s = '(' + s + ')';
+ if (JS_GET_FLAG('PRINT_LEGACY_STARS')) {
+ int argumentKind = Rti._getKind(starArgument);
+ if (argumentKind == Rti.kindFunction ||
+ argumentKind == Rti.kindGenericFunction) {
+ s = '(' + s + ')';
+ }
+ return s + '*';
+ } else {
+ return s;
}
- return s + '*';
}
if (kind == Rti.kindQuestion) {
@@ -1251,7 +1296,7 @@
}
String _unminifyOrTag(String rawClassName) {
- String preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName);
+ String? preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName);
if (preserved != null) return preserved;
return JS_GET_FLAG('MINIFIED') ? 'minified:$rawClassName' : rawClassName;
}
@@ -1416,11 +1461,11 @@
static Object typeParameterVariances(universe) =>
JS('', '#.#', universe, RtiUniverseFieldNames.typeParameterVariances);
- static Object _findRule(universe, String targetType) =>
+ static Object? _findRule(universe, String targetType) =>
JS('', '#.#', typeRules(universe), targetType);
- static Object findRule(universe, String targetType) {
- Object rule = _findRule(universe, targetType);
+ static Object? findRule(universe, String targetType) {
+ Object? rule = _findRule(universe, targetType);
while (_Utils.isString(rule)) {
rule = _findRule(universe, _Utils.asString(rule));
}
@@ -1447,7 +1492,7 @@
}
}
- static Object findTypeParameterVariances(universe, String cls) =>
+ static Object? findTypeParameterVariances(universe, String cls) =>
JS('', '#.#', typeParameterVariances(universe), cls);
static void addRules(universe, rules) =>
@@ -1517,9 +1562,9 @@
}
String interfaceName = Rti._getInterfaceName(environment);
- Object rule = _Universe.findRule(universe, interfaceName);
+ Object? rule = _Universe.findRule(universe, interfaceName);
assert(rule != null);
- String recipe = TypeRule.lookupTypeVariable(rule, name);
+ String? recipe = TypeRule.lookupTypeVariable(rule, name);
if (recipe == null) {
throw 'No "$name" in "${Rti._getCanonicalRecipe(environment)}"';
}
@@ -2426,10 +2471,10 @@
throw UnimplementedError("TypeRule is static methods only.");
}
- static String lookupTypeVariable(rule, String typeVariable) =>
+ static String? lookupTypeVariable(rule, String typeVariable) =>
JS('', '#.#', rule, typeVariable);
- static JSArray lookupSupertype(rule, String supertype) =>
+ static JSArray? lookupSupertype(rule, String supertype) =>
JS('', '#.#', rule, supertype);
}
@@ -2781,7 +2826,7 @@
// interface, so rather than iterating over the Ci, we can instead look up
// [t] in our ruleset.
// TODO(fishythefish): Handle variance correctly.
- Object rule = _Universe.findRule(universe, sName);
+ Object? rule = _Universe.findRule(universe, sName);
if (rule == null) return false;
var supertypeArgs = TypeRule.lookupSupertype(rule, tName);
if (supertypeArgs == null) return false;
@@ -2831,19 +2876,19 @@
/// Unchecked cast to Rti.
Rti _castToRti(s) => JS('Rti', '#', s);
-Rti /*?*/ _castToRtiOrNull(s) => JS('Rti|Null', '#', s);
+Rti? _castToRtiOrNull(s) => JS('Rti|Null', '#', s);
class _Utils {
- static bool asBool(Object o) => JS('bool', '#', o);
- static double asDouble(Object o) => JS('double', '#', o);
- static int asInt(Object o) => JS('int', '#', o);
- static num asNum(Object o) => JS('num', '#', o);
- static String asString(Object o) => JS('String', '#', o);
+ static bool asBool(o) => JS('bool', '#', o);
+ static double asDouble(o) => JS('double', '#', o);
+ static int asInt(o) => JS('int', '#', o);
+ static num asNum(o) => JS('num', '#', o);
+ static String asString(o) => JS('String', '#', o);
- static bool isString(Object o) => JS('bool', 'typeof # == "string"', o);
- static bool isNum(Object o) => JS('bool', 'typeof # == "number"', o);
+ static bool isString(o) => JS('bool', 'typeof # == "string"', o);
+ static bool isNum(o) => JS('bool', 'typeof # == "number"', o);
- static bool instanceOf(Object o, Object constructor) =>
+ static bool instanceOf(o, Object constructor) =>
JS('bool', '# instanceof #', o, constructor);
static bool isIdentical(s, t) => JS('bool', '# === #', s, t);
@@ -2862,13 +2907,13 @@
}
}
- static bool isArray(Object o) => JS('bool', 'Array.isArray(#)', o);
+ static bool isArray(o) => JS('bool', 'Array.isArray(#)', o);
static int arrayLength(Object array) => JS('int', '#.length', array);
static Object arrayAt(Object array, int i) => JS('', '#[#]', array, i);
- static void arraySetAt(Object array, int i, Object value) {
+ static void arraySetAt(Object array, int i, value) {
JS('', '#[#] = #', array, i, value);
}
@@ -2881,7 +2926,7 @@
static JSArray arrayConcat(Object a1, Object a2) =>
JS('JSArray', '#.concat(#)', a1, a2);
- static void arrayPush(Object array, Object? value) {
+ static void arrayPush(Object array, value) {
JS('', '#.push(#)', array, value);
}
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index e3c5f3e..4ec4fc2 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -121,6 +121,11 @@
// [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
const ISOLATE_TAG = 'isolateTag';
+/// An embedded global that contains the property used to store type information
+/// on JavaScript Array instances. This is a Symbol (except for IE11, where is
+/// is a String).
+const ARRAY_RTI_PROPERTY = 'arrayRti';
+
/// This embedded global (a function) returns the isolate-specific dispatch-tag
/// that is used to accelerate interceptor calls.
const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
@@ -333,21 +338,6 @@
/// String representation of the type of the JavaScriptFunction class.
JS_FUNCTION_CLASS_TYPE_NAME,
- /// String recipe for the [bool] type.
- BOOL_RECIPE,
-
- /// String recipe for the [double] type.
- DOUBLE_RECIPE,
-
- /// String recipe for the [int] type.
- INT_RECIPE,
-
- /// String recipe for the [num] type.
- NUM_RECIPE,
-
- /// String recipe for the [String] type.
- STRING_RECIPE,
-
/// Property name for Rti._is field.
RTI_FIELD_IS,
}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/array.dart b/sdk_nnbd/lib/_internal/vm/lib/array.dart
index 73e1237..1922173 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/array.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/array.dart
@@ -250,7 +250,10 @@
assert(array is _List<E> || array is _ImmutableList<E>);
}
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
@pragma("vm:prefer-inline")
bool moveNext() {
diff --git a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
index db69321..ff6009b 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
@@ -69,6 +69,17 @@
}
@patch
+ factory List.generate(int length, E generator(int index),
+ {bool growable = true}) {
+ final List<E> result =
+ growable ? new _GrowableList<E>(length) : new _List<E>(length);
+ for (int i = 0; i < result.length; ++i) {
+ result[i] = generator(i);
+ }
+ return result;
+ }
+
+ @patch
factory List.unmodifiable(Iterable elements) {
final result = new List<E>.from(elements, growable: false);
return makeFixedListUnmodifiable(result);
diff --git a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
index 2feba14..dcb8fa1 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
@@ -841,7 +841,10 @@
return false;
}
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
}
/**
diff --git a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
index 3a8c7cf..7f3984d 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
@@ -464,7 +464,10 @@
}
}
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
}
// Set implementation, analogous to _CompactLinkedHashMap.
diff --git a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
index ea3f461..0366017 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
@@ -125,14 +125,18 @@
T get current {
final iterator = _yieldEachIterator;
- return iterator != null ? iterator.current : _current as T;
+ if (iterator != null) {
+ return iterator.current;
+ } else {
+ final cur = _current;
+ return (cur != null) ? cur : cur as T;
+ }
}
_SyncIterator(this._moveNextFn);
bool moveNext() {
- final moveNextFn = _moveNextFn;
- if (moveNextFn == null) {
+ if (_moveNextFn == null) {
return false;
}
while (true) {
@@ -145,7 +149,7 @@
}
// _moveNextFn() will update the values of _yieldEachIterable
// and _current.
- if (!moveNextFn(this)) {
+ if (!_moveNextFn!(this)) {
_moveNextFn = null;
_current = null;
return false;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
index 00134bd..d5749b0 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
@@ -454,10 +454,10 @@
int _nativeApiFunctionPointer(String symbol) native "NativeApiFunctionPointer";
@patch
-class NativeApi {
+abstract class NativeApi {
@patch
static Pointer<NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>>
- get nativeApiPostCObject =>
+ get postCObject =>
Pointer.fromAddress(_nativeApiFunctionPointer("Dart_PostCObject"));
@patch
@@ -466,11 +466,10 @@
Int64 Function(
Pointer<Uint8>,
Pointer<NativeFunction<Dart_NativeMessageHandler>>,
- Int8)>> get nativeApiNewNativePort =>
+ Int8)>> get newNativePort =>
Pointer.fromAddress(_nativeApiFunctionPointer("Dart_NewNativePort"));
@patch
- static Pointer<NativeFunction<Int8 Function(Int64)>>
- get nativeApiCloseNativePort => Pointer.fromAddress(
- _nativeApiFunctionPointer("Dart_CloseNativePort"));
+ static Pointer<NativeFunction<Int8 Function(Int64)>> get closeNativePort =>
+ Pointer.fromAddress(_nativeApiFunctionPointer("Dart_CloseNativePort"));
}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart b/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart
index 2f653f5..7be9890 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart
@@ -173,7 +173,10 @@
return false;
}
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
}
class _ImmutableMapValueIterator<E> implements Iterator<E> {
@@ -194,7 +197,10 @@
return false;
}
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
}
class _ImmutableMapEntryIterator<K, V> implements Iterator<MapEntry<K, V>> {
@@ -216,5 +222,8 @@
return false;
}
- MapEntry<K, V> get current => _current as MapEntry<K, V>;
+ MapEntry<K, V> get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as MapEntry<K, V>;
+ }
}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart
index 48712f5..e4000a4 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart
@@ -34,8 +34,9 @@
// ArgumentsDescriptor layout. Keep in sync with enum in dart_entry.h.
static const int _TYPE_ARGS_LEN = 0;
static const int _COUNT = 1;
- static const int _POSITIONAL_COUNT = 2;
- static const int _FIRST_NAMED_ENTRY = 3;
+ static const int _SIZE = 2;
+ static const int _POSITIONAL_COUNT = 3;
+ static const int _FIRST_NAMED_ENTRY = 4;
// Internal representation of the invocation mirror.
String? _functionName;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
index e9d094f..1d896ba 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
@@ -1388,5 +1388,8 @@
return true;
}
- Match get current => _current as Match;
+ Match get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as Match;
+ }
}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart
index ef294e0..6d0cc5a 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart
@@ -3861,7 +3861,10 @@
return false;
}
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
}
abstract class _TypedListView extends _TypedListBase implements TypedData {
diff --git a/sdk_nnbd/lib/async/stream.dart b/sdk_nnbd/lib/async/stream.dart
index c4ee2f2..565b9f4 100644
--- a/sdk_nnbd/lib/async/stream.dart
+++ b/sdk_nnbd/lib/async/stream.dart
@@ -668,7 +668,7 @@
}
/**
- * Applies [streamTransformer] to this stream.
+ * Applies [streamTransformer] to this stream.
*
* Returns the transformed stream,
* that is, the result of `streamTransformer.bind(this)`.
diff --git a/sdk_nnbd/lib/collection/linked_list.dart b/sdk_nnbd/lib/collection/linked_list.dart
index 71e0226..843eedd 100644
--- a/sdk_nnbd/lib/collection/linked_list.dart
+++ b/sdk_nnbd/lib/collection/linked_list.dart
@@ -181,7 +181,10 @@
_next = list._first,
_visitedFirst = false;
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
bool moveNext() {
if (_modificationCount != _list._modificationCount) {
diff --git a/sdk_nnbd/lib/collection/maps.dart b/sdk_nnbd/lib/collection/maps.dart
index 90ecb6a..85a3155 100644
--- a/sdk_nnbd/lib/collection/maps.dart
+++ b/sdk_nnbd/lib/collection/maps.dart
@@ -258,7 +258,10 @@
return false;
}
- V get current => _current as V;
+ V get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as V;
+ }
}
/// Mixin that overrides mutating map operations with implementations that
diff --git a/sdk_nnbd/lib/collection/queue.dart b/sdk_nnbd/lib/collection/queue.dart
index c238840..26abbfe 100644
--- a/sdk_nnbd/lib/collection/queue.dart
+++ b/sdk_nnbd/lib/collection/queue.dart
@@ -518,7 +518,10 @@
return true;
}
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
}
/// List based [Queue].
@@ -898,7 +901,10 @@
_modificationCount = queue._modificationCount,
_position = queue._head;
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
bool moveNext() {
_queue._checkModification(_modificationCount);
diff --git a/sdk_nnbd/lib/convert/json.dart b/sdk_nnbd/lib/convert/json.dart
index a75dbb5..9528602 100644
--- a/sdk_nnbd/lib/convert/json.dart
+++ b/sdk_nnbd/lib/convert/json.dart
@@ -473,6 +473,13 @@
}
/// This class parses JSON strings and builds the corresponding objects.
+///
+/// A JSON input must be the JSON encoding of a single JSON value,
+/// which can be a list or map containing other values.
+///
+/// When used as a [StreamTransformer], the input stream may emit
+/// multiple strings. The concatenation of all of these strings must
+/// be a valid JSON encoding of a single JSON value.
class JsonDecoder extends Converter<String, Object?> {
final Object? Function(Object? key, Object? value)? _reviver;
diff --git a/sdk_nnbd/lib/core/list.dart b/sdk_nnbd/lib/core/list.dart
index c934195..afd7f11 100644
--- a/sdk_nnbd/lib/core/list.dart
+++ b/sdk_nnbd/lib/core/list.dart
@@ -180,16 +180,8 @@
*
* The [length] must be non-negative.
*/
- factory List.generate(int length, E generator(int index),
- {bool growable = true}) {
- if (length < 0) throw RangeError.index(length, 0, null, "length");
- if (length == 0) return List<E>.empty(growable: growable);
- List<E> result = List<E>.filled(length, generator(0), growable: growable);
- for (int i = 1; i < length; i++) {
- result[i] = generator(i);
- }
- return result;
- }
+ external factory List.generate(int length, E generator(int index),
+ {bool growable = true});
/**
* Creates an unmodifiable list containing all [elements].
diff --git a/sdk_nnbd/lib/core/num.dart b/sdk_nnbd/lib/core/num.dart
index f63dc68..55bb910 100644
--- a/sdk_nnbd/lib/core/num.dart
+++ b/sdk_nnbd/lib/core/num.dart
@@ -359,8 +359,8 @@
* 1.toStringAsFixed(3); // 1.000
* (4321.12345678).toStringAsFixed(3); // 4321.123
* (4321.12345678).toStringAsFixed(5); // 4321.12346
- * 123456789012345678901.toStringAsFixed(3); // 123456789012345683968.000
- * 1000000000000000000000.toStringAsFixed(3); // 1e+21
+ * 123456789012345.toStringAsFixed(3); // 123456789012345.000
+ * 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000
* 5.25.toStringAsFixed(0); // 5
*/
String toStringAsFixed(int fractionDigits);
diff --git a/sdk_nnbd/lib/ffi/ffi.dart b/sdk_nnbd/lib/ffi/ffi.dart
index c7ded4d..202f4f6 100644
--- a/sdk_nnbd/lib/ffi/ffi.dart
+++ b/sdk_nnbd/lib/ffi/ffi.dart
@@ -628,13 +628,13 @@
typedef Dart_NativeMessageHandler = Void Function(Int64, Pointer<Dart_CObject>);
/// Exposes function pointers to functions in `dart_native_api.h`.
-class NativeApi {
+abstract class NativeApi {
/// A function pointer to
/// `bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message)`
/// in `dart_native_api.h`.
external static Pointer<
NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>>
- get nativeApiPostCObject;
+ get postCObject;
/// A function pointer to
/// ```
@@ -648,11 +648,11 @@
Int64 Function(
Pointer<Uint8>,
Pointer<NativeFunction<Dart_NativeMessageHandler>>,
- Int8)>> get nativeApiNewNativePort;
+ Int8)>> get newNativePort;
/// A function pointer to
/// `bool Dart_CloseNativePort(Dart_Port native_port_id)`
/// in `dart_native_api.h`.
external static Pointer<NativeFunction<Int8 Function(Int64)>>
- get nativeApiCloseNativePort;
+ get closeNativePort;
}
diff --git a/sdk_nnbd/lib/internal/iterable.dart b/sdk_nnbd/lib/internal/iterable.dart
index 55134af..2817132 100644
--- a/sdk_nnbd/lib/internal/iterable.dart
+++ b/sdk_nnbd/lib/internal/iterable.dart
@@ -325,7 +325,10 @@
_length = iterable.length,
_index = 0;
- E get current => _current as E;
+ E get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as E;
+ }
@pragma("vm:prefer-inline")
bool moveNext() {
@@ -393,7 +396,10 @@
return false;
}
- T get current => _current as T;
+ T get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as T;
+ }
}
/**
@@ -465,7 +471,10 @@
ExpandIterator(this._iterator, this._f);
- T get current => _current as T;
+ T get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as T;
+ }
bool moveNext() {
if (_currentExpansion == null) return false;
diff --git a/sdk_nnbd/lib/internal/linked_list.dart b/sdk_nnbd/lib/internal/linked_list.dart
index e11cd7d..b5e5275 100644
--- a/sdk_nnbd/lib/internal/linked_list.dart
+++ b/sdk_nnbd/lib/internal/linked_list.dart
@@ -98,7 +98,11 @@
class _LinkedListIterator<T extends LinkedListEntry<T>> implements Iterator<T> {
/// The current element of the iterator.
T? _current;
- T get current => _current as T;
+
+ T get current {
+ final cur = _current;
+ return (cur != null) ? cur : cur as T;
+ }
/// The list the iterator iterates over.
///
diff --git a/tests/compiler/dart2js/analyses/api_allowed.json b/tests/compiler/dart2js/analyses/api_allowed.json
index 737f757..fec741e 100644
--- a/tests/compiler/dart2js/analyses/api_allowed.json
+++ b/tests/compiler/dart2js/analyses/api_allowed.json
@@ -9,13 +9,13 @@
"org-dartlang-sdk:///sdk/lib/_internal/js_runtime/lib/js_helper.dart": {
"Dynamic invocation of '[]'.": 3,
"Dynamic access of 'isNaN'.": 3,
- "Dynamic invocation of '<='.": 4,
- "Dynamic invocation of '-'.": 4,
- "Dynamic invocation of '>>'.": 2,
- "Dynamic invocation of '&'.": 3,
- "Dynamic invocation of '<'.": 3,
- "Dynamic invocation of '>'.": 2,
+ "Dynamic invocation of '<='.": 2,
+ "Dynamic invocation of '-'.": 3,
+ "Dynamic invocation of '&'.": 1,
+ "Dynamic invocation of '>>'.": 1,
+ "Dynamic invocation of '<'.": 2,
"Dynamic invocation of '+'.": 1,
+ "Dynamic invocation of '>'.": 1,
"Dynamic access of 'length'.": 1
},
"org-dartlang-sdk:///sdk/lib/_internal/js_runtime/lib/string_helper.dart": {
@@ -23,7 +23,7 @@
"Dynamic invocation of '+'.": 1,
"Dynamic invocation of '>='.": 1,
"Dynamic invocation of 'substring'.": 7,
- "Dynamic invocation of 'allMatches'.": 4,
+ "Dynamic invocation of 'allMatches'.": 3,
"Dynamic access of 'isNotEmpty'.": 1,
"Dynamic invocation of '_js_helper::_execGlobal'.": 1,
"Dynamic access of 'start'.": 1,
diff --git a/tests/compiler/dart2js/end_to_end/dill_loader_test.dart b/tests/compiler/dart2js/end_to_end/dill_loader_test.dart
index 64062ed..92ea4ef 100644
--- a/tests/compiler/dart2js/end_to_end/dill_loader_test.dart
+++ b/tests/compiler/dart2js/end_to_end/dill_loader_test.dart
@@ -30,7 +30,7 @@
var options = new CompilerOptions()
..target = new Dart2jsTarget("dart2js", new TargetFlags())
..packagesFileUri = Uri.base.resolve('.packages')
- ..linkedDependencies = <Uri>[
+ ..additionalDills = <Uri>[
computePlatformBinariesLocation().resolve("dart2js_platform.dill"),
]
..setExitCodeOnProblem = true
diff --git a/tests/compiler/dart2js/end_to_end/modular_loader_test.dart b/tests/compiler/dart2js/end_to_end/modular_loader_test.dart
index 3b3cd0b..1f79ed0 100644
--- a/tests/compiler/dart2js/end_to_end/modular_loader_test.dart
+++ b/tests/compiler/dart2js/end_to_end/modular_loader_test.dart
@@ -70,14 +70,14 @@
entity.writeAsBytesSync(data);
}
});
- List<Uri> linkedDependencies = [
+ List<Uri> additionalDills = [
computePlatformBinariesLocation().resolve("dart2js_platform.dill"),
]..addAll(deps.map(toTestUri));
fs.entityForUri(toTestUri('.packages')).writeAsStringSync('');
var options = new CompilerOptions()
..target = new Dart2jsTarget("dart2js", new TargetFlags())
..fileSystem = new TestFileSystem(fs)
- ..linkedDependencies = linkedDependencies
+ ..additionalDills = additionalDills
..packagesFileUri = toTestUri('.packages');
var inputUris = inputs.map(toTestUri).toList();
var inputUriSet = inputUris.toSet();
diff --git a/tests/compiler/dart2js/end_to_end/no_platform_test.dart b/tests/compiler/dart2js/end_to_end/no_platform_test.dart
index 968507b..cf6766d 100644
--- a/tests/compiler/dart2js/end_to_end/no_platform_test.dart
+++ b/tests/compiler/dart2js/end_to_end/no_platform_test.dart
@@ -19,7 +19,7 @@
new Dart2jsTarget('dart2js', new TargetFlags()),
Uri.base
.resolve('sdk/lib/libraries.json'), // librariesSpecificationUri
- [], // linkedDependencies
+ [], // additionalDills
Uri.base.resolve('.packages'), // packagesFileUri
experimentalFlags: experimentalFlags,
verify: true);
diff --git a/tests/compiler/dart2js/impact/data/as.dart b/tests/compiler/dart2js/impact/data/as.dart
index 45a687f..80bbc69f 100644
--- a/tests/compiler/dart2js/impact/data/as.dart
+++ b/tests/compiler/dart2js/impact/data/as.dart
@@ -9,14 +9,14 @@
promoted(null);
}
-/*member: explicitAs:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:String]*/
+/*member: explicitAs:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:String]*/
explicitAs(String i) {
i.length;
// ignore: unnecessary_cast
return i as String;
}
-/*member: implicitAs:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:String]*/
+/*member: implicitAs:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:String]*/
String implicitAs(String i) {
dynamic j = i;
i.length;
@@ -24,7 +24,7 @@
return j;
}
-/*member: promoted:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:String]*/
+/*member: promoted:dynamic=[String.length],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:String]*/
String promoted(dynamic i) {
if (i is! String) return null;
i.length;
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
index 541c67f..41172c1 100644
--- a/tests/compiler/dart2js/impact/data/async.dart
+++ b/tests/compiler/dart2js/impact/data/async.dart
@@ -217,13 +217,13 @@
return () async* {};
}
-/*member: testAsyncForIn:dynamic=[_StreamIterator.cancel(0),_StreamIterator.current,_StreamIterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),StreamIterator.(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_asyncAwait(2),_asyncRethrow(2),_asyncReturn(2),_asyncStartSync(2),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),_makeAsyncAwaitCompleter<dynamic>(0),_wrapJsFunctionForAsync(1),findType(1),instanceType(1)],type=[impl:Stream<dynamic>,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
+/*member: testAsyncForIn:dynamic=[_StreamIterator.cancel(0),_StreamIterator.current,_StreamIterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),StreamIterator.(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_asyncAwait(2),_asyncRethrow(2),_asyncReturn(2),_asyncStartSync(2),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),_makeAsyncAwaitCompleter<dynamic>(0),_wrapJsFunctionForAsync(1),findType(1),instanceType(1)],type=[impl:Stream<dynamic>,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
testAsyncForIn(o) async {
// ignore: UNUSED_LOCAL_VARIABLE
await for (var e in o) {}
}
-/*member: testAsyncForInTyped:dynamic=[_StreamIterator.cancel(0),_StreamIterator.current,_StreamIterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),StreamIterator.(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_asyncAwait(2),_asyncRethrow(2),_asyncReturn(2),_asyncStartSync(2),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),_makeAsyncAwaitCompleter<dynamic>(0),_wrapJsFunctionForAsync(1),findType(1),instanceType(1)],type=[impl:Stream<dynamic>,impl:int,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
+/*member: testAsyncForInTyped:dynamic=[_StreamIterator.cancel(0),_StreamIterator.current,_StreamIterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),StreamIterator.(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_asyncAwait(2),_asyncRethrow(2),_asyncReturn(2),_asyncStartSync(2),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),_makeAsyncAwaitCompleter<dynamic>(0),_wrapJsFunctionForAsync(1),findType(1),instanceType(1)],type=[impl:Stream<dynamic>,impl:int,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
testAsyncForInTyped(o) async {
// ignore: UNUSED_LOCAL_VARIABLE
await for (int e in o) {}
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index bb334a7..925f979 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -137,7 +137,7 @@
testForwardingConstructor() => new ForwardingConstructorClass(null);
class ForwardingConstructorTypedSuperClass {
- /*member: ForwardingConstructorTypedSuperClass.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
+ /*member: ForwardingConstructorTypedSuperClass.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
ForwardingConstructorTypedSuperClass(int arg);
}
@@ -151,7 +151,7 @@
testForwardingConstructorTyped() => new ForwardingConstructorTypedClass(null);
class ForwardingConstructorGenericSuperClass<T> {
- /*member: ForwardingConstructorGenericSuperClass.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:ForwardingConstructorGenericSuperClass.T]*/
+ /*member: ForwardingConstructorGenericSuperClass.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:ForwardingConstructorGenericSuperClass.T]*/
ForwardingConstructorGenericSuperClass(T arg);
}
@@ -181,7 +181,7 @@
*/
testEnum() => Enum.A;
-/*member: staticGenericMethod:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,inst:List<staticGenericMethod.T>,param:Object,param:staticGenericMethod.T]*/
+/*member: staticGenericMethod:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,inst:List<staticGenericMethod.T>,param:Object,param:staticGenericMethod.T]*/
List<T> staticGenericMethod<T>(T arg) => [arg];
/*member: testStaticGenericMethod:
@@ -228,7 +228,7 @@
class GenericClass<X, Y> {
const GenericClass.generative();
- /*member: GenericClass.genericMethod:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,inst:Map<GenericClass.X,genericMethod.T>,param:Object,param:genericMethod.T]*/
+ /*member: GenericClass.genericMethod:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,inst:Map<GenericClass.X,genericMethod.T>,param:Object,param:genericMethod.T]*/
Map<X, T> genericMethod<T>(T arg) => {null: arg};
}
diff --git a/tests/compiler/dart2js/impact/data/constants/lib.dart b/tests/compiler/dart2js/impact/data/constants/lib.dart
index a896863..5e0bb96 100644
--- a/tests/compiler/dart2js/impact/data/constants/lib.dart
+++ b/tests/compiler/dart2js/impact/data/constants/lib.dart
@@ -42,7 +42,7 @@
const typeLiteralField = String;
-/*member: id:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
+/*member: id:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
T id<T>(T t) => t;
const int Function(int) _instantiation = id;
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
index 2d6b991..a56a258 100644
--- a/tests/compiler/dart2js/impact/data/constructors.dart
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -152,7 +152,7 @@
/*member: GenericClass.generative:static=[Object.(0)]*/
const GenericClass.generative();
- /*member: GenericClass.fact:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Object]*/
+ /*member: GenericClass.fact:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Object]*/
factory GenericClass.fact() => null;
const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
diff --git a/tests/compiler/dart2js/impact/data/effectively_final.dart b/tests/compiler/dart2js/impact/data/effectively_final.dart
index 2b5f3cd..281b098 100644
--- a/tests/compiler/dart2js/impact/data/effectively_final.dart
+++ b/tests/compiler/dart2js/impact/data/effectively_final.dart
@@ -67,7 +67,7 @@
/*member: _method1:type=[inst:JSNull]*/
num _method1() => null;
-/*member: effectivelyFinalPromoted:dynamic=[int.+,num.+],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),_method1(0),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32,is:int]*/
+/*member: effectivelyFinalPromoted:dynamic=[int.+,num.+],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),_method1(0),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32,is:int]*/
effectivelyFinalPromoted() {
dynamic c = _method1();
c + 0;
@@ -79,7 +79,7 @@
/*member: _method2:type=[inst:JSNull]*/
String _method2() => null;
-/*member: effectivelyFinalPromotedInvalid:dynamic=[String.+,int.+],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),_method2(0),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,is:int]*/
+/*member: effectivelyFinalPromotedInvalid:dynamic=[String.+,int.+],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),_method2(0),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,is:int]*/
effectivelyFinalPromotedInvalid() {
dynamic c = _method2();
c + '';
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
index ef74e94..3976aee 100644
--- a/tests/compiler/dart2js/impact/data/expressions.dart
+++ b/tests/compiler/dart2js/impact/data/expressions.dart
@@ -105,58 +105,58 @@
*/
testPreDec(o) => --o;
-/*member: testIs:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:Class]*/
+/*member: testIs:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:Class]*/
testIs() => null is Class;
-/*member: testIsGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:GenericClass<int,String>]*/
+/*member: testIsGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:GenericClass<int,String>]*/
testIsGeneric() => null is GenericClass<int, String>;
-/*member: testIsGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
+/*member: testIsGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
testIsGenericRaw() => null is GenericClass;
-/*member: testIsGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
+/*member: testIsGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
testIsGenericDynamic() => null is GenericClass<dynamic, dynamic>;
-/*member: testIsNot:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:Class]*/
+/*member: testIsNot:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:Class]*/
testIsNot() => null is! Class;
-/*member: testIsNotGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:GenericClass<int,String>]*/
+/*member: testIsNotGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:GenericClass<int,String>]*/
testIsNotGeneric() => null is! GenericClass<int, String>;
-/*member: testIsNotGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
+/*member: testIsNotGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
testIsNotGenericRaw() => null is! GenericClass;
-/*member: testIsNotGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
+/*member: testIsNotGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]*/
testIsNotGenericDynamic() => null is! GenericClass<dynamic, dynamic>;
-/*member: testIsTypedef:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function()]*/
+/*member: testIsTypedef:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function()]*/
testIsTypedef() => null is Typedef;
-/*member: testIsTypedefGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:int Function(String)]*/
+/*member: testIsTypedefGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:int Function(String)]*/
testIsTypedefGeneric() => null is GenericTypedef<int, String>;
-/*member: testIsTypedefGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function(dynamic)]*/
+/*member: testIsTypedefGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function(dynamic)]*/
testIsTypedefGenericRaw() => null is GenericTypedef;
-/*member: testIsTypedefGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function(dynamic)]*/
+/*member: testIsTypedefGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:dynamic Function(dynamic)]*/
testIsTypedefGenericDynamic() => null is GenericTypedef<dynamic, dynamic>;
-/*member: testIsTypedefDeep:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:List<int Function(dynamic Function(dynamic))>]*/
+/*member: testIsTypedefDeep:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,is:List<int Function(dynamic Function(dynamic))>]*/
testIsTypedefDeep() => null is List<GenericTypedef<int, GenericTypedef>>;
-/*member: testAs:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:Class,inst:Closure,inst:JSBool]*/
+/*member: testAs:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:Class,inst:Closure,inst:JSBool]*/
// ignore: UNNECESSARY_CAST
testAs(dynamic o) => o as Class;
-/*member: testAsGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2),throwRuntimeError(1)],type=[as:GenericClass<int,String>,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>]*/
+/*member: testAsGeneric:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2),throwRuntimeError(1)],type=[as:GenericClass<int,String>,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>]*/
// ignore: UNNECESSARY_CAST
testAsGeneric(dynamic o) => o as GenericClass<int, String>;
-/*member: testAsGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:GenericClass<dynamic,dynamic>,inst:Closure,inst:JSBool]*/
+/*member: testAsGenericRaw:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:GenericClass<dynamic,dynamic>,inst:Closure,inst:JSBool]*/
// ignore: UNNECESSARY_CAST
testAsGenericRaw(dynamic o) => o as GenericClass;
-/*member: testAsGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:GenericClass<dynamic,dynamic>,inst:Closure,inst:JSBool]*/
+/*member: testAsGenericDynamic:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1),throwRuntimeError(1)],type=[as:GenericClass<dynamic,dynamic>,inst:Closure,inst:JSBool]*/
// ignore: UNNECESSARY_CAST
testAsGenericDynamic(dynamic o) => o as GenericClass<dynamic, dynamic>;
@@ -168,7 +168,7 @@
/*member: testIfNotNull:dynamic=[Object.==,foo],type=[inst:JSNull]*/
testIfNotNull(o) => o?.foo;
-/*member: testTypedIfNotNull:dynamic=[Class.==,Class.field],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class]*/
+/*member: testTypedIfNotNull:dynamic=[Class.==,Class.field],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class]*/
testTypedIfNotNull(Class o) => o?.field;
/*member: testIfNotNullSet:dynamic=[Object.==,foo=],type=[inst:JSBool,inst:JSNull]*/
diff --git a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
index ef75dc8..d498017 100644
--- a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
+++ b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
@@ -12,10 +12,10 @@
/*member: C.:static=[Object.(0)]*/
class C implements A<int>, B<String, bool> {}
-/*member: testA:dynamic=[call<A.T>(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),extractTypeArguments<A<dynamic>>(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[impl:A<dynamic>,impl:Function,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,is:A<A.T>]*/
+/*member: testA:dynamic=[call<A.T>(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),extractTypeArguments<A<dynamic>>(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[impl:A<dynamic>,impl:Function,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,is:A<A.T>]*/
testA(c, f) => extractTypeArguments<A>(c, f);
-/*member: testB:dynamic=[call<B.S,B.U>(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),extractTypeArguments<B<dynamic,dynamic>>(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[impl:B<dynamic,dynamic>,impl:Function,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,is:B<B.S,B.U>]*/
+/*member: testB:dynamic=[call<B.S,B.U>(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),extractTypeArguments<B<dynamic,dynamic>>(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[impl:B<dynamic,dynamic>,impl:Function,inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,is:B<B.S,B.U>]*/
testB(c, f) => extractTypeArguments<B>(c, f);
/*member: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
index c083e9d..778c065 100644
--- a/tests/compiler/dart2js/impact/data/initializers.dart
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -28,10 +28,10 @@
testGenericClass();
}
-/*member: testDefaultValuesPositional:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
+/*member: testDefaultValuesPositional:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
testDefaultValuesPositional([bool value = false]) {}
-/*member: testDefaultValuesNamed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
+/*member: testDefaultValuesNamed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
testDefaultValuesNamed({bool value: false}) {}
class ClassFieldInitializer1 {
@@ -84,7 +84,7 @@
/*member: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
class ClassInstanceFieldWithInitializer {
- /*member: ClassInstanceFieldWithInitializer.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
+ /*member: ClassInstanceFieldWithInitializer.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:bool]*/
var field = false;
}
@@ -93,7 +93,7 @@
/*member: ClassInstanceFieldTyped.:static=[Object.(0)]*/
class ClassInstanceFieldTyped {
- /*member: ClassInstanceFieldTyped.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:int]*/
+ /*member: ClassInstanceFieldTyped.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:int]*/
int field;
}
@@ -120,7 +120,7 @@
testSuperInitializer() => new ClassSuperInitializer();
class ClassGeneric<T> {
- /*member: ClassGeneric.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:ClassGeneric.T]*/
+ /*member: ClassGeneric.:static=[Object.(0),Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),checkSubtypeOfRuntimeType(2),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:ClassGeneric.T]*/
ClassGeneric(T arg);
}
diff --git a/tests/compiler/dart2js/impact/data/injected_cast.dart b/tests/compiler/dart2js/impact/data/injected_cast.dart
index 92ea4a3..7ff1527 100644
--- a/tests/compiler/dart2js/impact/data/injected_cast.dart
+++ b/tests/compiler/dart2js/impact/data/injected_cast.dart
@@ -14,11 +14,11 @@
/*member: Class1.:static=[Object.(0)]*/
class Class1 {
- /*member: Class1.field1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A]*/
+ /*member: Class1.field1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A]*/
A field1;
}
-/*member: method1:dynamic=[Class1.field1=],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,inst:Closure,inst:JSBool,is:Class1]*/
+/*member: method1:dynamic=[Class1.field1=],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,inst:Closure,inst:JSBool,is:Class1]*/
method1(dynamic o, dynamic value) {
if (o is! Class1) return;
o.field1 = value;
@@ -48,11 +48,11 @@
/*member: Class3.:static=[Object.(0)]*/
class Class3 {
- /*member: Class3.method3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
+ /*member: Class3.method3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
method3(A a, [B b, C c]) {}
}
-/*member: method3:dynamic=[Class3.method3(3)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,impl:C,inst:Closure,inst:JSBool,is:Class3,param:B]*/
+/*member: method3:dynamic=[Class3.method3(3)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,impl:C,inst:Closure,inst:JSBool,is:Class3,param:B]*/
method3(dynamic o, dynamic a, B b, dynamic c) {
if (o is! Class3) return;
o.method3(a, b, c);
@@ -60,11 +60,11 @@
/*member: Class4.:static=[Object.(0)]*/
class Class4 {
- /*member: Class4.method4:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
+ /*member: Class4.method4:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
method4(A a, {B b, C c}) {}
}
-/*member: method4:dynamic=[Class4.method4(1,b,c)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,impl:C,inst:Closure,inst:JSBool,is:Class4,param:B]*/
+/*member: method4:dynamic=[Class4.method4(1,b,c)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,impl:C,inst:Closure,inst:JSBool,is:Class4,param:B]*/
method4(dynamic o, dynamic a, B b, dynamic c) {
if (o is! Class4) return;
o.method4(a, c: c, b: b);
@@ -142,7 +142,7 @@
A Function(A) get f => null;
}
-/*member: method7:dynamic=[Class7.f(1),call(1)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,inst:Closure,inst:JSBool,is:Class7]*/
+/*member: method7:dynamic=[Class7.f(1),call(1)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:A,inst:Closure,inst:JSBool,is:Class7]*/
method7(dynamic o, dynamic a) {
if (o is! Class7) return;
o.f(a);
@@ -170,7 +170,7 @@
return g.method(iterable);
}
-/*member: method9:dynamic=[G.field=],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:int,inst:Closure,inst:JSBool,inst:JSNull,is:G,param:num]*/
+/*member: method9:dynamic=[G.field=],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[impl:int,inst:Closure,inst:JSBool,inst:JSNull,is:G,param:num]*/
method9(dynamic g, num value) {
if (g is! G) return null;
return g.field = value;
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
index 77f827d..ec1ce07 100644
--- a/tests/compiler/dart2js/impact/data/invokes.dart
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -115,13 +115,13 @@
topLevelFunction3(15, c: 16, b: 17);
}
-/*member: topLevelFunction1Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
+/*member: topLevelFunction1Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
void topLevelFunction1Typed(int a) {}
-/*member: topLevelFunction2Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:String,param:double,param:num]*/
+/*member: topLevelFunction2Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:String,param:double,param:num]*/
int topLevelFunction2Typed(String a, [num b, double c]) => null;
-/*member: topLevelFunction3Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:List<int>,param:Map<String,bool>,param:bool]*/
+/*member: topLevelFunction3Typed:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:List<int>,param:Map<String,bool>,param:bool]*/
double topLevelFunction3Typed(bool a, {List<int> b, Map<String, bool> c}) {
return null;
}
@@ -162,16 +162,16 @@
topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
}
-/*member: topLevelFunctionTyped1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num)]*/
+/*member: topLevelFunctionTyped1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num)]*/
topLevelFunctionTyped1(void a(num b)) {}
-/*member: topLevelFunctionTyped2:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,[String])]*/
+/*member: topLevelFunctionTyped2:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,[String])]*/
topLevelFunctionTyped2(void a(num b, [String c])) {}
-/*member: topLevelFunctionTyped3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,{String c,int d})]*/
+/*member: topLevelFunctionTyped3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,{String c,int d})]*/
topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
-/*member: topLevelFunctionTyped4:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,{int c,String d})]*/
+/*member: topLevelFunctionTyped4:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:void Function(num,{int c,String d})]*/
topLevelFunctionTyped4(void a(num b, {String d, int c})) {}
/*member: testTopLevelFunctionTyped:
@@ -210,7 +210,7 @@
/*member: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
testTopLevelSetterSet() => topLevelSetter = null;
-/*member: topLevelSetterTyped=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
+/*member: topLevelSetterTyped=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:int]*/
void set topLevelSetterTyped(int value) {}
/*member: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
@@ -239,25 +239,25 @@
/*member: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
testTopLevelFieldFinal() => topLevelFieldFinal;
-/*member: topLevelFieldTyped:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:int]*/
+/*member: topLevelFieldTyped:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:int]*/
int topLevelFieldTyped;
/*member: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
testTopLevelFieldTyped() => topLevelFieldTyped;
-/*member: topLevelFieldGeneric1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*member: topLevelFieldGeneric1:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
GenericClass topLevelFieldGeneric1;
/*member: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
-/*member: topLevelFieldGeneric2:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*member: topLevelFieldGeneric2:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
/*member: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
-/*member: topLevelFieldGeneric3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:GenericClass<int,String>]*/
+/*member: topLevelFieldGeneric3:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:GenericClass<int,String>]*/
GenericClass<int, String> topLevelFieldGeneric3;
/*member: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
@@ -382,7 +382,7 @@
localFunction() {}
}
-/*member: testLocalFunctionTyped:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),computeSignature(3),def:localFunction,findType(1),getRuntimeTypeArguments(3),getRuntimeTypeInfo(1),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:Function,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:String]*/
+/*member: testLocalFunctionTyped:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),computeSignature(3),def:localFunction,findType(1),getRuntimeTypeArguments(3),getRuntimeTypeInfo(1),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:Function,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:String]*/
testLocalFunctionTyped() {
// ignore: UNUSED_ELEMENT
int localFunction(String a) => null;
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
index 703c91c..6dce2cd 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -59,7 +59,7 @@
/*member: GenericClass.:static=[JavaScriptObject.(0)]*/
@JS()
class GenericClass<T> {
- /*member: GenericClass.method:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:void Function(GenericClass.T)]*/
+ /*member: GenericClass.method:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:void Function(GenericClass.T)]*/
external GenericClass method([Callback<T> callback]);
}
diff --git a/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart b/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
index 24dd87c..379e8e9 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop_setter1.dart
@@ -9,11 +9,11 @@
import 'package:js/js.dart';
-/*member: foo=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,native:ApplicationCacheErrorEvent,native:DomError,native:DomException,native:ErrorEvent,native:MediaError,native:NavigatorUserMediaError,native:OverconstrainedError,native:PositionError,native:SensorErrorEvent,native:SpeechRecognitionError,native:SqlError,param:Function]*/
+/*member: foo=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,native:ApplicationCacheErrorEvent,native:DomError,native:DomException,native:ErrorEvent,native:MediaError,native:NavigatorUserMediaError,native:OverconstrainedError,native:PositionError,native:SensorErrorEvent,native:SpeechRecognitionError,native:SqlError,param:Function]*/
@JS()
external set foo(Function f);
-/*member: _doStuff:dynamic=[File.==,File.name],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1),print(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,inst:JSString,param:File,param:String]*/
+/*member: _doStuff:dynamic=[File.==,File.name],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1),print(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,inst:JSString,param:File,param:String]*/
void _doStuff(String name, File file) {
if (file == null) {
print('OK');
diff --git a/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart b/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
index 5cc18d3..4fdac09 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop_setter2.dart
@@ -9,11 +9,11 @@
import 'package:js/js.dart';
-/*member: foo=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,native:ApplicationCacheErrorEvent,native:DomError,native:DomException,native:ErrorEvent,native:File,native:MediaError,native:NavigatorUserMediaError,native:OverconstrainedError,native:PositionError,native:SensorErrorEvent,native:SpeechRecognitionError,native:SqlError,param:void Function(String,File)]*/
+/*member: foo=:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,native:ApplicationCacheErrorEvent,native:DomError,native:DomException,native:ErrorEvent,native:File,native:MediaError,native:NavigatorUserMediaError,native:OverconstrainedError,native:PositionError,native:SensorErrorEvent,native:SpeechRecognitionError,native:SqlError,param:void Function(String,File)]*/
@JS()
external set foo(void Function(String, File) f);
-/*member: _doStuff:dynamic=[File.==,File.name],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1),print(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,inst:JSString,param:File,param:String]*/
+/*member: _doStuff:dynamic=[File.==,File.name],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1),print(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,inst:JSString,param:File,param:String]*/
void _doStuff(String name, File file) {
if (file == null) {
print('OK');
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
index 9d6abb5..a759f7f 100644
--- a/tests/compiler/dart2js/impact/data/native.dart
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -56,7 +56,7 @@
@Native("NativeClass")
class NativeClass {
- /*member: NativeClass.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,native:JSExtendableArray<JSExtendableArray.E>,native:Object,native:String,native:bool,native:double,native:int,param:Object]*/
+ /*member: NativeClass.field:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,native:JSExtendableArray<JSExtendableArray.E>,native:Object,native:String,native:bool,native:double,native:int,param:Object]*/
@annotation_Creates_SerializedScriptValue
final Object field;
@@ -65,5 +65,5 @@
}
}
-/*member: testNativeField:dynamic=[NativeClass.field],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:NativeClass]*/
+/*member: testNativeField:dynamic=[NativeClass.field],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),defineProperty(3),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:NativeClass]*/
testNativeField(NativeClass c) => c.field;
diff --git a/tests/compiler/dart2js/impact/data/promotion.dart b/tests/compiler/dart2js/impact/data/promotion.dart
index fb8f608..e0513e7 100644
--- a/tests/compiler/dart2js/impact/data/promotion.dart
+++ b/tests/compiler/dart2js/impact/data/promotion.dart
@@ -37,17 +37,17 @@
dynamicToNoSuchMethodTearOff(null);
}
-/*member: positiveTyped:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass,param:Class]*/
+/*member: positiveTyped:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass,param:Class]*/
positiveTyped(Class cls) {
if (cls is SubClass) cls.method();
}
-/*member: positiveDynamic:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass]*/
+/*member: positiveDynamic:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass]*/
positiveDynamic(dynamic cls) {
if (cls is SubClass) cls.method();
}
-/*member: negativeDynamic:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass]*/
+/*member: negativeDynamic:dynamic=[SubClass.method(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,is:SubClass]*/
negativeDynamic(dynamic cls) {
if (cls is! SubClass) return;
cls.method();
diff --git a/tests/compiler/dart2js/impact/data/runtime_type.dart b/tests/compiler/dart2js/impact/data/runtime_type.dart
index 77a187c..7b1ca18 100644
--- a/tests/compiler/dart2js/impact/data/runtime_type.dart
+++ b/tests/compiler/dart2js/impact/data/runtime_type.dart
@@ -60,88 +60,88 @@
/*member: Class4.:static=[Object.(0)]*/
class Class4 {}
-/*member: toString1:dynamic=[Class2.runtimeType,toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),S(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSString,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*member: toString1:dynamic=[Class2.runtimeType,toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),S(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSString,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
toString1(Class2<int> c) => '${c.runtimeType}';
-/*member: toString2:dynamic=[Class2.==,Class2.runtimeType,toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),S(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSString,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*member: toString2:dynamic=[Class2.==,Class2.runtimeType,toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),S(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSString,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
toString2(Class2<int> c) => '${c?.runtimeType}';
-/*member: toString3:dynamic=[Class2.runtimeType,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*member: toString3:dynamic=[Class2.runtimeType,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
toString3(Class2<int> c) => c.runtimeType.toString();
-/*member: toString4:dynamic=[Class2.runtimeType,Type.==,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*member: toString4:dynamic=[Class2.runtimeType,Type.==,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
toString4(Class2<int> c) => c.runtimeType?.toString();
-/*member: toString5:dynamic=[Class2.==,Class2.runtimeType,Type.==,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*member: toString5:dynamic=[Class2.==,Class2.runtimeType,Type.==,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
toString5(Class2<int> c) => c?.runtimeType?.toString();
-/*member: toString6:dynamic=[Class2.==,Class2.runtimeType,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*member: toString6:dynamic=[Class2.==,Class2.runtimeType,Type.toString(0)],runtimeType=[string:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
toString6(Class2<int> c) => c?.runtimeType.toString();
-/*member: unknown:dynamic=[Class2.runtimeType],runtimeType=[unknown:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
+/*member: unknown:dynamic=[Class2.runtimeType],runtimeType=[unknown:Class2<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Class2<int>]*/
unknown(Class2<int> c) => c.runtimeType;
-/*member: equals1:dynamic=[Class1a.==,Class1a.runtimeType,Class1d.==,Class1d.runtimeType,Type.==],runtimeType=[equals:Class1a<int>/Class1d<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class1a<int>,param:Class1d<int>]*/
+/*member: equals1:dynamic=[Class1a.==,Class1a.runtimeType,Class1d.==,Class1d.runtimeType,Type.==],runtimeType=[equals:Class1a<int>/Class1d<int>],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkSubtype(4),findType(1),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),instanceType(1),setRuntimeTypeInfo(2)],type=[inst:Closure,inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSNull,inst:JSUnmodifiableArray<dynamic>,param:Class1a<int>,param:Class1d<int>]*/
equals1(Class1a<int> a, Class1d<int> b) => a?.runtimeType == b?.runtimeType;
-/*member: almostEquals1:dynamic=[Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals1:dynamic=[Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals1(Class3 a) => a.runtimeType == null;
-/*member: almostEquals2:dynamic=[Class3.==,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals2:dynamic=[Class3.==,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals2(Class3 a) => a?.runtimeType == null;
-/*member: almostEquals3:dynamic=[Class3.runtimeType,Null.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals3:dynamic=[Class3.runtimeType,Null.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals3(Class3 a) => null == a.runtimeType;
-/*member: almostEquals4:dynamic=[Class3.==,Class3.runtimeType,Null.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals4:dynamic=[Class3.==,Class3.runtimeType,Null.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals4(Class3 a) => null == a?.runtimeType;
-/*member: almostEquals5:dynamic=[Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
+/*member: almostEquals5:dynamic=[Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
almostEquals5(Class3 a) => a.runtimeType == a.field;
-/*member: almostEquals6:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals6:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals6(Class3 a) => a?.runtimeType == a.field;
-/*member: almostEquals7:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals7:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals7(Class3 a) => a.runtimeType == a?.field;
-/*member: almostEquals8:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals8:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals8(Class3 a) => a?.runtimeType == a?.field;
-/*member: almostEquals9:dynamic=[Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
+/*member: almostEquals9:dynamic=[Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
almostEquals9(Class3 a) => a.field == a.runtimeType;
-/*member: almostEquals10:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals10:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals10(Class3 a) => a?.field == a.runtimeType;
-/*member: almostEquals11:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals11:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals11(Class3 a) => a.field == a?.runtimeType;
-/*member: almostEquals12:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostEquals12:dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostEquals12(Class3 a) => a?.field == a?.runtimeType;
-/*member: almostToString1:dynamic=[Class3.runtimeType,Type.toString],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
+/*member: almostToString1:dynamic=[Class3.runtimeType,Type.toString],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3]*/
almostToString1(Class3 a) => a.runtimeType.toString;
-/*member: almostToString2:dynamic=[Class3.==,Class3.runtimeType,Type.==,Type.toString],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostToString2:dynamic=[Class3.==,Class3.runtimeType,Type.==,Type.toString],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostToString2(Class3 a) => a?.runtimeType?.toString;
-/*member: almostToString3:dynamic=[Class3.runtimeType,Type.noSuchMethod(1)],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostToString3:dynamic=[Class3.runtimeType,Type.noSuchMethod(1)],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostToString3(Class3 a) => a.runtimeType.noSuchMethod(null);
-/*member: almostToString4:dynamic=[Class3.==,Class3.runtimeType,Type.noSuchMethod(1)],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
+/*member: almostToString4:dynamic=[Class3.==,Class3.runtimeType,Type.noSuchMethod(1)],runtimeType=[unknown:Class3],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3]*/
almostToString4(Class3 a) => a?.runtimeType.noSuchMethod(null);
-/*member: notEquals1:dynamic=[Class3.runtimeType,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3,param:Class4]*/
+/*member: notEquals1:dynamic=[Class3.runtimeType,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,param:Class3,param:Class4]*/
notEquals1(Class3 a, Class4 b) => a.runtimeType != b.runtimeType;
-/*member: notEquals2:dynamic=[Class3.==,Class3.runtimeType,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
+/*member: notEquals2:dynamic=[Class3.==,Class3.runtimeType,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
notEquals2(Class3 a, Class4 b) => a?.runtimeType != b.runtimeType;
-/*member: notEquals3:dynamic=[Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
+/*member: notEquals3:dynamic=[Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
notEquals3(Class3 a, Class4 b) => a.runtimeType != b?.runtimeType;
-/*member: notEquals4:dynamic=[Class3.==,Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
+/*member: notEquals4:dynamic=[Class3.==,Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],runtimeType=[equals:Class3/Class4],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1)],type=[inst:Closure,inst:JSBool,inst:JSNull,param:Class3,param:Class4]*/
notEquals4(Class3 a, Class4 b) => a?.runtimeType != b?.runtimeType;
/*member: main:dynamic=[exact:Class1a.==],static=[Class1a.(0),Class1b.(0),Class1c.(0),Class1d.(0),Class2.(0),Class3.(0),Class4.(0),almostEquals1(1),almostEquals10(1),almostEquals11(1),almostEquals12(1),almostEquals2(1),almostEquals3(1),almostEquals4(1),almostEquals5(1),almostEquals6(1),almostEquals7(1),almostEquals8(1),almostEquals9(1),almostToString1(1),almostToString2(1),almostToString3(1),almostToString4(1),checkTypeBound(4),equals1(2),notEquals1(2),notEquals2(2),notEquals3(2),notEquals4(2),print(1),throwTypeError(1),toString1(1),toString2(1),toString3(1),toString4(1),toString5(1),toString6(1),unknown(1)]*/
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
index 4eb9ab4..15a28cf 100644
--- a/tests/compiler/dart2js/impact/data/statements.dart
+++ b/tests/compiler/dart2js/impact/data/statements.dart
@@ -65,13 +65,13 @@
return 1;
}
-/*member: testForIn:dynamic=[Iterator.current,Iterator.iterator,Iterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkConcurrentModificationError(2),findType(1),instanceType(1)],type=[impl:Iterable<dynamic>,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
+/*member: testForIn:dynamic=[Iterator.current,Iterator.iterator,Iterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkConcurrentModificationError(2),findType(1),instanceType(1)],type=[impl:Iterable<dynamic>,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
testForIn(o) {
// ignore: UNUSED_LOCAL_VARIABLE
for (var e in o) {}
}
-/*member: testForInTyped:dynamic=[Iterator.current,Iterator.iterator,Iterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),checkConcurrentModificationError(2),findType(1),instanceType(1)],type=[impl:Iterable<dynamic>,impl:int,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
+/*member: testForInTyped:dynamic=[Iterator.current,Iterator.iterator,Iterator.moveNext(0)],static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),checkConcurrentModificationError(2),findType(1),instanceType(1)],type=[impl:Iterable<dynamic>,impl:int,inst:Closure,inst:JSBool,inst:JSNull,inst:Null]*/
testForInTyped(o) {
// ignore: UNUSED_LOCAL_VARIABLE
for (int e in o) {}
@@ -87,7 +87,7 @@
try {} catch (e) {}
}
-/*member: testTryCatchOn:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isString(1),_isTop(1),findType(1),instanceType(1),unwrapException(1)],type=[catch:String,inst:Closure,inst:JSBool,inst:PlainJavaScriptObject,inst:UnknownJavaScriptObject]*/
+/*member: testTryCatchOn:static=[Rti._bind(1),Rti._eval(1),_arrayInstanceType(1),_asBoolNullable(1),_asDoubleNullable(1),_asIntNullable(1),_asNumNullable(1),_asObject(1),_asStringNullable(1),_asTop(1),_checkBoolNullable(1),_checkDoubleNullable(1),_checkIntNullable(1),_checkNumNullable(1),_checkObject(1),_checkStringNullable(1),_generalAsCheckImplementation(1),_generalIsTestImplementation(1),_generalTypeCheckImplementation(1),_instanceType(1),_isBool(1),_isInt(1),_isNum(1),_isObject(1),_isString(1),_isTop(1),findType(1),instanceType(1),unwrapException(1)],type=[catch:String,inst:Closure,inst:JSBool,inst:PlainJavaScriptObject,inst:UnknownJavaScriptObject]*/
testTryCatchOn() {
// ignore: UNUSED_CATCH_CLAUSE
try {} on String catch (e) {}
diff --git a/tests/compiler/dart2js/js/js_spec_string_test.dart b/tests/compiler/dart2js/js/js_spec_string_test.dart
index bcc11b8..a3245e4 100644
--- a/tests/compiler/dart2js/js/js_spec_string_test.dart
+++ b/tests/compiler/dart2js/js/js_spec_string_test.dart
@@ -34,7 +34,7 @@
DiagnosticMessage createMessage(spannable, messageKind,
[arguments = const {}]) {
return new DiagnosticMessage(null, spannable,
- MessageTemplate.TEMPLATES[messageKind].message(arguments));
+ MessageTemplate.TEMPLATES[messageKind].message(arguments, null));
}
@override
diff --git a/tests/compiler/dart2js/jsinterop/declaration_test.dart b/tests/compiler/dart2js/jsinterop/declaration_test.dart
index 2239c40..6c94aab 100644
--- a/tests/compiler/dart2js/jsinterop/declaration_test.dart
+++ b/tests/compiler/dart2js/jsinterop/declaration_test.dart
@@ -264,7 +264,7 @@
@JS()
class A {
- A();
+ external A();
}
main() => new A();
@@ -303,7 +303,7 @@
@JS()
@anonymous
class A {
- A();
+ external A();
}
main() => new A();
diff --git a/tests/compiler/dart2js/model/native_test.dart b/tests/compiler/dart2js/model/native_test.dart
index 6ae4e32..b0b227a 100644
--- a/tests/compiler/dart2js/model/native_test.dart
+++ b/tests/compiler/dart2js/model/native_test.dart
@@ -68,9 +68,7 @@
'46',
'51',
// TODO(33834): Non-external constructors should not be allowed.
- '34',
'35',
- '36',
'37',
// TODO(34345): Non-external static members should not be allowed.
'43',
@@ -127,9 +125,7 @@
'46',
'51',
// TODO(33834): Non-external constructors should not be allowed.
- '34',
'35',
- '36',
'37',
// TODO(34345): Non-external static members should not be allowed.
'43',
diff --git a/tests/compiler/dart2js_extra/40902_test.dart b/tests/compiler/dart2js_extra/40902_test.dart
new file mode 100644
index 0000000..d62c769
--- /dev/null
+++ b/tests/compiler/dart2js_extra/40902_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, 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.
+
+import "package:expect/expect.dart";
+
+class Foo {
+ int f() => 42;
+}
+
+class Bar extends Foo {
+ void test() {
+ Expect.isFalse(super.f is int);
+ }
+}
+
+void main() {
+ Bar().test();
+}
diff --git a/tests/compiler/dart2js_extra/jsinterop_test.dart b/tests/compiler/dart2js_extra/jsinterop_test.dart
index f689269..07798e5 100644
--- a/tests/compiler/dart2js_extra/jsinterop_test.dart
+++ b/tests/compiler/dart2js_extra/jsinterop_test.dart
@@ -143,7 +143,7 @@
@JS('d')
class JsInteropClass {
- // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 34: compile-time error
+ // GENERIC //# 34: compile-time error
JsInteropClass.generative(); //# 34: continued
// JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 35: compile-time error
@@ -152,7 +152,7 @@
external JsInteropClass.externalGenerative();
external factory JsInteropClass.externalFact();
- @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 36: compile-time error
+ @JS('a') // GENERIC //# 36: compile-time error
JsInteropClass.jsInteropGenerative(); //# 36: continued
@JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 37: compile-time error
diff --git a/tests/compiler/dart2js_extra/non_jsinterop_test.dart b/tests/compiler/dart2js_extra/non_jsinterop_test.dart
index d4cd22c..e66c5d5 100644
--- a/tests/compiler/dart2js_extra/non_jsinterop_test.dart
+++ b/tests/compiler/dart2js_extra/non_jsinterop_test.dart
@@ -145,7 +145,7 @@
@JS('d')
class JsInteropClass {
- // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 34: compile-time error
+ // GENERIC //# 34: compile-time error
JsInteropClass.generative(); //# 34: continued
// JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 35: compile-time error
@@ -154,7 +154,7 @@
external JsInteropClass.externalGenerative();
external factory JsInteropClass.externalFact();
- @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 36: compile-time error
+ @JS('a') // GENERIC //# 36: compile-time error
JsInteropClass.jsInteropGenerative(); //# 36: continued
@JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 37: compile-time error
diff --git a/tests/kernel/unsorted/regression_flutter51828_test.dart b/tests/kernel/unsorted/regression_flutter51828_test.dart
new file mode 100644
index 0000000..3d161f3
--- /dev/null
+++ b/tests/kernel/unsorted/regression_flutter51828_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, 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.
+
+// This is a regression test for https://github.com/flutter/flutter/issues/51828
+// which failed due bad reuse/typing of temp. vars. in the async transform.
+
+class A {
+ Future<void> foo(x) async {}
+}
+
+class B {
+ Future<void> bar(x) async {}
+}
+
+main() async => [A().foo(await null), B().bar(await null)];
diff --git a/tests/language/await/and_ifnull_test.dart b/tests/language/await/and_ifnull_test.dart
new file mode 100644
index 0000000..16d3fe5
--- /dev/null
+++ b/tests/language/await/and_ifnull_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, 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.
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+
+Future<String?> foo(bool x) async => x ? "foo" : null;
+
+Future<String> bar(bool x) async {
+ return ((await foo(x)) ?? "bar").toUpperCase();
+}
+
+main() async {
+ Expect.equals(await bar(true), "FOO");
+ Expect.equals(await bar(false), "BAR");
+}
diff --git a/tests/language/await/await_test.dart b/tests/language/await/await_test.dart
new file mode 100644
index 0000000..2938a57
--- /dev/null
+++ b/tests/language/await/await_test.dart
@@ -0,0 +1,240 @@
+// Copyright (c) 2014, 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=---optimization-counter-threshold=10
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import 'dart:async';
+
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+int get topLevelGetter => globalVariable;
+void set topLevelSetter(val) {
+ globalVariable = val;
+}
+
+class C {
+ static int staticField = 1;
+ static int get staticGetter => staticField;
+ static void set staticSetter(val) {
+ staticField = val;
+ }
+
+ static int staticFoo(int param) => param;
+
+ int field = 1;
+ int get getter => field;
+ void set setter(val) {
+ field = val;
+ }
+
+ int foo(int param) => param;
+}
+
+dummy() => 1;
+
+staticMembers() async {
+ var a = C.staticField + await dummy();
+ Expect.equals(a, 2);
+ var f = (C.staticField = 1) + await dummy();
+ Expect.equals(f, 2);
+ var b = C.staticGetter + await dummy();
+ Expect.equals(b, 2);
+ var c = (C.staticSetter = 1) + await dummy();
+ Expect.equals(c, 2);
+ var d = C.staticFoo(2) + await dummy();
+ Expect.equals(d, 3);
+ var e = C.staticField +
+ C.staticGetter +
+ (C.staticSetter = 1) +
+ C.staticFoo(1) +
+ await dummy();
+ Expect.equals(e, 5);
+}
+
+topLevelMembers() async {
+ var a = globalVariable + await dummy();
+ Expect.equals(a, 2);
+ var b = topLevelGetter + await dummy();
+ Expect.equals(b, 2);
+ var c = (topLevelSetter = 1) + await dummy();
+ Expect.equals(c, 2);
+ var d = topLevelFoo(1) + await dummy();
+ Expect.equals(d, 2);
+ var e = globalVariable +
+ topLevelGetter +
+ (topLevelSetter = 1) +
+ topLevelFoo(1) +
+ await dummy();
+ Expect.equals(e, 5);
+}
+
+instanceMembers() async {
+ var inst = new C();
+ var a = inst.field + await dummy();
+ Expect.equals(a, 2);
+ var b = inst.getter + await dummy();
+ Expect.equals(b, 2);
+ var c = (inst.setter = 1) + await dummy();
+ Expect.equals(c, 2);
+ var d = inst.foo(1) + await dummy();
+ Expect.equals(d, 2);
+ var e = inst.field +
+ inst.getter +
+ (inst.setter = 1) +
+ inst.foo(1) +
+ await dummy();
+ Expect.equals(e, 5);
+}
+
+others() async {
+ var a = "${globalVariable} ${await dummy()} " + await "someString";
+ Expect.equals(a, "1 1 someString");
+ var c = new C();
+ var d = c.field + await dummy();
+ var cnt = 2;
+ var b = [1, 2, 3];
+ b[cnt] = await dummy();
+ Expect.equals(b[cnt], 1);
+ var e = b[0] + await dummy();
+ Expect.equals(e, 2);
+}
+
+conditionals() async {
+ var a = false;
+ var b = true;
+ var c = (a || b) || await dummy();
+ Expect.isTrue(c);
+ var d = (a || b) ? a : await dummy();
+ Expect.isFalse(d);
+ var e = (a is int) ? await dummy() : 2;
+ Expect.equals(e, 2);
+ try {
+ var f = (a is int) ? await dummy() : 2;
+ } catch (e) {}
+}
+
+asserts() async {
+ for (final FutureOr<T> Function<T>(T) func in <dynamic>[id, future]) {
+ assert(await func(true));
+ assert(id(true) as bool, await func("message"));
+ assert(await func(true), await (func("message")));
+ bool success = true;
+ try {
+ assert(await func(false), await (func("message")));
+ if (assertStatementsEnabled) Expect.fail("Didn't throw");
+ } on AssertionError catch (e) {
+ Expect.equals("message", e.message);
+ }
+ }
+}
+
+controlFlow() async {
+ for (final FutureOr<T> Function<T>(T) func in <dynamic>[id, future]) {
+ // For.
+ var c = 0;
+ for (var i = await (func(0)); await func(i < 5); await func(i++)) {
+ c++;
+ }
+ Expect.equals(5, c);
+ // While.
+ c = 0;
+ while (await func(c < 5)) c++;
+ Expect.equals(5, c);
+ // Do-while.
+ c = 0;
+ do {
+ c++;
+ } while (await func(c < 5));
+ Expect.equals(5, c);
+ // If.
+ if (await func(c == 5)) {
+ Expect.equals(5, c);
+ } else {
+ Expect.fail("unreachable");
+ }
+ // Throw.
+ try {
+ throw await func("string");
+ } on String {
+ // OK.
+ }
+
+ try {
+ await (throw "string");
+ } on String {
+ // OK.
+ }
+ // Try/catch/finally
+ try {
+ try {
+ throw "string";
+ } catch (e) {
+ Expect.equals("string", e);
+ Expect.equals(0, await func(0));
+ rethrow;
+ } finally {
+ Expect.equals(0, await func(0));
+ }
+ } catch (e) {
+ Expect.equals(0, await func(0));
+ Expect.equals("string", e);
+ } finally {
+ Expect.equals(0, await func(0));
+ }
+ // Switch
+ switch (await func(2)) {
+ case 2:
+ break;
+ default:
+ Expect.fail("unreachable");
+ }
+ // Return.
+ Expect.equals(
+ 42,
+ await () async {
+ return await func(42);
+ }());
+ Expect.equals(
+ 42,
+ await () async {
+ return func(42);
+ }());
+ // Yield.
+ Stream<int> testStream1() async* {
+ yield await func(42);
+ }
+
+ Expect.listEquals([42], await testStream1().toList());
+ // Yield*
+ Stream<int> testStream2() async* {
+ yield* await func(intStream());
+ }
+
+ Expect.listEquals([42], await testStream2().toList());
+ }
+}
+
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+
+Stream<int> intStream() async* {
+ yield 42;
+}
+
+main() {
+ asyncStart();
+ for (int i = 0; i < 11; i++) {
+ asyncTest(staticMembers);
+ asyncTest(topLevelMembers);
+ asyncTest(instanceMembers);
+ asyncTest(conditionals);
+ asyncTest(others);
+ asyncTest(asserts);
+ asyncTest(controlFlow);
+ }
+ asyncEnd();
+}
diff --git a/tests/language/await/backwards_compatibility_runtime_test.dart b/tests/language/await/backwards_compatibility_runtime_test.dart
new file mode 100644
index 0000000..e257558
--- /dev/null
+++ b/tests/language/await/backwards_compatibility_runtime_test.dart
@@ -0,0 +1,49 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, 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.
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+
+get await => 4;
+
+// For functions that are declared with the async modifier we treat await as
+// keyword.
+
+test0() async {
+ var x = await 7;
+ Expect.equals(7, x);
+
+}
+
+test1() async {
+ var x = await 9;
+ Expect.equals(9, x);
+
+}
+
+// For functions that are not declared with the async modifier we allow await to
+// be used as an identifier.
+
+test2() {
+ var y = await;
+ Expect.equals(4, y);
+
+}
+
+test3() {
+ var await = 3;
+ Expect.equals(3, await);
+
+}
+
+main() {
+ test0();
+ test1();
+ test2();
+ test3();
+}
diff --git a/tests/language/await/backwards_compatibility_test.dart b/tests/language/await/backwards_compatibility_test.dart
new file mode 100644
index 0000000..ea6084c
--- /dev/null
+++ b/tests/language/await/backwards_compatibility_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2014, 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.
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+
+get await => 4;
+
+// For functions that are declared with the async modifier we treat await as
+// keyword.
+
+test0() async {
+ var x = await 7;
+ Expect.equals(7, x);
+ var await = 1;
+ // ^^^^^
+ // [analyzer] SYNTACTIC_ERROR.ASYNC_KEYWORD_USED_AS_IDENTIFIER
+ // [cfe] 'await' can't be used as an identifier in 'async', 'async*', or 'sync*' methods.
+}
+
+test1() async {
+ var x = await 9;
+ Expect.equals(9, x);
+ var y = await;
+ // ^
+ // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+ // [cfe] Expected an identifier, but got ';'.
+}
+
+// For functions that are not declared with the async modifier we allow await to
+// be used as an identifier.
+
+test2() {
+ var y = await;
+ Expect.equals(4, y);
+ var x = await 1;
+ // ^^^^^
+ // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+ // [cfe] Expected ';' after this.
+}
+
+test3() {
+ var await = 3;
+ Expect.equals(3, await);
+ var x = await 1;
+ // ^^^^^
+ // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+ // [cfe] Expected ';' after this.
+}
+
+main() {
+ test0();
+ test1();
+ test2();
+ test3();
+}
diff --git a/tests/language/await/exceptions_test.dart b/tests/language/await/exceptions_test.dart
new file mode 100644
index 0000000..c141edc
--- /dev/null
+++ b/tests/language/await/exceptions_test.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2014, 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=--optimization-counter-threshold=5
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+
+import 'dart:async';
+
+// It does not matter where a future is generated.
+bar(p) async => p;
+baz(p) => new Future(() => p);
+
+test0_1() async {
+ throw 1;
+}
+
+test0() async {
+ try {
+ await test0_1();
+ } catch (e) {
+ Expect.equals(1, e);
+ }
+}
+
+test1_1() async {
+ throw 1;
+}
+
+test1_2() async {
+ try {
+ await test1_1();
+ } catch (e) {
+ throw e + 1;
+ }
+}
+
+test1() async {
+ try {
+ await test1_2();
+ } catch (e) {
+ Expect.equals(2, e);
+ }
+}
+
+test2() async {
+ var x;
+ var test2_1 = () async {
+ try {
+ throw 'a';
+ } catch (e) {
+ throw e + 'b';
+ }
+ };
+ try {
+ try {
+ await test2_1();
+ } catch (e) {
+ var y = await bar(e + 'c');
+ throw y;
+ }
+ } catch (e) {
+ x = e + 'd';
+ return '?';
+ } finally {
+ return x;
+ }
+ return '!';
+}
+
+test() async {
+ var result;
+ for (int i = 0; i < 10; i++) {
+ await test0();
+ await test1();
+ result = await test2();
+ Expect.equals('abcd', result);
+ }
+ await 1;
+}
+
+foo() {
+ throw "Error";
+}
+
+awaitFoo() async {
+ await foo();
+}
+
+main() {
+ asyncStart();
+ test()
+ .then((_) => awaitFoo().then((_) => Expect.fail("Should have thrown"),
+ onError: (error) => Expect.equals("Error", error)))
+ .whenComplete(asyncEnd);
+}
diff --git a/tests/language/await/for_cancel_test.dart b/tests/language/await/for_cancel_test.dart
new file mode 100644
index 0000000..308b2a9
--- /dev/null
+++ b/tests/language/await/for_cancel_test.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2014, 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.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+late bool canceled;
+
+test1() async {
+ canceled = false;
+ try {
+ StreamController controller = infiniteStreamController();
+ outer:
+ while (true) {
+ await for (var x in controller.stream) {
+ for (int j = 0; j < 10; j++) {
+ if (j == 5) break outer;
+ }
+ }
+ }
+ } finally {
+ Expect.isTrue(canceled);
+ }
+}
+
+test2() async {
+ canceled = false;
+ try {
+ StreamController controller = infiniteStreamController();
+ bool first = true;
+ outer:
+ while (true) {
+ if (first) {
+ first = false;
+ } else {
+ break;
+ }
+ await for (var x in controller.stream) {
+ for (int j = 0; j < 10; j++) {
+ if (j == 5) continue outer;
+ }
+ }
+ }
+ } finally {
+ Expect.isTrue(canceled);
+ }
+}
+
+test() async {
+ await test1();
+ await test2();
+}
+
+main() {
+ asyncStart();
+ test().then((_) {
+ asyncEnd();
+ });
+}
+
+// Create a stream that produces numbers [1, 2, ... ]
+StreamController infiniteStreamController() {
+ late StreamController controller;
+ Timer timer;
+ int counter = 0;
+
+ void tick() {
+ if (controller.isPaused) {
+ return;
+ }
+ if (canceled) {
+ return;
+ }
+ counter++;
+ controller.add(counter); // Ask stream to send counter values as event.
+ Timer.run(tick);
+ }
+
+ void startTimer() {
+ Timer.run(tick);
+ }
+
+ controller = new StreamController(
+ onListen: startTimer,
+ onResume: startTimer,
+ onCancel: () {
+ canceled = true;
+ });
+
+ return controller;
+}
diff --git a/tests/language/await/for_test.dart b/tests/language/await/for_test.dart
new file mode 100644
index 0000000..0c72a4d
--- /dev/null
+++ b/tests/language/await/for_test.dart
@@ -0,0 +1,152 @@
+// Copyright (c) 2014, 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.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+class Trace {
+ String trace = "";
+ record(x) {
+ trace += x.toString();
+ }
+
+ toString() => trace;
+}
+
+Stream makeMeAStream() {
+ return timedCounter(5);
+}
+
+Trace t1 = new Trace();
+
+Future consumeOne() async {
+ // Equivalent to await for (x in makeMeAStream()) { ... }
+ var s = makeMeAStream();
+ var it = new StreamIterator(s);
+ while (await it.moveNext()) {
+ var x = it.current;
+ t1.record(x);
+ }
+ t1.record("X");
+}
+
+Trace t2 = new Trace();
+
+Future consumeTwo() async {
+ await for (var x in makeMeAStream()) {
+ t2.record(x);
+ }
+ t2.record("Y");
+}
+
+Trace t3 = new Trace();
+
+Future consumeNested() async {
+ await for (var x in makeMeAStream()) {
+ t3.record(x);
+ await for (var y in makeMeAStream()) {
+ t3.record(y);
+ }
+ t3.record("|");
+ }
+ t3.record("Z");
+}
+
+Trace t4 = new Trace();
+
+Future consumeSomeOfInfinite() async {
+ int i = 0;
+ await for (var x in infiniteStream()) {
+ i++;
+ if (i > 10) break;
+ t4.record(x);
+ }
+ t4.record("U");
+}
+
+main() {
+ var f1 = consumeOne();
+ t1.record("T1:");
+
+ var f2 = consumeTwo();
+ t2.record("T2:");
+
+ var f3 = consumeNested();
+ t3.record("T3:");
+
+ var f4 = consumeSomeOfInfinite();
+ t4.record("T4:");
+
+ asyncStart();
+ Future.wait([f1, f2, f3, f4]).then((_) {
+ Expect.equals("T1:12345X", t1.toString());
+ Expect.equals("T2:12345Y", t2.toString());
+ Expect.equals("T3:112345|212345|312345|412345|512345|Z", t3.toString());
+ Expect.equals("T4:12345678910U", t4.toString());
+ asyncEnd();
+ });
+}
+
+// Create a stream that produces numbers [1, 2, ... maxCount]
+Stream timedCounter(int maxCount) {
+ late StreamController controller;
+ Timer? timer;
+ int counter = 0;
+
+ void tick(_) {
+ counter++;
+ controller.add(counter); // Ask stream to send counter values as event.
+ if (counter >= maxCount) {
+ timer!.cancel();
+ controller.close(); // Ask stream to shut down and tell listeners.
+ }
+ }
+
+ void startTimer() {
+ timer = new Timer.periodic(const Duration(milliseconds: 10), tick);
+ }
+
+ void stopTimer() {
+ timer?.cancel();
+ timer = null;
+ }
+
+ controller = new StreamController(
+ onListen: startTimer,
+ onPause: stopTimer,
+ onResume: startTimer,
+ onCancel: stopTimer);
+
+ return controller.stream;
+}
+
+// Create a stream that produces numbers [1, 2, ... ]
+Stream infiniteStream() {
+ late StreamController controller;
+ Timer? timer;
+ int counter = 0;
+
+ void tick(_) {
+ counter++;
+ controller.add(counter); // Ask stream to send counter values as event.
+ }
+
+ void startTimer() {
+ timer = new Timer.periodic(const Duration(milliseconds: 10), tick);
+ }
+
+ void stopTimer() {
+ timer?.cancel();
+ timer = null;
+ }
+
+ controller = new StreamController(
+ onListen: startTimer,
+ onPause: stopTimer,
+ onResume: startTimer,
+ onCancel: stopTimer);
+
+ return controller.stream;
+}
diff --git a/tests/language/await/for_use_local_test.dart b/tests/language/await/for_use_local_test.dart
new file mode 100644
index 0000000..7ebe7e6
--- /dev/null
+++ b/tests/language/await/for_use_local_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2015, 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.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+sumStream(Stream<int> s) async {
+ int accum = 0;
+ await for (var v in s) {
+ accum += v;
+ }
+ return accum;
+}
+
+test() async {
+ var countStreamController;
+ int i = 0;
+ void tick() {
+ if (i < 10) {
+ countStreamController.add(i);
+ i++;
+ scheduleMicrotask(tick);
+ } else {
+ countStreamController.close();
+ }
+ }
+
+ countStreamController = new StreamController<int>(onListen: () {
+ scheduleMicrotask(tick);
+ });
+ Expect.equals(45, await sumStream(countStreamController.stream));
+}
+
+void main() {
+ asyncStart();
+ test().then((_) => asyncEnd());
+}
diff --git a/tests/language/await/future_test.dart b/tests/language/await/future_test.dart
new file mode 100644
index 0000000..bfd11e6
--- /dev/null
+++ b/tests/language/await/future_test.dart
@@ -0,0 +1,236 @@
+// Copyright (c) 2014, 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=--optimization-counter-threshold=5
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+
+import 'dart:async';
+
+// It does not matter where a future is generated.
+bar(p) async => p;
+baz(p) => new Future(() => p);
+
+foo() async {
+ var b = 0;
+ for (int i = 0; i < 10; i++) {
+ b += ((await bar(1)) + (await baz(2))) as int;
+ }
+ return b;
+}
+
+faa() async => (await bar('faa')).length;
+
+quaz(p) async {
+ var x = 0;
+ try {
+ for (var j = 0; j < 10; j++) {
+ x += (await baz(j)) as int;
+ }
+ return x;
+ } finally {
+ Expect.equals(x, 45);
+ return p;
+ }
+}
+
+quazz() async {
+ var x = 0;
+ try {
+ try {
+ x = await bar(1);
+ throw x;
+ } catch (e1) {
+ var y = await baz(e1 + 1);
+ throw y;
+ }
+ } catch (e2) {
+ return e2;
+ }
+}
+
+nesting() async {
+ try {
+ try {
+ var x = 1;
+ var y = () async {
+ try {
+ var z = (await bar(3)) + x;
+ throw z;
+ } catch (e1) {
+ return e1;
+ }
+ };
+ var a = await y();
+ throw a;
+ } catch (e2) {
+ throw e2 + 1;
+ }
+ } catch (e3) {
+ return e3;
+ }
+}
+
+awaitAsUnary(a, b) async {
+ return await a + await b;
+}
+
+awaitIf(p) async {
+ if (p < (await bar(5))) {
+ return "p<5";
+ } else {
+ return "p>=5";
+ }
+}
+
+awaitNestedIf(p, q) async {
+ if (p == (await bar(5))) {
+ if (q < (await bar(7))) {
+ return "q<7";
+ } else {
+ return "q>=7";
+ }
+ } else {
+ return "p!=5";
+ }
+ return "!";
+}
+
+awaitElseIf(p) async {
+ if (p > (await bar(5))) {
+ return "p>5";
+ } else if (p < (await bar(5))) {
+ return "p<5";
+ } else {
+ return "p==5";
+ }
+ return "!";
+}
+
+awaitReturn() async {
+ return await bar(17);
+}
+
+awaitSwitch() async {
+ switch (await bar(3)) {
+ case 1:
+ return 1;
+ break;
+ case 3:
+ return 3;
+ break;
+ default:
+ return -1;
+ }
+}
+
+awaitNestedWhile(int i, int j) async {
+ int savedJ = j;
+ var decI = () async {
+ return i--;
+ };
+ var decJ = () async {
+ return j--;
+ };
+ var k = 0;
+ while ((await decI()) > 0) {
+ j = savedJ;
+ while (0 < (await decJ())) {
+ k++;
+ }
+ }
+ return k;
+}
+
+awaitNestedDoWhile(int i, int j) async {
+ int savedJ = j;
+ var decI = () async {
+ return i--;
+ };
+ var decJ = () async {
+ return j--;
+ };
+ var k = 0;
+ do {
+ do {
+ k++;
+ } while (0 < (await decI()));
+ } while ((await decJ()) > 0);
+ return k;
+}
+
+awaitFor() async {
+ var asyncInc = (p) async => p + 1;
+ var k = 0;
+ for (int j = (await bar(0)), i = (await bar(1));
+ j < (await bar(5));
+ j = (await asyncInc(j)), i = (await asyncInc(i))) {
+ k += i;
+ k += j;
+ }
+ return k;
+}
+
+awaitForIn() async {
+ var list = ['a', 'b', 'c'];
+ var k = '';
+ for (var c in (await bar(list))) {
+ k += c;
+ }
+ return k;
+}
+
+test() async {
+ var result;
+ for (int i = 0; i < 10; i++) {
+ result = await foo();
+ Expect.equals(30, result);
+ result = await faa();
+ Expect.equals(3, result);
+ result = await quaz(17);
+ Expect.equals(17, result);
+ result = await quazz();
+ Expect.equals(2, result);
+ result = await nesting();
+ Expect.equals(5, result);
+ result = await awaitIf(3);
+ Expect.equals("p<5", result);
+ result = await awaitIf(5);
+ Expect.equals("p>=5", result);
+ result = await awaitNestedIf(5, 3);
+ Expect.equals("q<7", result);
+ result = await awaitNestedIf(5, 8);
+ Expect.equals("q>=7", result);
+ result = await awaitNestedIf(3, 8);
+ Expect.equals("p!=5", result);
+ result = await awaitReturn();
+ Expect.equals(17, result);
+ result = await awaitSwitch();
+ Expect.equals(3, result);
+ result = await awaitElseIf(6);
+ Expect.equals("p>5", result);
+ result = await awaitElseIf(4);
+ Expect.equals("p<5", result);
+ result = await awaitElseIf(5);
+ Expect.equals("p==5", result);
+ result = await awaitNestedWhile(5, 3);
+ Expect.equals(15, result);
+ result = await awaitNestedWhile(4, 6);
+ Expect.equals(24, result);
+ result = await awaitAsUnary(bar(1), bar(2));
+ Expect.equals(3, result);
+ result = await awaitFor();
+ Expect.equals(25, result);
+ result = await awaitForIn();
+ Expect.equals('abc', result);
+ }
+}
+
+main() {
+ asyncStart();
+ test().then((_) {
+ asyncEnd();
+ });
+}
diff --git a/tests/language/await/in_cascade_test.dart b/tests/language/await/in_cascade_test.dart
new file mode 100644
index 0000000..7049e73
--- /dev/null
+++ b/tests/language/await/in_cascade_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2016, 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.
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+
+class C {
+ Future<List<int>> m() async => []..add(await _m());
+ Future<int> _m() async => 42;
+}
+
+main() async {
+ Expect.equals((await new C().m()).first, 42);
+}
diff --git a/tests/language/await/nonfuture_test.dart b/tests/language/await/nonfuture_test.dart
new file mode 100644
index 0000000..1aa6855
--- /dev/null
+++ b/tests/language/await/nonfuture_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2014, 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=--optimization-counter-threshold=5
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+var X = 0;
+
+foo() async {
+ Expect.equals(X, 0);
+ await 5;
+ Expect.equals(X, 10);
+ return await 499;
+}
+
+main() {
+ asyncStart();
+ var f = foo();
+ f.then((res) {
+ Expect.equals(499, res);
+ asyncEnd();
+ });
+ X = 10;
+}
diff --git a/tests/language/await/null_aware_test.dart b/tests/language/await/null_aware_test.dart
new file mode 100644
index 0000000..819de12
--- /dev/null
+++ b/tests/language/await/null_aware_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for issue dartbug.com/24392
+
+import 'package:expect/expect.dart';
+import 'dart:async';
+
+Future<int?> f() async {
+ // Unreachable.
+ Expect.isTrue(false);
+}
+
+main() async {
+ int? x = 1;
+ x ??= await f();
+ Expect.equals(1, x);
+
+ int? y = 1;
+ y = y ?? await f();
+ Expect.equals(1, y);
+}
diff --git a/tests/language/await/postfix_expr_test.dart b/tests/language/await/postfix_expr_test.dart
new file mode 100644
index 0000000..9295844
--- /dev/null
+++ b/tests/language/await/postfix_expr_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2015, 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.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+post0(a) async {
+ return await a++;
+}
+
+post1(a) async {
+ return await a++ + await a++;
+}
+
+pref0(a) async {
+ return await ++a;
+}
+
+pref1(a) async {
+ return await ++a + await ++a;
+}
+
+sum(List<int> a) async {
+ var s = 0;
+ for (int i = 0; i < a.length; /* nothing */) {
+ s += a[await i++];
+ }
+ return s;
+}
+
+// Adapted from repro case for issue 22875.
+sum2(n) async {
+ int i, s = 0;
+ for (i = 1; i <= n; await i++) {
+ // The loop-local variable j was necessary for the crash in 22785.
+ var j = await i;
+ s += j;
+ }
+ return s;
+}
+
+test() async {
+ Expect.equals(10, await post0(10));
+ Expect.equals(21, await post1(10));
+ Expect.equals(11, await pref0(10));
+ Expect.equals(23, await pref1(10));
+ Expect.equals(10, await sum([1, 2, 3, 4]));
+ Expect.equals(10, await sum2(4));
+}
+
+main() {
+ asyncStart();
+ test().then((_) {
+ asyncEnd();
+ });
+}
diff --git a/tests/language/await/regression_test.dart b/tests/language/await/regression_test.dart
new file mode 100644
index 0000000..44031d8
--- /dev/null
+++ b/tests/language/await/regression_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2014, 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.
+//
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+
+later(vodka) => new Future.value(vodka);
+
+manana(tequila) async => tequila;
+
+// Regression test for issue 21536.
+testNestedFunctions() async {
+ var a = await later('Asterix').then((tonic) {
+ return later(tonic);
+ });
+ var o = await manana('Obelix').then(manana);
+ Expect.equals("$a and $o", "Asterix and Obelix");
+}
+
+addLater({a, b}) => new Future.value(a + b);
+
+// Regression test for issue 21480.
+testNamedArguments() async {
+ var sum = await addLater(a: 5, b: 10);
+ Expect.equals(sum, 15);
+ sum = await addLater(b: 11, a: -11);
+ Expect.equals(sum, 0);
+}
+
+testSideEffects() async {
+ Future foo(int a1, int a2) {
+ Expect.equals(10, a1);
+ Expect.equals(11, a2);
+ return new Future.value();
+ }
+
+ int a = 10;
+ await foo(a++, a++);
+ Expect.equals(12, a);
+}
+
+main() async {
+ testNestedFunctions();
+ testNamedArguments();
+ testSideEffects();
+}
diff --git a/tests/language/await/started_immediately_test.dart b/tests/language/await/started_immediately_test.dart
new file mode 100644
index 0000000..c21591f
--- /dev/null
+++ b/tests/language/await/started_immediately_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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.
+
+// Test that an async function does start immediately.
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+var x = 0;
+
+foo() async {
+ x++;
+ await 1;
+ x++;
+}
+
+void main() {
+ asyncStart();
+ foo().then((_) => Expect.equals(2, x)).whenComplete(asyncEnd);
+ Expect.equals(1, x);
+}
diff --git a/tests/language/bool/bool_test.dart b/tests/language/bool/bool_test.dart
new file mode 100644
index 0000000..51d4d9f
--- /dev/null
+++ b/tests/language/bool/bool_test.dart
@@ -0,0 +1,210 @@
+// Copyright (c) 2011, 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.
+
+import "package:expect/expect.dart";
+
+class BoolTest {
+ static void testEquality() {
+ Expect.equals(true, true);
+ Expect.equals(false, false);
+ Expect.isTrue(identical(true, true));
+ Expect.isFalse(identical(true, false));
+ Expect.isTrue(identical(false, false));
+ Expect.isFalse(identical(false, true));
+ Expect.isFalse(!identical(true, true));
+ Expect.isTrue(!identical(true, false));
+ Expect.isFalse(!identical(false, false));
+ Expect.isTrue(!identical(false, true));
+ Expect.isTrue(true == true);
+ Expect.isFalse(true == false);
+ Expect.isTrue(false == false);
+ Expect.isFalse(false == true);
+ Expect.isFalse(true != true);
+ Expect.isTrue(true != false);
+ Expect.isFalse(false != false);
+ Expect.isTrue(false != true);
+ Expect.isTrue(identical(true, (true == true)));
+ Expect.isTrue(identical(false, (true == false)));
+ Expect.isTrue(identical(true, (false == false)));
+ Expect.isTrue(identical(false, (false == true)));
+ Expect.isFalse(!identical(true, (true == true)));
+ Expect.isFalse(!identical(false, (true == false)));
+ Expect.isFalse(!identical(true, (false == false)));
+ Expect.isFalse(!identical(false, (false == true)));
+ Expect.isFalse(identical(false, (true == true)));
+ Expect.isFalse(identical(true, (true == false)));
+ Expect.isFalse(identical(false, (false == false)));
+ Expect.isFalse(identical(true, (false == true)));
+ Expect.isTrue(!identical(false, (true == true)));
+ Expect.isTrue(!identical(true, (true == false)));
+ Expect.isTrue(!identical(false, (false == false)));
+ Expect.isTrue(!identical(true, (false == true)));
+ // Expect.equals could rely on a broken boolean equality.
+ if (true == false) {
+ throw "Expect.equals broken";
+ }
+ if (false == true) {
+ throw "Expect.equals broken";
+ }
+ if (identical(true, false)) {
+ throw "Expect.equals broken";
+ }
+ if (identical(false, true)) {
+ throw "Expect.equals broken";
+ }
+ if (true == true) {} else {
+ throw "Expect.equals broken";
+ }
+ if (false == false) {} else {
+ throw "Expect.equals broken";
+ }
+ if (identical(true, true)) {} else {
+ throw "Expect.equals broken";
+ }
+ if (identical(false, false)) {} else {
+ throw "Expect.equals broken";
+ }
+ if (true != false) {} else {
+ throw "Expect.equals broken";
+ }
+ if (false != true) {} else {
+ throw "Expect.equals broken";
+ }
+ if (!identical(true, false)) {} else {
+ throw "Expect.equals broken";
+ }
+ if (!identical(false, true)) {} else {
+ throw "Expect.equals broken";
+ }
+ if (true != true) {
+ throw "Expect.equals broken";
+ }
+ if (false != false) {
+ throw "Expect.equals broken";
+ }
+ if (!identical(true, true)) {
+ throw "Expect.equals broken";
+ }
+ if (!identical(false, false)) {
+ throw "Expect.equals broken";
+ }
+ }
+
+ static void testToString() {
+ Expect.equals("true", true.toString());
+ Expect.equals("false", false.toString());
+ }
+
+ static void testNegate(isTrue, isFalse) {
+ Expect.equals(true, !false);
+ Expect.equals(false, !true);
+ Expect.equals(true, !isFalse);
+ Expect.equals(false, !isTrue);
+ }
+
+ static void testLogicalOp() {
+ testOr(a, b, onTypeError) {
+ try {
+ return a || b;
+ } on TypeError catch (t) {
+ return onTypeError;
+ }
+ }
+
+ testAnd(a, b, onTypeError) {
+ try {
+ return a && b;
+ } on TypeError catch (t) {
+ return onTypeError;
+ }
+ }
+
+ var isTrue = true;
+ var isFalse = false;
+ Expect.equals(true, testAnd(isTrue, isTrue, false));
+ Expect.equals(false, testAnd(isTrue, 0, false));
+ Expect.equals(false, testAnd(isTrue, 1, false));
+ Expect.equals(false, testAnd(isTrue, "true", false));
+ Expect.equals(false, testAnd(0, isTrue, false));
+ Expect.equals(false, testAnd(1, isTrue, false));
+
+ Expect.equals(true, testOr(isTrue, isTrue, false));
+ Expect.equals(true, testOr(isFalse, isTrue, false));
+ Expect.equals(true, testOr(isTrue, isFalse, false));
+ Expect.equals(true, testOr(isTrue, 0, true));
+ Expect.equals(true, testOr(isTrue, 1, true));
+ Expect.equals(false, testOr(isFalse, 0, false));
+ Expect.equals(false, testOr(isFalse, 1, false));
+ Expect.equals(true, testOr(0, isTrue, true));
+ Expect.equals(true, testOr(1, isTrue, true));
+ Expect.equals(false, testOr(0, isFalse, false));
+ Expect.equals(false, testOr(1, isFalse, false));
+
+ // Test side effects.
+ int trueCount = 0, falseCount = 0;
+
+ trueFunc() {
+ trueCount++;
+ return true;
+ }
+
+ falseFunc() {
+ falseCount++;
+ return false;
+ }
+
+ Expect.equals(0, trueCount);
+ Expect.equals(0, falseCount);
+
+ trueFunc() && trueFunc();
+ Expect.equals(2, trueCount);
+ Expect.equals(0, falseCount);
+
+ trueCount = falseCount = 0;
+ falseFunc() && trueFunc();
+ Expect.equals(0, trueCount);
+ Expect.equals(1, falseCount);
+
+ trueCount = falseCount = 0;
+ trueFunc() && falseFunc();
+ Expect.equals(1, trueCount);
+ Expect.equals(1, falseCount);
+
+ trueCount = falseCount = 0;
+ falseFunc() && falseFunc();
+ Expect.equals(0, trueCount);
+ Expect.equals(1, falseCount);
+
+ trueCount = falseCount = 0;
+ trueFunc() || trueFunc();
+ Expect.equals(1, trueCount);
+ Expect.equals(0, falseCount);
+
+ trueCount = falseCount = 0;
+ falseFunc() || trueFunc();
+ Expect.equals(1, trueCount);
+ Expect.equals(1, falseCount);
+
+ trueCount = falseCount = 0;
+ trueFunc() || falseFunc();
+ Expect.equals(1, trueCount);
+ Expect.equals(0, falseCount);
+
+ trueCount = falseCount = 0;
+ falseFunc() || falseFunc();
+ Expect.equals(0, trueCount);
+ Expect.equals(2, falseCount);
+ }
+
+ static void testMain() {
+ testEquality();
+ testNegate(true, false);
+ testToString();
+ testLogicalOp();
+ }
+}
+
+main() {
+ BoolTest.testMain();
+}
diff --git a/tests/language/bool/check_test.dart b/tests/language/bool/check_test.dart
new file mode 100644
index 0000000..b26eba7
--- /dev/null
+++ b/tests/language/bool/check_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, 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.
+
+import "package:expect/expect.dart";
+
+main() {
+ Expect.throwsTypeError(() {
+ if (null as dynamic) {}
+ });
+
+ Expect.throwsTypeError(() {
+ if ("true" as dynamic) {}
+ });
+}
diff --git a/tests/language/bool/condition_check_test.dart b/tests/language/bool/condition_check_test.dart
new file mode 100644
index 0000000..dd648c7
--- /dev/null
+++ b/tests/language/bool/condition_check_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2015, 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.
+
+// Check that passing `null` for a boolean typed parameter will still cause
+// a boolean conversion error when used in a condition.
+
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+String check({bool? a, bool? b}) {
+ String aString = (a as dynamic) ? 'a' : '';
+ String bString = (b as dynamic) ? 'b' : '';
+ return '$aString$bString';
+}
+
+class Class {
+ final String field;
+ Class({bool? a: false, bool? b: true}) : this.field = check(a: a, b: b);
+}
+
+main() {
+ Expect.throwsTypeError(() => new Class(a: null, b: null).field);
+}
diff --git a/tests/language/call/argument_inference_test.dart b/tests/language/call/argument_inference_test.dart
new file mode 100644
index 0000000..0af5537
--- /dev/null
+++ b/tests/language/call/argument_inference_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+
+class A {
+ call(a) => a is num;
+}
+
+main() {
+ Expect.isTrue(new A().call(42));
+ Expect.isFalse(new A()('foo'));
+}
diff --git a/tests/language/call/call_test.dart b/tests/language/call/call_test.dart
new file mode 100644
index 0000000..882eeb4
--- /dev/null
+++ b/tests/language/call/call_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2012, 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=--optimization_counter_threshold=10 --no-background_compilation
+
+import "package:expect/expect.dart";
+
+main() {
+ bar(a) {
+ return a is String;
+ }
+
+ for (var i = 0; i < 20; i++) {
+ Expect.isFalse(bar(1));
+ Expect.isTrue(bar.call('foo'));
+ }
+
+ opt_arg([a = "a"]) => a is String;
+
+ for (var i = 0; i < 20; i++) {
+ Expect.isFalse(opt_arg(1));
+ Expect.isFalse(opt_arg.call(1));
+ Expect.isTrue(opt_arg());
+ Expect.isTrue(opt_arg.call());
+ Expect.isTrue(opt_arg("b"));
+ Expect.isTrue(opt_arg.call("b"));
+ }
+
+ named_arg({x: 11, y: 22}) => "$x$y";
+
+ for (var i = 0; i < 20; i++) {
+ Expect.equals("1122", named_arg());
+ Expect.equals("1122", named_arg.call());
+ Expect.equals("4455", named_arg(y: 55, x: 44));
+ Expect.equals("4455", named_arg.call(y: 55, x: 44));
+ Expect.equals("4455", named_arg(x: 44, y: 55));
+ Expect.equals("4455", named_arg.call(x: 44, y: 55));
+ }
+
+ Expect.throwsNoSuchMethodError(() => (bar as dynamic).call());
+ Expect.throwsNoSuchMethodError(() => (opt_arg as dynamic).call(x: "p"));
+ Expect.throwsNoSuchMethodError(() => (named_arg as dynamic).call("p", "q"));
+}
diff --git a/tests/language/call/closurization_test.dart b/tests/language/call/closurization_test.dart
new file mode 100644
index 0000000..683c229
--- /dev/null
+++ b/tests/language/call/closurization_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2014, 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=--optimization_counter_threshold=10 --no-background_compilation
+
+import "package:expect/expect.dart";
+
+main() {
+ bar(a) {
+ return a is String;
+ }
+
+ var bar_tearOff = bar.call;
+
+ for (var i = 0; i < 20; i++) {
+ Expect.isFalse(bar_tearOff(1));
+ Expect.isTrue(bar_tearOff.call('foo'));
+ Expect.isFalse(bar_tearOff.call(1));
+ Expect.isTrue(bar_tearOff('foo'));
+ }
+
+ opt_arg([a = "a"]) => a is String;
+ var opt_arg_tearOff = opt_arg.call;
+
+ for (var i = 0; i < 20; i++) {
+ Expect.isFalse(opt_arg_tearOff(1));
+ Expect.isFalse(opt_arg_tearOff.call(1));
+ Expect.isTrue(opt_arg_tearOff());
+ Expect.isTrue(opt_arg_tearOff.call());
+ Expect.isTrue(opt_arg_tearOff("b"));
+ Expect.isTrue(opt_arg_tearOff.call("b"));
+ }
+
+ named_arg({x: 11, y: 22}) => "$x$y";
+ var named_arg_tearOff = named_arg.call;
+
+ for (var i = 0; i < 20; i++) {
+ Expect.equals("1122", named_arg_tearOff());
+ Expect.equals("1122", named_arg_tearOff.call());
+ Expect.equals("4455", named_arg_tearOff(y: 55, x: 44));
+ Expect.equals("4455", named_arg_tearOff.call(y: 55, x: 44));
+ Expect.equals("4455", named_arg_tearOff(x: 44, y: 55));
+ Expect.equals("4455", named_arg_tearOff.call(x: 44, y: 55));
+ }
+
+ // In order to test runtime behavior of calling with invalid arguments,
+ // we cast to dynamic to make the type system forget about the actual types.
+ dynamic bar_tearOff_d = bar_tearOff;
+ dynamic opt_arg_tearOff_d = opt_arg_tearOff;
+ dynamic named_arg_tearOff_d = named_arg_tearOff;
+ Expect.throws(() => bar_tearOff_d.call());
+ Expect.throwsNoSuchMethodError(() => opt_arg_tearOff_d.call(x: "p"));
+ Expect.throwsNoSuchMethodError(() => named_arg_tearOff_d.call("p", "q"));
+}
diff --git a/tests/language/call/constructor_on_unresolvable_class_runtime_test.dart b/tests/language/call/constructor_on_unresolvable_class_runtime_test.dart
new file mode 100644
index 0000000..0c30e8b
--- /dev/null
+++ b/tests/language/call/constructor_on_unresolvable_class_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, 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.
+
+// Check that calling a constructor of a class that cannot be resolved causes
+// compile error.
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+main() {
+
+
+
+}
diff --git a/tests/language/call/constructor_on_unresolvable_class_test.dart b/tests/language/call/constructor_on_unresolvable_class_test.dart
new file mode 100644
index 0000000..d068b53
--- /dev/null
+++ b/tests/language/call/constructor_on_unresolvable_class_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2012, 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.
+
+// Check that calling a constructor of a class that cannot be resolved causes
+// compile error.
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+main() {
+ new A();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [cfe] Method not found: 'A'.
+ new A.foo();
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [cfe] Method not found: 'A.foo'.
+ new lib.A();
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [cfe] Method not found: 'lib.A'.
+}
diff --git a/tests/language/call/function2_test.dart b/tests/language/call/function2_test.dart
new file mode 100644
index 0000000..31c98b1
--- /dev/null
+++ b/tests/language/call/function2_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, 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.
+
+import "package:expect/expect.dart";
+
+typedef Object Func(Object x);
+
+class Bar {
+ int x = 42;
+
+ Object call(Object x) {
+ return 'Bar $x';
+ }
+}
+
+Object baz(Object x) => x;
+
+var map = <String, Func>{'baz': baz, 'bar': new Bar()};
+
+Object test(String str, Object arg) {
+ return map[str]!.call(arg);
+}
+
+void main() {
+ Expect.equals(42, test('baz', 42));
+ Expect.equals('Bar 42', test('bar', 42));
+}
diff --git a/tests/language/call/function_apply_test.dart b/tests/language/call/function_apply_test.dart
new file mode 100644
index 0000000..935cfaf
--- /dev/null
+++ b/tests/language/call/function_apply_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2015, 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.
+
+import "package:expect/expect.dart";
+
+class A {
+ call({a: 42}) {
+ return 499 + a;
+ }
+}
+
+main() {
+ Expect.equals(497, Function.apply(new A(), [], {#a: -2}));
+}
diff --git a/tests/language/call/function_test.dart b/tests/language/call/function_test.dart
new file mode 100644
index 0000000..49d8b7c
--- /dev/null
+++ b/tests/language/call/function_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2015, 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.
+
+import "package:expect/expect.dart";
+
+Object bar(Object x) {
+ return x;
+}
+
+Function baz = bar;
+
+dynamic dyn = bar;
+
+class Foo {
+ Object call(Object x) {
+ return 'Foo$x';
+ }
+}
+
+typedef Object FooType(Object x);
+FooType foo = bar;
+
+void main() {
+ Expect.equals(42, bar.call(42));
+ Expect.equals(42, baz.call(42));
+ Expect.equals(42, foo.call(42));
+ Expect.equals(42, dyn.call(42));
+ Expect.equals(42, bar(42));
+ Expect.equals(42, baz(42));
+ Expect.equals(42, foo(42));
+ Expect.equals(42, dyn(42));
+
+ baz = new Foo();
+ foo = new Foo();
+ dyn = new Foo();
+ Expect.equals('Foo42', baz.call(42));
+ Expect.equals('Foo42', foo.call(42));
+ Expect.equals('Foo42', dyn.call(42));
+ Expect.equals('Foo42', baz(42));
+ Expect.equals('Foo42', foo(42));
+ Expect.equals('Foo42', dyn(42));
+
+ var s = (FooType).toString();
+ var minified = s != 'FooType'; // dart2js --minify has minified names.
+ dynamic d = null;
+ Expect.throws(() => d(),
+ (e) => e is NoSuchMethodError && (minified || '$e'.contains('call')));
+}
diff --git a/tests/language/call/method_as_cast_test.dart b/tests/language/call/method_as_cast_test.dart
new file mode 100644
index 0000000..f0718a3
--- /dev/null
+++ b/tests/language/call/method_as_cast_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class B {}
+
+class C {
+ B call(B b) => b;
+}
+
+class D implements Function {
+ B call(B b) => b;
+}
+
+typedef B BToB(B x);
+
+typedef Object NullToObject(Null x);
+
+main() {
+ // The presence of a `.call` method does not cause class `C` to become a
+ // subtype of any function type.
+ C c = new C();
+ Expect.throwsCastError(() => c as BToB); //# 01: ok
+ Expect.throwsCastError(() => c as NullToObject); //# 02: ok
+ Expect.throwsCastError(() => c as Function); //# 03: ok
+
+ // The same goes for class `D`: `implements Function` is ignored in Dart 2.
+ D d = new D();
+ Expect.throwsCastError(() => d as BToB); //# 04: ok
+ Expect.throwsCastError(() => d as NullToObject); //# 05: ok
+ Expect.throwsCastError(() => d as Function); //# 06: ok
+}
diff --git a/tests/language/call/method_function_typed_value_test.dart b/tests/language/call/method_function_typed_value_test.dart
new file mode 100644
index 0000000..7aa9ed8
--- /dev/null
+++ b/tests/language/call/method_function_typed_value_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+int f(int i) => 2 * i;
+
+typedef int IntToInt(int x);
+
+main() {
+ // It is possible to use `.call` on a function-typed value (even though it is
+ // redundant). Similarly, it is possible to tear off `.call` on a
+ // function-typed value (but it is a no-op).
+ Expect.equals(f.call(1), 2); //# 01: ok
+ Expect.identical(f.call, f); //# 02: ok
+ IntToInt f2 = f;
+ Expect.equals(f2.call(1), 2); //# 03: ok
+ Expect.identical(f2.call, f); //# 04: ok
+ Function f3 = f;
+ Expect.equals(f3.call(1), 2); //# 05: ok
+ Expect.identical(f3.call, f); //# 06: ok
+ dynamic d = f;
+ Expect.equals(d.call(1), 2); //# 07: ok
+ Expect.identical(d.call, f); //# 08: ok
+}
diff --git a/tests/language/call/method_implicit_invoke_instance_test.dart b/tests/language/call/method_implicit_invoke_instance_test.dart
new file mode 100644
index 0000000..fdcb12b
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_instance_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+class D {
+ C1 c1 = new C1();
+ dynamic d1 = new C1();
+ C2 c2 = new C2();
+ dynamic d2 = new C2();
+
+ void test() {
+ // Implicitly invokes c1.call(1)
+ Expect.equals(c1(1), 2); //# 01: ok
+ // Implicitly invokes d1.call(1)
+ Expect.equals(d1(1), 2); //# 02: ok
+ // Implicitly invokes c2.call(1)
+ Expect.equals(c2(1), 2); //# 03: ok
+ // Implicitly invokes d2.call(1)
+ Expect.equals(d2(1), 2); //# 04: ok
+ }
+}
+
+main() {
+ new D().test();
+ // Implicitly invokes D.c1.call(1)
+ Expect.equals(new D().c1(1), 2); //# 05: ok
+ // Implicitly invokes D.d1.call(1)
+ Expect.equals(new D().d1(1), 2); //# 06: ok
+ // Implicitly invokes D.c2.call(1)
+ Expect.equals(new D().c2(1), 2); //# 07: ok
+ // Implicitly invokes D.d2.call(1)
+ Expect.equals(new D().d2(1), 2); //# 08: ok
+ D d = new D();
+ // Implicitly invokes d.c1.call(1)
+ Expect.equals(d.c1(1), 2); //# 09: ok
+ // Implicitly invokes d.d1.call(1)
+ Expect.equals(d.d1(1), 2); //# 10: ok
+ // Implicitly invokes d.c2.call(1)
+ Expect.equals(d.c2(1), 2); //# 11: ok
+ // Implicitly invokes d.d2.call(1)
+ Expect.equals(d.d2(1), 2); //# 12: ok
+}
diff --git a/tests/language/call/method_implicit_invoke_local_runtime_1_test.dart b/tests/language/call/method_implicit_invoke_local_runtime_1_test.dart
new file mode 100644
index 0000000..5df9be0
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_local_runtime_1_test.dart
@@ -0,0 +1,35 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+main() {
+ C1 c1 = new C1();
+ // Implicitly invokes c1.call(1)
+ Expect.equals(c1(1), 2);
+ dynamic d1 = c1;
+ // Implicitly invokes d1.call(1)
+
+ C2 c2 = new C2();
+ // Implicitly invokes c2.call(1)
+
+ dynamic d2 = c2;
+ // Implicitly invokes d2.call(1)
+
+ // Cannot invoke with the wrong signature.
+
+
+}
diff --git a/tests/language/call/method_implicit_invoke_local_runtime_2_test.dart b/tests/language/call/method_implicit_invoke_local_runtime_2_test.dart
new file mode 100644
index 0000000..b4b00f4
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_local_runtime_2_test.dart
@@ -0,0 +1,35 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+main() {
+ C1 c1 = new C1();
+ // Implicitly invokes c1.call(1)
+
+ dynamic d1 = c1;
+ // Implicitly invokes d1.call(1)
+ Expect.equals(d1(1), 2);
+ C2 c2 = new C2();
+ // Implicitly invokes c2.call(1)
+
+ dynamic d2 = c2;
+ // Implicitly invokes d2.call(1)
+
+ // Cannot invoke with the wrong signature.
+
+
+}
diff --git a/tests/language/call/method_implicit_invoke_local_runtime_3_test.dart b/tests/language/call/method_implicit_invoke_local_runtime_3_test.dart
new file mode 100644
index 0000000..215d998
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_local_runtime_3_test.dart
@@ -0,0 +1,35 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+main() {
+ C1 c1 = new C1();
+ // Implicitly invokes c1.call(1)
+
+ dynamic d1 = c1;
+ // Implicitly invokes d1.call(1)
+
+ C2 c2 = new C2();
+ // Implicitly invokes c2.call(1)
+ Expect.equals(c2(1), 2);
+ dynamic d2 = c2;
+ // Implicitly invokes d2.call(1)
+
+ // Cannot invoke with the wrong signature.
+
+
+}
diff --git a/tests/language/call/method_implicit_invoke_local_runtime_4_test.dart b/tests/language/call/method_implicit_invoke_local_runtime_4_test.dart
new file mode 100644
index 0000000..01a364c
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_local_runtime_4_test.dart
@@ -0,0 +1,35 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+main() {
+ C1 c1 = new C1();
+ // Implicitly invokes c1.call(1)
+
+ dynamic d1 = c1;
+ // Implicitly invokes d1.call(1)
+
+ C2 c2 = new C2();
+ // Implicitly invokes c2.call(1)
+
+ dynamic d2 = c2;
+ // Implicitly invokes d2.call(1)
+ Expect.equals(d2(1), 2);
+ // Cannot invoke with the wrong signature.
+
+
+}
diff --git a/tests/language/call/method_implicit_invoke_local_runtime_test.dart b/tests/language/call/method_implicit_invoke_local_runtime_test.dart
new file mode 100644
index 0000000..f06206f
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_local_runtime_test.dart
@@ -0,0 +1,35 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+main() {
+ C1 c1 = new C1();
+ // Implicitly invokes c1.call(1)
+
+ dynamic d1 = c1;
+ // Implicitly invokes d1.call(1)
+
+ C2 c2 = new C2();
+ // Implicitly invokes c2.call(1)
+
+ dynamic d2 = c2;
+ // Implicitly invokes d2.call(1)
+
+ // Cannot invoke with the wrong signature.
+
+
+}
diff --git a/tests/language/call/method_implicit_invoke_local_test.dart b/tests/language/call/method_implicit_invoke_local_test.dart
new file mode 100644
index 0000000..1e58c47
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_local_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+main() {
+ C1 c1 = new C1();
+ // Implicitly invokes c1.call(1)
+ Expect.equals(c1(1), 2);
+ dynamic d1 = c1;
+ // Implicitly invokes d1.call(1)
+ Expect.equals(d1(1), 2);
+ C2 c2 = new C2();
+ // Implicitly invokes c2.call(1)
+ Expect.equals(c2(1), 2);
+ dynamic d2 = c2;
+ // Implicitly invokes d2.call(1)
+ Expect.equals(d2(1), 2);
+ // Cannot invoke with the wrong signature.
+ c2();
+ //^^
+ // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+ // [cfe] Too few positional arguments: 1 required, 0 given.
+ c2(3, 4);
+ //^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+ // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+}
diff --git a/tests/language/call/method_implicit_invoke_static_test.dart b/tests/language/call/method_implicit_invoke_static_test.dart
new file mode 100644
index 0000000..17f868d
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_static_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+class D {
+ static C1 c1 = new C1();
+ static dynamic d1 = new C1();
+ static C2 c2 = new C2();
+ static dynamic d2 = new C2();
+
+ void test1() {
+ // Implicitly invokes c1.call(1)
+ Expect.equals(c1(1), 2); //# 01: ok
+ // Implicitly invokes d1.call(1)
+ Expect.equals(d1(1), 2); //# 02: ok
+ // Implicitly invokes c2.call(1)
+ Expect.equals(c2(1), 2); //# 03: ok
+ // Implicitly invokes d2.call(1)
+ Expect.equals(d2(1), 2); //# 04: ok
+ }
+
+ static void test2() {
+ // Implicitly invokes c1.call(1)
+ Expect.equals(c1(1), 2); //# 05: ok
+ // Implicitly invokes d1.call(1)
+ Expect.equals(d1(1), 2); //# 06: ok
+ // Implicitly invokes c2.call(1)
+ Expect.equals(c2(1), 2); //# 07: ok
+ // Implicitly invokes d2.call(1)
+ Expect.equals(d2(1), 2); //# 08: ok
+ }
+}
+
+main() {
+ new D().test1();
+ D.test2();
+ // Implicitly invokes D.c1.call(1)
+ Expect.equals(D.c1(1), 2); //# 09: ok
+ // Implicitly invokes D.d1.call(1)
+ Expect.equals(D.d1(1), 2); //# 10: ok
+ // Implicitly invokes D.c2.call(1)
+ Expect.equals(D.c2(1), 2); //# 11: ok
+ // Implicitly invokes D.d2.call(1)
+ Expect.equals(D.d2(1), 2); //# 12: ok
+}
diff --git a/tests/language/call/method_implicit_invoke_top_level_test.dart b/tests/language/call/method_implicit_invoke_top_level_test.dart
new file mode 100644
index 0000000..eaed546
--- /dev/null
+++ b/tests/language/call/method_implicit_invoke_top_level_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C1 {
+ int call(int i) => 2 * i;
+}
+
+class C2 implements Function {
+ int call(int i) => 2 * i;
+}
+
+C1 c1 = new C1();
+dynamic d1 = new C1();
+C2 c2 = new C2();
+dynamic d2 = new C2();
+
+main() {
+ // Implicitly invokes c1.call(1)
+ Expect.equals(c1(1), 2); //# 01: ok
+ // Implicitly invokes d1.call(1)
+ Expect.equals(d1(1), 2); //# 02: ok
+ // Implicitly invokes c2.call(1)
+ Expect.equals(c2(1), 2); //# 03: ok
+ // Implicitly invokes d2.call(1)
+ Expect.equals(d2(1), 2); //# 04: ok
+}
diff --git a/tests/language/call/method_implicit_tear_off_assignable_test.dart b/tests/language/call/method_implicit_tear_off_assignable_test.dart
new file mode 100644
index 0000000..791b083
--- /dev/null
+++ b/tests/language/call/method_implicit_tear_off_assignable_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, 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.
+
+abstract class I {
+ void call();
+}
+
+class C implements I {
+ void call([int x = 0]) {}
+}
+
+main() {
+ I i = new C();
+ // The tear off is attempting to tear off a call method whose type is a
+ // supertype of the target type. Since we no longer allow implicit downcasts,
+ // this is a static error.
+ void Function([int]) f = i;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] unspecified
+}
diff --git a/tests/language/call/method_implicit_tear_off_nullable_test.dart b/tests/language/call/method_implicit_tear_off_nullable_test.dart
new file mode 100644
index 0000000..da2fbce
--- /dev/null
+++ b/tests/language/call/method_implicit_tear_off_nullable_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+class B {}
+
+class C {
+ B call(B b) => b;
+}
+
+typedef B BToB(B x);
+
+C? c = null;
+
+void check(BToB f) {}
+
+main() {
+ // Nullable types cannot have their `.call` method implicitly torn off.
+ check(c);
+ // ^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] unspecified
+}
diff --git a/tests/language/call/method_implicit_tear_off_test.dart b/tests/language/call/method_implicit_tear_off_test.dart
new file mode 100644
index 0000000..24446cb
--- /dev/null
+++ b/tests/language/call/method_implicit_tear_off_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "dart:async";
+import "package:expect/expect.dart";
+
+class B {}
+
+class C {
+ B? call(B? b) => b;
+}
+
+typedef B? BToB(B? x);
+
+typedef Object? NullToObject(Null x);
+
+C c = new C();
+
+void check1(BToB f) {
+ Expect.isFalse(identical(c, f));
+ Expect.equals(c.call, f);
+ B b = new B();
+ Expect.identical(f(b), b);
+}
+
+void check2(FutureOr<BToB> f) {
+ Expect.isFalse(identical(c, f));
+ Expect.equals(c.call, f);
+ BToB f2 = f as BToB;
+ Expect.identical(f, f2);
+ B b = new B();
+ Expect.identical(f2(b), b);
+}
+
+void check3(NullToObject f) {
+ Expect.isFalse(identical(c, f));
+ Expect.equals(c.call, f);
+ Expect.isNull(f(null));
+}
+
+void check4(FutureOr<NullToObject> f) {
+ Expect.isFalse(identical(c, f));
+ Expect.equals(c.call, f);
+ NullToObject f2 = f as NullToObject;
+ Expect.identical(f, f2);
+ Expect.isNull(f2(null));
+}
+
+void check5(Function f) {
+ Expect.isFalse(identical(c, f));
+ Expect.equals(c.call, f);
+ B b = new B();
+ Expect.identical(f(b), b);
+}
+
+void check6(FutureOr<Function> f) {
+ Expect.isFalse(identical(c, f));
+ Expect.equals(c.call, f);
+ Function f2 = f as Function;
+ Expect.identical(f, f2);
+ B b = new B();
+ Expect.identical(f2(b), b);
+}
+
+void check7(C x) {
+ Expect.identical(c, x);
+}
+
+void check8(FutureOr<C> x) {
+ Expect.identical(c, x);
+}
+
+void check9(Object o) {
+ Expect.identical(c, o);
+}
+
+void check10(FutureOr<Object> o) {
+ Expect.identical(c, o);
+}
+
+void check11(dynamic d) {
+ Expect.identical(c, d);
+}
+
+void check12(FutureOr<dynamic> d) {
+ Expect.identical(c, d);
+}
+
+void checkNullableFunction(BToB? f) {
+ Expect.isFalse(identical(c, f));
+ Expect.equals(c.call, f);
+ B b = new B();
+ Expect.identical(f!(b), b);
+}
+
+main() {
+ // Implicitly tears off c.call
+ check1(c); //# 01: ok
+ check2(c); //# 02: ok
+ check3(c); //# 03: ok
+ check4(c); //# 04: ok
+ check5(c); //# 05: ok
+ check6(c); //# 06: ok
+ // Does not tear off c.call
+ check7(c); //# 07: ok
+ check8(c); //# 08: ok
+ check9(c); //# 09: ok
+ check10(c); //# 10: ok
+ check11(c); //# 11: ok
+ check12(c); //# 12: ok
+ // Implicitly tears off c.call even when the context type is nullable.
+ checkNullableFunction(c); //# 13: ok
+}
diff --git a/tests/language/call/method_is_check_test.dart b/tests/language/call/method_is_check_test.dart
new file mode 100644
index 0000000..9c705a3
--- /dev/null
+++ b/tests/language/call/method_is_check_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class B {}
+
+class C {
+ B call(B b) => b;
+}
+
+class D implements Function {
+ B call(B b) => b;
+}
+
+typedef B BToB(B x);
+
+typedef Object NullToObject(Null x);
+
+main() {
+ // The presence of a `.call` method does not cause class `C` to become a
+ // subtype of any function type.
+ C c = new C();
+ Expect.isFalse(c is BToB); //# 01: ok
+ Expect.isFalse(c is NullToObject); //# 02: ok
+ Expect.isFalse(c is Function); //# 03: ok
+
+ // The same goes for class `D`: `implements Function` is ignored in Dart 2.
+ D d = new D();
+ Expect.isFalse(d is BToB); //# 04: ok
+ Expect.isFalse(d is NullToObject); //# 05: ok
+ Expect.isFalse(d is Function); //# 06: ok
+}
diff --git a/tests/language/call/method_must_not_be_field_test.dart b/tests/language/call/method_must_not_be_field_test.dart
new file mode 100644
index 0000000..05cbce9
--- /dev/null
+++ b/tests/language/call/method_must_not_be_field_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C {
+ void Function() call = () {};
+}
+
+main() {
+ C c = new C();
+ dynamic d = c;
+
+ // The presence of a field named `call` does not permit the class `C` to be
+ // implicitly called.
+ c(); //# 01: compile-time error
+ // Nor does it permit an implicit tear-off of `call`.
+ void Function() f = c; //# 02: compile-time error
+ // Nor does it permit a dynamic invocation of `call`.
+ Expect.throws(() => d()); //# 03: ok
+
+ // However, all these things are possible if `call` is mentioned explicitly.
+ c.call(); //# 04: ok
+ void Function() f = c.call; //# 05: ok
+ d.call(); //# 06: ok
+ (d.call)(); //# 07: ok
+}
diff --git a/tests/language/call/method_must_not_be_getter_test.dart b/tests/language/call/method_must_not_be_getter_test.dart
new file mode 100644
index 0000000..ac070dd
--- /dev/null
+++ b/tests/language/call/method_must_not_be_getter_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+import "package:expect/expect.dart";
+
+class C {
+ void Function() get call => () {};
+}
+
+class D {
+ get call => this;
+}
+
+// Recurs outside the try-block to avoid disabling inlining.
+callD() {
+ dynamic d = new D();
+ d();
+}
+
+main() {
+ C c = new C();
+ dynamic d = c;
+
+ // The presence of a getter named `call` does not permit the class `C` to be
+ // implicitly called.
+ c(); //# 01: compile-time error
+ // Nor does it permit an implicit tear-off of `call`.
+ void Function() f = c; //# 02: compile-time error
+ // Nor does it permit a dynamic invocation of `call`.
+ Expect.throws(() => d()); //# 03: ok
+ // Same as previous line, but with a getter that can stack overflow if
+ // incorrect behavior is present. Merged from issue21159_test.
+ Expect.throwsNoSuchMethodError(() => callD()); //# 03: ok
+
+ // However, all these things are possible if `call` is mentioned explicitly.
+ c.call(); //# 04: ok
+ void Function() f = c.call; //# 05: ok
+ d.call(); //# 06: ok
+}
diff --git a/tests/language/call/method_override_runtime_test.dart b/tests/language/call/method_override_runtime_test.dart
new file mode 100644
index 0000000..d69e720
--- /dev/null
+++ b/tests/language/call/method_override_runtime_test.dart
@@ -0,0 +1,32 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+class B {}
+
+class C {
+ B call(B b) => b;
+}
+
+typedef B BToB(B x);
+
+class D {
+ BToB f() => ((B x) => x);
+ void g(C x) {}
+}
+
+class E extends D {
+ // This override is illegal because C is not a subtype of BToB.
+
+
+ // This override is illegal because BToB is not a supertype of C.
+
+}
+
+main() {
+ new E();
+}
diff --git a/tests/language/call/method_override_test.dart b/tests/language/call/method_override_test.dart
new file mode 100644
index 0000000..eaba802
--- /dev/null
+++ b/tests/language/call/method_override_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, 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.
+// Dart test program to test arithmetic operations.
+
+class B {}
+
+class C {
+ B call(B b) => b;
+}
+
+typedef B BToB(B x);
+
+class D {
+ BToB f() => ((B x) => x);
+ void g(C x) {}
+}
+
+class E extends D {
+ // This override is illegal because C is not a subtype of BToB.
+ C f() => C();
+ //^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
+ // [cfe] The return type of the method 'E.f' is 'C', which does not match the return type, 'B Function(B)', of the overridden method, 'D.f'.
+
+ // This override is illegal because BToB is not a supertype of C.
+ void g(BToB x) {}
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
+ // ^
+ // [cfe] The parameter 'x' of the method 'E.g' has type 'B Function(B)', which does not match the corresponding type, 'C', in the overridden method, 'D.g'.
+}
+
+main() {
+ new E();
+}
diff --git a/tests/language/call/non_method_field_runtime_test.dart b/tests/language/call/non_method_field_runtime_test.dart
new file mode 100644
index 0000000..0510151
--- /dev/null
+++ b/tests/language/call/non_method_field_runtime_test.dart
@@ -0,0 +1,22 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, 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.
+
+// Tests calling an object's field which is not a method.
+
+class Fisk {
+ int i = 0;
+}
+
+class Hest extends Fisk {}
+
+main() {
+ Fisk x1 = new Fisk();
+
+
+ Hest x2 = new Hest();
+
+}
diff --git a/tests/language/call/non_method_field_test.dart b/tests/language/call/non_method_field_test.dart
new file mode 100644
index 0000000..83a022d
--- /dev/null
+++ b/tests/language/call/non_method_field_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2012, 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.
+
+// Tests calling an object's field which is not a method.
+
+class Fisk {
+ int i = 0;
+}
+
+class Hest extends Fisk {}
+
+main() {
+ Fisk x1 = new Fisk();
+ x1.i();
+//^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] 'i' isn't a function or method and can't be invoked.
+
+ Hest x2 = new Hest();
+ x2.i();
+//^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] 'i' isn't a function or method and can't be invoked.
+}
diff --git a/tests/language/call/nonexistent_constructor_runtime_test.dart b/tests/language/call/nonexistent_constructor_runtime_test.dart
new file mode 100644
index 0000000..92e4b19
--- /dev/null
+++ b/tests/language/call/nonexistent_constructor_runtime_test.dart
@@ -0,0 +1,25 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, 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.
+
+import "package:expect/expect.dart";
+
+// When attempting to call a nonexistent constructor, check that a
+// compile error is reported.
+
+foo() {
+ throw 'hest';
+}
+
+class A {
+ A.foo(var x) {}
+}
+
+main() {
+ new A.foo(42);
+
+
+}
diff --git a/tests/language/call/nonexistent_constructor_test.dart b/tests/language/call/nonexistent_constructor_test.dart
new file mode 100644
index 0000000..4649f37
--- /dev/null
+++ b/tests/language/call/nonexistent_constructor_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2012, 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.
+
+import "package:expect/expect.dart";
+
+// When attempting to call a nonexistent constructor, check that a
+// compile error is reported.
+
+foo() {
+ throw 'hest';
+}
+
+class A {
+ A.foo(var x) {}
+}
+
+main() {
+ new A.foo(42);
+ new A.bar(foo());
+ // ^^^
+ // [analyzer] STATIC_WARNING.NEW_WITH_UNDEFINED_CONSTRUCTOR
+ // [cfe] Method not found: 'A.bar'.
+ new A();
+ // ^
+ // [analyzer] STATIC_WARNING.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
+ // [cfe] Method not found: 'A'.
+}
diff --git a/tests/language/call/nonexistent_static_test.dart b/tests/language/call/nonexistent_static_test.dart
new file mode 100644
index 0000000..603bdde
--- /dev/null
+++ b/tests/language/call/nonexistent_static_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2012, 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.
+
+import "package:expect/expect.dart";
+
+// When attempting to call a nonexistent static method, getter or setter, check
+// that a compile error is reported.
+
+class C {}
+
+class D {
+ get hest => 1; //# 04: continued
+ set hest(val) {} //# 05: continued
+}
+
+get fisk => 2; //# 09: continued
+set fisk(val) {} //# 10: continued
+
+main() {
+ C.hest = 1; //# 01: compile-time error
+ C.hest; //# 02: compile-time error
+ C.hest(); //# 03: compile-time error
+
+ D.hest = 1; //# 04: compile-time error
+ D.hest; //# 05: compile-time error
+ fisk = 1; //# 06: compile-time error
+ fisk; //# 07: compile-time error
+ fisk(); //# 08: compile-time error
+ fisk = 1; //# 09: compile-time error
+ fisk; //# 10: compile-time error
+}
diff --git a/tests/language/call/object_has_no_call_method_test.dart b/tests/language/call/object_has_no_call_method_test.dart
new file mode 100644
index 0000000..dcb2a5c
--- /dev/null
+++ b/tests/language/call/object_has_no_call_method_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2017, 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.
+
+void test(dynamic d, Object o, Function f) {
+ d();
+ o();
+//^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] The method 'call' isn't defined for the class 'Object'.
+ f();
+ d.call;
+ o.call;
+ //^^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'call' isn't defined for the class 'Object'.
+ f.call;
+ d.call();
+ o.call();
+ //^^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_METHOD
+ // [cfe] The method 'call' isn't defined for the class 'Object'.
+ f.call();
+}
+
+main() {}
diff --git a/tests/language/call/object_has_no_call_runtime_1_test.dart b/tests/language/call/object_has_no_call_runtime_1_test.dart
new file mode 100644
index 0000000..3bb0108
--- /dev/null
+++ b/tests/language/call/object_has_no_call_runtime_1_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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.
+
+void test(dynamic d, Object o, Function f) {
+ d();
+
+
+
+
+
+
+
+
+}
+
+main() {}
diff --git a/tests/language/call/object_has_no_call_runtime_2_test.dart b/tests/language/call/object_has_no_call_runtime_2_test.dart
new file mode 100644
index 0000000..8c209c5
--- /dev/null
+++ b/tests/language/call/object_has_no_call_runtime_2_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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.
+
+void test(dynamic d, Object o, Function f) {
+
+
+ f();
+
+
+
+
+
+
+}
+
+main() {}
diff --git a/tests/language/call/object_has_no_call_runtime_3_test.dart b/tests/language/call/object_has_no_call_runtime_3_test.dart
new file mode 100644
index 0000000..6507f06
--- /dev/null
+++ b/tests/language/call/object_has_no_call_runtime_3_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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.
+
+void test(dynamic d, Object o, Function f) {
+
+
+
+ d.call;
+
+
+
+
+
+}
+
+main() {}
diff --git a/tests/language/call/object_has_no_call_runtime_4_test.dart b/tests/language/call/object_has_no_call_runtime_4_test.dart
new file mode 100644
index 0000000..a64f242
--- /dev/null
+++ b/tests/language/call/object_has_no_call_runtime_4_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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.
+
+void test(dynamic d, Object o, Function f) {
+
+
+
+
+
+ f.call;
+
+
+
+}
+
+main() {}
diff --git a/tests/language/call/object_has_no_call_runtime_5_test.dart b/tests/language/call/object_has_no_call_runtime_5_test.dart
new file mode 100644
index 0000000..ef58c84
--- /dev/null
+++ b/tests/language/call/object_has_no_call_runtime_5_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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.
+
+void test(dynamic d, Object o, Function f) {
+
+
+
+
+
+
+ d.call();
+
+
+}
+
+main() {}
diff --git a/tests/language/call/object_has_no_call_runtime_6_test.dart b/tests/language/call/object_has_no_call_runtime_6_test.dart
new file mode 100644
index 0000000..2dcd453
--- /dev/null
+++ b/tests/language/call/object_has_no_call_runtime_6_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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.
+
+void test(dynamic d, Object o, Function f) {
+
+
+
+
+
+
+
+
+ f.call();
+}
+
+main() {}
diff --git a/tests/language/call/object_has_no_call_runtime_test.dart b/tests/language/call/object_has_no_call_runtime_test.dart
new file mode 100644
index 0000000..c0ec957
--- /dev/null
+++ b/tests/language/call/object_has_no_call_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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.
+
+void test(dynamic d, Object o, Function f) {
+
+
+
+
+
+
+
+
+
+}
+
+main() {}
diff --git a/tests/language/call/operator_test.dart b/tests/language/call/operator_test.dart
new file mode 100644
index 0000000..8513bcb
--- /dev/null
+++ b/tests/language/call/operator_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2012, 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.
+
+import "package:expect/expect.dart";
+
+// simple test with no types in signature
+class A1 {
+ call() => 42;
+}
+
+// same test, include return type
+class A2 {
+ int call() => 35;
+}
+
+class B {
+ call() => 28;
+}
+
+// A call() operator can have any arity
+class C {
+ call(arg) => 7 * arg;
+}
+
+// Test named arguments
+class D {
+ call([arg = 6]) => 7 * arg;
+}
+
+// Non-trivial method body combination of positional and named.
+class E {
+ String call(String str, {int count: 1}) {
+ StringBuffer buffer = new StringBuffer();
+ for (var i = 0; i < count; i++) {
+ buffer.write(str);
+ if (i < count - 1) {
+ buffer.write(":");
+ }
+ }
+ return buffer.toString();
+ }
+}
+
+main() {
+ var a1 = new A1();
+ Expect.equals(42, a1());
+ Expect.equals(42, a1.call());
+
+ var a2 = new A2();
+ Expect.equals(35, a2());
+ Expect.equals(35, a2.call());
+
+ var b = new B();
+ Expect.equals(28, b());
+ Expect.equals(28, b.call());
+
+ var c = new C();
+ Expect.equals(42, c(6));
+ Expect.equals(42, c.call(6));
+
+ var d = new D();
+ Expect.equals(42, d());
+ Expect.equals(7, d(1));
+ Expect.equals(14, d(2));
+ Expect.equals(42, d.call());
+ Expect.equals(7, d.call(1));
+ Expect.equals(14, d.call(2));
+
+ var e = new E();
+ Expect.equals("foo", e("foo"));
+ Expect.equals("foo:foo", e("foo", count: 2));
+ Expect.equals("foo:foo:foo", e("foo", count: 3));
+ Expect.equals("foo", e.call("foo"));
+ Expect.equals("foo:foo", e.call("foo", count: 2));
+ Expect.equals("foo:foo:foo", e.call("foo", count: 3));
+
+ Expect.isFalse(a1 is Function); //# 01: ok
+ Expect.isFalse(e is Function); //# 02: ok
+}
diff --git a/tests/language/call/property_test.dart b/tests/language/call/property_test.dart
new file mode 100644
index 0000000..87407c3
--- /dev/null
+++ b/tests/language/call/property_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, 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.
+
+// Test that a class with a [call] property does not implement [Function] or
+// a typedef of function type.
+
+import 'package:expect/expect.dart';
+
+class Call {
+ int get call => 0;
+}
+
+typedef void F();
+
+main() {
+ Expect.isFalse(new Call() is Function);
+ Expect.isFalse(new Call() is F);
+}
diff --git a/tests/language/call/through_getter_runtime_test.dart b/tests/language/call/through_getter_runtime_test.dart
new file mode 100644
index 0000000..4737aa6
--- /dev/null
+++ b/tests/language/call/through_getter_runtime_test.dart
@@ -0,0 +1,179 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, 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.
+
+import "package:expect/expect.dart";
+
+// Tests that we can call functions through getters.
+
+const TOP_LEVEL_CONST = 1;
+const TOP_LEVEL_CONST_REF = TOP_LEVEL_CONST;
+const TOP_LEVEL_NULL = null;
+
+var topLevel;
+
+class CallThroughGetterTest {
+ static void testMain() {
+ testTopLevel();
+ testField();
+ testGetter();
+ testMethod();
+ testEvaluationOrder();
+ }
+
+ static void testTopLevel() {
+ topLevel = () {
+ return 2;
+ };
+ Expect.equals(1, TOP_LEVEL_CONST);
+ Expect.equals(1, TOP_LEVEL_CONST_REF);
+ Expect.equals(2, topLevel());
+
+
+
+ }
+
+ static void testField() {
+ A a = new A();
+ a.field = () => 42;
+ Expect.equals(42, a.field());
+ Expect.equals(42, (a.field)());
+
+ a.field = () => 87;
+ Expect.equals(87, a.field());
+ Expect.equals(87, (a.field)());
+
+ a.field = 99;
+ Expect.throwsNoSuchMethodError(() => a.field());
+ Expect.throwsNoSuchMethodError(() => (a.field)());
+ }
+
+ static void testGetter() {
+ A a = new A();
+ a.field = () => 42;
+ Expect.equals(42, a.getter());
+ Expect.equals(42, (a.getter)());
+
+ a.field = () => 87;
+ Expect.equals(87, a.getter());
+ Expect.equals(87, (a.getter)());
+
+ a.field = 99;
+ Expect.throwsNoSuchMethodError(() => a.getter());
+ Expect.throwsNoSuchMethodError(() => (a.getter)());
+ }
+
+ static void testMethod() {
+ A a = new A();
+ a.field = () => 42;
+ Expect.equals(true, a.method() is Function);
+ Expect.equals(42, a.method()());
+
+ a.field = () => 87;
+ Expect.equals(true, a.method() is Function);
+ Expect.equals(87, a.method()());
+
+ a.field = null;
+ Expect.equals(null, a.method());
+ }
+
+ static void testEvaluationOrder() {
+ B b = new B();
+ Expect.equals("gf", b.g0());
+ b = new B();
+ Expect.equals("gf", (b.g0)());
+
+ b = new B();
+ Expect.equals("xgf", b.g1(b.x));
+ b = new B();
+ Expect.equals("gxf", (b.g1)(b.x));
+
+ b = new B();
+ Expect.equals("xygf", b.g2(b.x, b.y));
+ b = new B();
+ Expect.equals("gxyf", (b.g2)(b.x, b.y));
+
+ b = new B();
+ Expect.equals("xyzgf", b.g3(b.x, b.y, b.z));
+ b = new B();
+ Expect.equals("gxyzf", (b.g3)(b.x, b.y, b.z));
+
+ b = new B();
+ Expect.equals("yzxgf", b.g3(b.y, b.z, b.x));
+ b = new B();
+ Expect.equals("gyzxf", (b.g3)(b.y, b.z, b.x));
+ }
+}
+
+class A {
+ A() {}
+ var field;
+ get getter {
+ return field;
+ }
+
+ method() {
+ return field;
+ }
+}
+
+class B {
+ B() : _order = new StringBuffer("") {}
+
+ get g0 {
+ _mark('g');
+ return () {
+ return _mark('f');
+ };
+ }
+
+ get g1 {
+ _mark('g');
+ return (x) {
+ return _mark('f');
+ };
+ }
+
+ get g2 {
+ _mark('g');
+ return (x, y) {
+ return _mark('f');
+ };
+ }
+
+ get g3 {
+ _mark('g');
+ return (x, y, z) {
+ return _mark('f');
+ };
+ }
+
+ get x {
+ _mark('x');
+ return 0;
+ }
+
+ get y {
+ _mark('y');
+ return 1;
+ }
+
+ get z {
+ _mark('z');
+ return 2;
+ }
+
+ _mark(m) {
+ _order.write(m);
+ return _order.toString();
+ }
+
+ StringBuffer _order;
+}
+
+main() {
+ CallThroughGetterTest.testMain();
+}
diff --git a/tests/language/call/through_getter_test.dart b/tests/language/call/through_getter_test.dart
new file mode 100644
index 0000000..2169e8c6
--- /dev/null
+++ b/tests/language/call/through_getter_test.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2011, 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.
+
+import "package:expect/expect.dart";
+
+// Tests that we can call functions through getters.
+
+const TOP_LEVEL_CONST = 1;
+const TOP_LEVEL_CONST_REF = TOP_LEVEL_CONST;
+const TOP_LEVEL_NULL = null;
+
+var topLevel;
+
+class CallThroughGetterTest {
+ static void testMain() {
+ testTopLevel();
+ testField();
+ testGetter();
+ testMethod();
+ testEvaluationOrder();
+ }
+
+ static void testTopLevel() {
+ topLevel = () {
+ return 2;
+ };
+ Expect.equals(1, TOP_LEVEL_CONST);
+ Expect.equals(1, TOP_LEVEL_CONST_REF);
+ Expect.equals(2, topLevel());
+
+ TOP_LEVEL_CONST();
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+ (TOP_LEVEL_CONST)();
+// ^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+ }
+
+ static void testField() {
+ A a = new A();
+ a.field = () => 42;
+ Expect.equals(42, a.field());
+ Expect.equals(42, (a.field)());
+
+ a.field = () => 87;
+ Expect.equals(87, a.field());
+ Expect.equals(87, (a.field)());
+
+ a.field = 99;
+ Expect.throwsNoSuchMethodError(() => a.field());
+ Expect.throwsNoSuchMethodError(() => (a.field)());
+ }
+
+ static void testGetter() {
+ A a = new A();
+ a.field = () => 42;
+ Expect.equals(42, a.getter());
+ Expect.equals(42, (a.getter)());
+
+ a.field = () => 87;
+ Expect.equals(87, a.getter());
+ Expect.equals(87, (a.getter)());
+
+ a.field = 99;
+ Expect.throwsNoSuchMethodError(() => a.getter());
+ Expect.throwsNoSuchMethodError(() => (a.getter)());
+ }
+
+ static void testMethod() {
+ A a = new A();
+ a.field = () => 42;
+ Expect.equals(true, a.method() is Function);
+ Expect.equals(42, a.method()());
+
+ a.field = () => 87;
+ Expect.equals(true, a.method() is Function);
+ Expect.equals(87, a.method()());
+
+ a.field = null;
+ Expect.equals(null, a.method());
+ }
+
+ static void testEvaluationOrder() {
+ B b = new B();
+ Expect.equals("gf", b.g0());
+ b = new B();
+ Expect.equals("gf", (b.g0)());
+
+ b = new B();
+ Expect.equals("xgf", b.g1(b.x));
+ b = new B();
+ Expect.equals("gxf", (b.g1)(b.x));
+
+ b = new B();
+ Expect.equals("xygf", b.g2(b.x, b.y));
+ b = new B();
+ Expect.equals("gxyf", (b.g2)(b.x, b.y));
+
+ b = new B();
+ Expect.equals("xyzgf", b.g3(b.x, b.y, b.z));
+ b = new B();
+ Expect.equals("gxyzf", (b.g3)(b.x, b.y, b.z));
+
+ b = new B();
+ Expect.equals("yzxgf", b.g3(b.y, b.z, b.x));
+ b = new B();
+ Expect.equals("gyzxf", (b.g3)(b.y, b.z, b.x));
+ }
+}
+
+class A {
+ A() {}
+ var field;
+ get getter {
+ return field;
+ }
+
+ method() {
+ return field;
+ }
+}
+
+class B {
+ B() : _order = new StringBuffer("") {}
+
+ get g0 {
+ _mark('g');
+ return () {
+ return _mark('f');
+ };
+ }
+
+ get g1 {
+ _mark('g');
+ return (x) {
+ return _mark('f');
+ };
+ }
+
+ get g2 {
+ _mark('g');
+ return (x, y) {
+ return _mark('f');
+ };
+ }
+
+ get g3 {
+ _mark('g');
+ return (x, y, z) {
+ return _mark('f');
+ };
+ }
+
+ get x {
+ _mark('x');
+ return 0;
+ }
+
+ get y {
+ _mark('y');
+ return 1;
+ }
+
+ get z {
+ _mark('z');
+ return 2;
+ }
+
+ _mark(m) {
+ _order.write(m);
+ return _order.toString();
+ }
+
+ StringBuffer _order;
+}
+
+main() {
+ CallThroughGetterTest.testMain();
+}
diff --git a/tests/language/call/through_null_getter_test.dart b/tests/language/call/through_null_getter_test.dart
new file mode 100644
index 0000000..3076029
--- /dev/null
+++ b/tests/language/call/through_null_getter_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2011, 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.
+
+import "package:expect/expect.dart";
+
+// Tests that we can call functions through getters which return null.
+
+const dynamic TOP_LEVEL_NULL = null;
+
+var topLevel;
+
+class CallThroughNullGetterTest {
+ static void testMain() {
+ testTopLevel();
+ testField();
+ testGetter();
+ testMethod();
+ }
+
+ static void testTopLevel() {
+ topLevel = null;
+ Expect.throwsNoSuchMethodError(() => topLevel());
+ Expect.throwsNoSuchMethodError(() => (topLevel)());
+ Expect.throwsNoSuchMethodError(() => TOP_LEVEL_NULL());
+ Expect.throwsNoSuchMethodError(() => (TOP_LEVEL_NULL)());
+ }
+
+ static void testField() {
+ A a = new A();
+
+ a.field = null;
+ Expect.throwsNoSuchMethodError(() => a.field());
+ Expect.throwsNoSuchMethodError(() => (a.field)());
+ }
+
+ static void testGetter() {
+ A a = new A();
+
+ a.field = null;
+ Expect.throwsNoSuchMethodError(() => a.getter());
+ Expect.throwsNoSuchMethodError(() => (a.getter)());
+ }
+
+ static void testMethod() {
+ A a = new A();
+
+ a.field = null;
+ Expect.throwsNoSuchMethodError(() => a.method()());
+ }
+}
+
+class A {
+ A() {}
+ var field;
+ get getter {
+ return field;
+ }
+
+ method() {
+ return field;
+ }
+}
+
+main() {
+ CallThroughNullGetterTest.testMain();
+}
diff --git a/tests/language/call/type_literal_test.dart b/tests/language/call/type_literal_test.dart
new file mode 100644
index 0000000..9e09bbe
--- /dev/null
+++ b/tests/language/call/type_literal_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2013, 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.
+
+class C {
+ void a() {}
+}
+
+void main() {
+ C().a();
+}
diff --git a/tests/language/call/with_no_such_method_test.dart b/tests/language/call/with_no_such_method_test.dart
new file mode 100644
index 0000000..95c27d5
--- /dev/null
+++ b/tests/language/call/with_no_such_method_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+
+class F {
+ final int value;
+ F(this.value);
+ call() => value;
+ noSuchMethod(Invocation i) {
+ if (i.memberName == #call && i.isMethod) {
+ return i.positionalArguments[0];
+ }
+ return super.noSuchMethod(i);
+ }
+}
+
+main() {
+ F f = new F(42);
+ // Tears off f.call, fails with nSM (wrong number of arguments).
+ Expect.throwsNoSuchMethodError(() => Function.apply(f, ['a', 'b', 'c', 'd']));
+
+ dynamic d = f;
+ var result = d('a', 'b', 'c', 'd'); // calls F.noSuchMethod
+ Expect.equals('a', result);
+
+ // Tears off f.call, call succeeds
+ Expect.equals(42, Function.apply(f, []));
+}
diff --git a/tests/language/nnbd/resolution/issue40931_test.dart b/tests/language/nnbd/resolution/issue40931_test.dart
new file mode 100644
index 0000000..0ea944d
--- /dev/null
+++ b/tests/language/nnbd/resolution/issue40931_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+main() {}
+
+extension E<T> on T? {
+ T foo() => throw 0;
+}
+
+void f(int? a) {
+ a.foo();
+}
diff --git a/tests/language/nnbd/resolution/question_question_lub_test.dart b/tests/language/nnbd/resolution/question_question_lub_test.dart
index 830c848..b050b2a 100644
--- a/tests/language/nnbd/resolution/question_question_lub_test.dart
+++ b/tests/language/nnbd/resolution/question_question_lub_test.dart
@@ -16,13 +16,13 @@
(nullableInt ?? nonNullInt) + 1;
(nullableInt ?? nullableInt) + 1;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer] STATIC_WARNING.USE_OF_NULLABLE_VALUE
// [cfe] unspecified
(nonNullInt ?? nullableInt) + 1;
// ^^^^^^^^^^^
// [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
//^^^^^^^^^^^^^^^^^^^^^^^^^^^
-// [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer] STATIC_WARNING.USE_OF_NULLABLE_VALUE
// [cfe] unspecified
(nonNullInt ?? nonNullInt) + 1;
// ^^^^^^^^^^
diff --git a/tests/language/nnbd/syntax/late_modifier_non_final_field_test.dart b/tests/language/nnbd/syntax/late_modifier_non_final_field_test.dart
index 0447025..bd7e91c 100644
--- a/tests/language/nnbd/syntax/late_modifier_non_final_field_test.dart
+++ b/tests/language/nnbd/syntax/late_modifier_non_final_field_test.dart
@@ -17,6 +17,12 @@
late int fieldWithTrivialInit = 123;
late int? fieldWithNullInit = null;
late int fieldWithNoInit;
+ late int? nullableFieldWithNoInit;
+ late int? fieldWithOnlyCtorInit;
+ late int? fieldWithOnlyBothInitAndCtorInit = 123;
+ A()
+ : fieldWithOnlyCtorInit = null,
+ fieldWithOnlyBothInitAndCtorInit = null;
}
main() {
@@ -29,22 +35,36 @@
Expect.equals(null, a.fieldWithNullInit);
Expect.throws(
() => a.fieldWithNoInit, (error) => error is LateInitializationError);
+ Expect.throws(() => a.nullableFieldWithNoInit,
+ (error) => error is LateInitializationError);
+ Expect.equals(null, a.fieldWithOnlyCtorInit);
+ Expect.equals(null, a.fieldWithOnlyBothInitAndCtorInit);
Expect.equals(1, initCalls);
Expect.equals(123, a.fieldWithInit);
Expect.equals(123, a.fieldWithTrivialInit);
Expect.equals(null, a.fieldWithNullInit);
Expect.throws(
() => a.fieldWithNoInit, (error) => error is LateInitializationError);
+ Expect.throws(() => a.nullableFieldWithNoInit,
+ (error) => error is LateInitializationError);
+ Expect.equals(null, a.fieldWithOnlyCtorInit);
+ Expect.equals(null, a.fieldWithOnlyBothInitAndCtorInit);
Expect.equals(1, initCalls);
a.fieldWithInit = 456;
a.fieldWithTrivialInit = 456;
a.fieldWithNullInit = 456;
a.fieldWithNoInit = 456;
+ a.nullableFieldWithNoInit = null;
+ a.fieldWithOnlyCtorInit = 456;
+ a.fieldWithOnlyBothInitAndCtorInit = 456;
Expect.equals(1, initCalls);
Expect.equals(456, a.fieldWithInit);
Expect.equals(456, a.fieldWithTrivialInit);
Expect.equals(456, a.fieldWithNullInit);
Expect.equals(456, a.fieldWithNoInit);
+ Expect.equals(null, a.nullableFieldWithNoInit);
+ Expect.equals(456, a.fieldWithOnlyCtorInit);
+ Expect.equals(456, a.fieldWithOnlyBothInitAndCtorInit);
Expect.equals(1, initCalls);
initCalls = 0;
diff --git a/tests/language/nnbd/syntax/required_modifier_dynamic_error_test.dart b/tests/language/nnbd/syntax/required_modifier_dynamic_error_test.dart
index 38c7c39..b9dee57 100644
--- a/tests/language/nnbd/syntax/required_modifier_dynamic_error_test.dart
+++ b/tests/language/nnbd/syntax/required_modifier_dynamic_error_test.dart
@@ -15,10 +15,30 @@
}
}
+int baz(
+ {required String a,
+ required String b,
+ required String c,
+ required String d}) {
+ return a.length + b.length + c.length + d.length;
+}
+
main() {
Expect.equals(8, Foo().foo(a: "aa", b: "bb", c: "cc", d: "dd"));
// Test that we throw a NoSuchMethodError, not a TypeError due to c.length.
dynamic f = Foo();
Expect.throwsNoSuchMethodError(() => f.foo(a: "aa", b: "bb", d: "dd"));
+
+ dynamic tearOff = baz;
+ Expect.throwsNoSuchMethodError(() => tearOff(a: "aa", c: "cc", d: "dd"));
+
+ dynamic closure = (
+ {required String a,
+ required String b,
+ required String c,
+ required String d}) {
+ return a.length + b.length + c.length + d.length;
+ };
+ Expect.throwsNoSuchMethodError(() => closure(a: "aa", c: "cc", d: "dd"));
}
diff --git a/tests/language/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart b/tests/language/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart
index 5f67881..058855e 100644
--- a/tests/language/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart
+++ b/tests/language/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart
@@ -7,12 +7,16 @@
void f() {
void g(Object x) {
if (x is String) {
- x.length; //# none: compile-time error
+ x.length; //# 01: ok
}
void h() {
x = 42;
}
+
+ if (x is String) {
+ x.length; //# 02: compile-time error
+ }
}
}
diff --git a/tests/legacy_status_dart2js.csv b/tests/legacy_status_dart2js.csv
index 903bfb6..e7f8343 100644
--- a/tests/legacy_status_dart2js.csv
+++ b/tests/legacy_status_dart2js.csv
@@ -18,9 +18,7 @@
$compiler == dart2js,jsinterop_test/02,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
$compiler == dart2js,jsinterop_test/03,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
$compiler == dart2js,jsinterop_test/04,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
-$compiler == dart2js,jsinterop_test/34,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
$compiler == dart2js,jsinterop_test/35,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
-$compiler == dart2js,jsinterop_test/36,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
$compiler == dart2js,jsinterop_test/37,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
$compiler == dart2js,jsinterop_test/38,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
$compiler == dart2js,jsinterop_test/42,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
@@ -38,9 +36,7 @@
$compiler == dart2js,non_jsinterop_test/02,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
$compiler == dart2js,non_jsinterop_test/03,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
$compiler == dart2js,non_jsinterop_test/04,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
-$compiler == dart2js,non_jsinterop_test/34,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
$compiler == dart2js,non_jsinterop_test/35,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
-$compiler == dart2js,non_jsinterop_test/36,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
$compiler == dart2js,non_jsinterop_test/37,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
$compiler == dart2js,non_jsinterop_test/38,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
$compiler == dart2js,non_jsinterop_test/42,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
diff --git a/tests/lib/mirrors/field_metadata2_test.dart b/tests/lib/mirrors/field_metadata2_test.dart
deleted file mode 100644
index 60e1b6c..0000000
--- a/tests/lib/mirrors/field_metadata2_test.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// compile options: --emit-metadata
-// Copyright (c) 2017, 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.
-
-// Run essentially the same test, but with emit-metadata compile option,
-// which allows us to reflect on the fields.
-import 'dart:mirrors';
-import 'package:expect/expect.dart';
-
-import 'field_metadata_test.dart' as field_metadata_test;
-import 'field_metadata_test.dart' show Foo, Bar;
-
-void main() {
- // Make sure the other test still works.
- field_metadata_test.main();
-
- // Check that we can now reflect on the annotations.
- dynamic f = new Foo();
- var members = reflect(f).type.declarations;
- var x = members[#x] as VariableMirror;
- var bar = x.metadata.first.reflectee as Bar;
- Expect.equals(bar.name, 'bar');
-
- var y = members[#y] as VariableMirror;
- var baz = y.metadata.first.reflectee as Bar;
- Expect.equals(baz.name, 'baz');
-}
diff --git a/tests/lib/mirrors/metadata_constructed_constant_test.dart b/tests/lib/mirrors/metadata_constructed_constant_test.dart
index 16746a0..fc72601 100644
--- a/tests/lib/mirrors/metadata_constructed_constant_test.dart
+++ b/tests/lib/mirrors/metadata_constructed_constant_test.dart
@@ -1,4 +1,3 @@
-// compile options: --emit-metadata
// Copyright (c) 2013, 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.
diff --git a/tests/lib/mirrors/metadata_constructor_arguments_test.dart b/tests/lib/mirrors/metadata_constructor_arguments_test.dart
index bc459e9..361d067 100644
--- a/tests/lib/mirrors/metadata_constructor_arguments_test.dart
+++ b/tests/lib/mirrors/metadata_constructor_arguments_test.dart
@@ -1,4 +1,3 @@
-// compile options: --emit-metadata
// Copyright (c) 2013, 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.
diff --git a/tests/lib/mirrors/metadata_nested_constructor_call_test.dart b/tests/lib/mirrors/metadata_nested_constructor_call_test.dart
index d2edccc..bb26dcf 100644
--- a/tests/lib/mirrors/metadata_nested_constructor_call_test.dart
+++ b/tests/lib/mirrors/metadata_nested_constructor_call_test.dart
@@ -1,4 +1,3 @@
-// compile options: --emit-metadata
// Copyright (c) 2014, 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.
diff --git a/tests/lib_2/html/custom/document_register_basic_test.dart b/tests/lib_2/html/custom/document_register_basic_test.dart
index c295b7f7..6bec727 100644
--- a/tests/lib_2/html/custom/document_register_basic_test.dart
+++ b/tests/lib_2/html/custom/document_register_basic_test.dart
@@ -7,7 +7,6 @@
import 'dart:html';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'utils.dart';
@@ -42,8 +41,6 @@
}
main() {
- useHtmlConfiguration();
-
// Adapted from Blink's fast/dom/custom/document-register-basic test.
setUp(() => customElementsReady);
diff --git a/tests/lib_2/html/custom/document_register_type_extensions_test.dart b/tests/lib_2/html/custom/document_register_type_extensions_test.dart
index 2e652c4..964d80d 100644
--- a/tests/lib_2/html/custom/document_register_type_extensions_test.dart
+++ b/tests/lib_2/html/custom/document_register_type_extensions_test.dart
@@ -4,7 +4,6 @@
import 'dart:html';
-import 'package:unittest/html_individual_config.dart';
import 'package:unittest/unittest.dart';
import 'utils.dart';
@@ -78,8 +77,6 @@
}
main() {
- useHtmlIndividualConfiguration();
-
// Adapted from Blink's fast/dom/custom/document-register-type-extension test.
var testForm = new FormElement()..id = 'testForm';
diff --git a/tests/lib_2/html/custom/element_upgrade_failure_test.dart b/tests/lib_2/html/custom/element_upgrade_failure_test.dart
index 16bb949..a255162 100644
--- a/tests/lib_2/html/custom/element_upgrade_failure_test.dart
+++ b/tests/lib_2/html/custom/element_upgrade_failure_test.dart
@@ -6,7 +6,6 @@
import 'dart:html';
import 'dart:js' as js;
-import 'package:unittest/html_individual_config.dart';
import 'package:unittest/unittest.dart';
import 'utils.dart';
diff --git a/tests/lib_2/html/custom/element_upgrade_test.dart b/tests/lib_2/html/custom/element_upgrade_test.dart
index 15a9f85..135cf3d 100644
--- a/tests/lib_2/html/custom/element_upgrade_test.dart
+++ b/tests/lib_2/html/custom/element_upgrade_test.dart
@@ -6,7 +6,6 @@
import 'dart:html';
import 'dart:js' as js;
-import 'package:unittest/html_individual_config.dart';
import 'package:unittest/unittest.dart';
import 'utils.dart';
diff --git a/tests/lib_2/html/element_test.dart b/tests/lib_2/html/element_test.dart
index b6eeb2b..e6e3e9a 100644
--- a/tests/lib_2/html/element_test.dart
+++ b/tests/lib_2/html/element_test.dart
@@ -5,7 +5,6 @@
library ElementTest;
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'package:unittest/src/expected_function.dart' show ExpectedFunction;
import 'dart:async';
import 'dart:html';
@@ -32,8 +31,6 @@
}
main() {
- useHtmlIndividualConfiguration();
-
var isHRElement = predicate((x) => x is HRElement, 'is a HRElement');
var isBRElement = predicate((x) => x is BRElement, 'is a BRElement');
var isInputElement =
diff --git a/tests/lib_2/html/fileapi_supported_test.dart b/tests/lib_2/html/fileapi_supported_test.dart
index 45cf32d..0de1f85 100644
--- a/tests/lib_2/html/fileapi_supported_test.dart
+++ b/tests/lib_2/html/fileapi_supported_test.dart
@@ -5,7 +5,6 @@
import 'package:async_helper/async_helper.dart';
import 'package:async_helper/async_minitest.dart';
-import 'package:expect/minitest.dart' as minitest;
Future<FileSystem> _fileSystem;
@@ -30,8 +29,8 @@
});
test('requestFileSystem', () async {
- var expectation = FileSystem.supported ? minitest.returnsNormally : throws;
- minitest.expect(() async {
+ var expectation = FileSystem.supported ? returnsNormally : throws;
+ expect(() async {
var fs = await fileSystem;
expect(fs.root != null, true);
}, expectation);
diff --git a/tests/lib_2/html/fileapi_supported_throws_test.dart b/tests/lib_2/html/fileapi_supported_throws_test.dart
index e6c2d7e..892ba50 100644
--- a/tests/lib_2/html/fileapi_supported_throws_test.dart
+++ b/tests/lib_2/html/fileapi_supported_throws_test.dart
@@ -5,12 +5,11 @@
import 'package:async_helper/async_helper.dart';
import 'package:async_helper/async_minitest.dart';
-import 'package:expect/minitest.dart' as minitest;
main() {
test('requestFileSystem', () async {
- var expectation = FileSystem.supported ? minitest.returnsNormally : throws;
- minitest.expect(() async {
+ var expectation = FileSystem.supported ? returnsNormally : throws;
+ expect(() async {
await window.requestFileSystem(100);
}, expectation);
});
diff --git a/tests/lib_2/html/history_history_test.dart b/tests/lib_2/html/history_history_test.dart
deleted file mode 100644
index e60f97c..0000000
--- a/tests/lib_2/html/history_history_test.dart
+++ /dev/null
@@ -1,81 +0,0 @@
-library HistoryTest;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
-import 'dart:html';
-import 'dart:async';
-
-main() {
- useHtmlIndividualConfiguration();
-
- var expectation = History.supportsState ? returnsNormally : throws;
-
- test('pushState', () {
- expect(() {
- window.history.pushState(null, document.title, '?dummy');
- var length = window.history.length;
-
- window.history.pushState(null, document.title, '?foo=bar');
-
- expect(window.location.href.endsWith('foo=bar'), isTrue);
- }, expectation);
- });
-
- test('pushState with data', () {
- expect(() {
- window.history.pushState({'one': 1}, document.title, '?dummy');
- expect(window.history.state, equals({'one': 1}));
- window.history.pushState(null, document.title, '?foo=bar');
-
- expect(window.location.href.endsWith('foo=bar'), isTrue);
- }, expectation);
- });
-
- test('back', () {
- expect(() {
- window.history.pushState(null, document.title, '?dummy1');
- window.history.pushState(null, document.title, '?dummy2');
- var length = window.history.length;
-
- expect(window.location.href.endsWith('dummy2'), isTrue);
-
- // Need to wait a frame or two to let the pushState events occur.
- new Timer(const Duration(milliseconds: 100), expectAsync(() {
- window.onPopState.first.then(expectAsync((_) {
- expect(window.history.length, length);
- expect(window.location.href.endsWith('dummy1'), isTrue);
- }));
-
- window.history.back();
- }));
- }, expectation);
- });
-
- test('replaceState', () {
- expect(() {
- var length = window.history.length;
-
- window.history.replaceState(null, document.title, '?foo=baz');
- expect(window.history.length, length);
- expect(window.location.href.endsWith('foo=baz'), isTrue);
- }, expectation);
- });
-
- test('popstatevent', () {
- expect(() {
- var event = new Event.eventType('PopStateEvent', 'popstate');
- expect(event is PopStateEvent, true);
- }, expectation);
- });
-
- test('hashchangeevent', () {
- var expectation = HashChangeEvent.supported ? returnsNormally : throws;
- expect(() {
- var event = new HashChangeEvent('change', oldUrl: 'old', newUrl: 'new');
- expect(event is HashChangeEvent, true);
- expect(event.oldUrl, 'old');
- expect(event.newUrl, 'new');
- }, expectation);
- });
-}
-
diff --git a/tests/lib_2/html/history_supported_test.dart b/tests/lib_2/html/history_supported_test.dart
new file mode 100644
index 0000000..1795e35
--- /dev/null
+++ b/tests/lib_2/html/history_supported_test.dart
@@ -0,0 +1,15 @@
+library HistoryTest;
+
+import 'package:unittest/unittest.dart';
+import 'dart:html';
+import 'dart:async';
+
+main() {
+ test('supports_state', () {
+ expect(History.supportsState, true);
+ });
+
+ test('supported_HashChangeEvent', () {
+ expect(HashChangeEvent.supported, true);
+ });
+}
diff --git a/tests/lib_2/html/history_supports_tests.dart b/tests/lib_2/html/history_supports_tests.dart
deleted file mode 100644
index 0459fae..0000000
--- a/tests/lib_2/html/history_supports_tests.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-library HistoryTest;
-
-import 'package:unittest/unittest.dart';
-import 'dart:html';
-import 'dart:async';
-
-main() {
- test('supportsState', () {
- expect(History.supportsState, true);
- });
-}
-
diff --git a/tests/lib_2/html/history_test.dart b/tests/lib_2/html/history_test.dart
index 907fa7c..064c583 100644
--- a/tests/lib_2/html/history_test.dart
+++ b/tests/lib_2/html/history_test.dart
@@ -1,94 +1,77 @@
library HistoryTest;
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:async';
main() {
- useHtmlIndividualConfiguration();
-
- group('supported_state', () {
- test('supportsState', () {
- expect(History.supportsState, true);
- });
- });
-
- group('supported_HashChangeEvent', () {
- test('supported', () {
- expect(HashChangeEvent.supported, true);
- });
- });
-
var expectation = History.supportsState ? returnsNormally : throws;
- group('history', () {
- test('pushState', () {
- expect(() {
- window.history.pushState(null, document.title, '?dummy');
- var length = window.history.length;
+ test('pushState', () {
+ expect(() {
+ window.history.pushState(null, document.title, '?dummy');
+ var length = window.history.length;
- window.history.pushState(null, document.title, '?foo=bar');
+ window.history.pushState(null, document.title, '?foo=bar');
- expect(window.location.href.endsWith('foo=bar'), isTrue);
- }, expectation);
- });
+ expect(window.location.href.endsWith('foo=bar'), isTrue);
+ }, expectation);
+ });
- test('pushState with data', () {
- expect(() {
- window.history.pushState({'one': 1}, document.title, '?dummy');
- expect(window.history.state, equals({'one': 1}));
- window.history.pushState(null, document.title, '?foo=bar');
+ test('pushState with data', () {
+ expect(() {
+ window.history.pushState({'one': 1}, document.title, '?dummy');
+ expect(window.history.state, equals({'one': 1}));
+ window.history.pushState(null, document.title, '?foo=bar');
- expect(window.location.href.endsWith('foo=bar'), isTrue);
- }, expectation);
- });
+ expect(window.location.href.endsWith('foo=bar'), isTrue);
+ }, expectation);
+ });
- test('back', () {
- expect(() {
- window.history.pushState(null, document.title, '?dummy1');
- window.history.pushState(null, document.title, '?dummy2');
- var length = window.history.length;
+ test('back', () {
+ expect(() {
+ window.history.pushState(null, document.title, '?dummy1');
+ window.history.pushState(null, document.title, '?dummy2');
+ var length = window.history.length;
- expect(window.location.href.endsWith('dummy2'), isTrue);
+ expect(window.location.href.endsWith('dummy2'), isTrue);
- // Need to wait a frame or two to let the pushState events occur.
- new Timer(const Duration(milliseconds: 100), expectAsync(() {
- window.onPopState.first.then(expectAsync((_) {
- expect(window.history.length, length);
- expect(window.location.href.endsWith('dummy1'), isTrue);
- }));
-
- window.history.back();
+ // Need to wait a frame or two to let the pushState events occur.
+ new Timer(const Duration(milliseconds: 100), expectAsync(() {
+ window.onPopState.first.then(expectAsync((_) {
+ expect(window.history.length, length);
+ expect(window.location.href.endsWith('dummy1'), isTrue);
}));
- }, expectation);
- });
- test('replaceState', () {
- expect(() {
- var length = window.history.length;
+ window.history.back();
+ }));
+ }, expectation);
+ });
- window.history.replaceState(null, document.title, '?foo=baz');
- expect(window.history.length, length);
- expect(window.location.href.endsWith('foo=baz'), isTrue);
- }, expectation);
- });
+ test('replaceState', () {
+ expect(() {
+ var length = window.history.length;
- test('popstatevent', () {
- expect(() {
- var event = new Event.eventType('PopStateEvent', 'popstate');
- expect(event is PopStateEvent, true);
- }, expectation);
- });
+ window.history.replaceState(null, document.title, '?foo=baz');
+ expect(window.history.length, length);
+ expect(window.location.href.endsWith('foo=baz'), isTrue);
+ }, expectation);
+ });
- test('hashchangeevent', () {
- var expectation = HashChangeEvent.supported ? returnsNormally : throws;
- expect(() {
- var event = new HashChangeEvent('change', oldUrl: 'old', newUrl: 'new');
- expect(event is HashChangeEvent, true);
- expect(event.oldUrl, 'old');
- expect(event.newUrl, 'new');
- }, expectation);
- });
+ test('popstatevent', () {
+ expect(() {
+ var event = new Event.eventType('PopStateEvent', 'popstate');
+ expect(event is PopStateEvent, true);
+ }, expectation);
+ });
+
+ test('hashchangeevent', () {
+ var expectation = HashChangeEvent.supported ? returnsNormally : throws;
+ expect(() {
+ var event = new HashChangeEvent('change', oldUrl: 'old', newUrl: 'new');
+ expect(event is HashChangeEvent, true);
+ expect(event.oldUrl, 'old');
+ expect(event.newUrl, 'new');
+ }, expectation);
});
}
diff --git a/tests/lib_2/html/indexeddb_1_test.dart b/tests/lib_2/html/indexeddb_1_test.dart
index 419b1c5..513c028 100644
--- a/tests/lib_2/html/indexeddb_1_test.dart
+++ b/tests/lib_2/html/indexeddb_1_test.dart
@@ -1,7 +1,6 @@
library IndexedDB1Test;
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dart:math' as math;
@@ -154,8 +153,6 @@
}
main() {
- useHtmlIndividualConfiguration();
-
// Test that indexed_db is properly flagged as supported or not.
// Note that the rest of the indexed_db tests assume that this has been
// checked.
diff --git a/tests/lib_2/html/interactive_geolocation_test.dart b/tests/lib_2/html/interactive_geolocation_test.dart
index 9f0d6d7..11d34c3 100644
--- a/tests/lib_2/html/interactive_geolocation_test.dart
+++ b/tests/lib_2/html/interactive_geolocation_test.dart
@@ -7,12 +7,9 @@
import 'dart:async';
import 'dart:html';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'utils.dart';
main() {
- useHtmlIndividualConfiguration();
-
test('getCurrentPosition', () {
return window.navigator.geolocation.getCurrentPosition().then((position) {
expect(position.coords.latitude, isNotNull);
diff --git a/tests/lib_2/html/js_function_getter_trust_types/compile_test.dart b/tests/lib_2/html/js_function_getter_trust_types/compile_test.dart
new file mode 100644
index 0000000..9cbbe1f
--- /dev/null
+++ b/tests/lib_2/html/js_function_getter_trust_types/compile_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2020, 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.
+
+// SharedOptions=--trust-type-annotations
+@JS()
+library js_function_getter_trust_types_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+import 'js_function_util.dart';
+
+main() {
+ injectJs();
+
+ foo.bar.nonFunctionStatic();
+// ^
+// [cfe] Error: 'nonFunctionStatic' isn't a function or method and can't be invoked.
+//^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+
+ foo.bar.nonFunctionStatic(0);
+// ^
+// [cfe] Error: 'nonFunctionStatic' isn't a function or method and can't be invoked.
+//^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+
+ foo.bar.nonFunctionStatic(0, 0);
+// ^
+// [cfe] Error: 'nonFunctionStatic' isn't a function or method and can't be invoked.
+//^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+
+ foo.bar.nonFunctionStatic(0, 0, 0, 0, 0, 0);
+// ^
+// [cfe] Error: 'nonFunctionStatic' isn't a function or method and can't be invoked.
+//^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+
+ foo.bar.add(4);
+ // ^
+ // [cfe] Error: Too few positional arguments: 2 required, 1 given.
+ // ^^^
+ // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+
+ foo.bar.add(4, 5, 10);
+ // ^
+ // [cfe] Error: Too many positional arguments: 2 allowed, but 3 found.
+ // ^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+}
diff --git a/tests/lib_2/html/js_function_getter_trust_types/function_test.dart b/tests/lib_2/html/js_function_getter_trust_types/function_test.dart
new file mode 100644
index 0000000..5a49f47
--- /dev/null
+++ b/tests/lib_2/html/js_function_getter_trust_types/function_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, 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.
+
+// SharedOptions=--trust-type-annotations
+@JS()
+library js_function_getter_trust_types_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+import 'js_function_util.dart';
+
+main() {
+ injectJs();
+
+ Expect.equals(foo.bar.add(4, 5), 9);
+}
diff --git a/tests/lib_2/html/js_function_getter_trust_types/js_function_util.dart b/tests/lib_2/html/js_function_getter_trust_types/js_function_util.dart
new file mode 100644
index 0000000..b6afd8f
--- /dev/null
+++ b/tests/lib_2/html/js_function_getter_trust_types/js_function_util.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2015, 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.
+
+// SharedOptions=--trust-type-annotations
+@JS()
+library js_function_getter_trust_types_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+
+injectJs() {
+ document.body.append(new ScriptElement()
+ ..type = 'text/javascript'
+ ..innerHtml = r"""
+ var bar = { };
+
+ bar.nonFunctionStatic = function() {
+ return arguments.length * 2;
+ };
+
+ bar.add = function(a, b) {
+ return a + b;
+ };
+
+ var foo = { 'bar' : bar };
+""");
+}
+
+typedef int AddFn(int x, int y);
+
+@JS()
+class NotAFn {}
+
+@JS()
+abstract class Bar {
+ external AddFn get add;
+ external NotAFn get nonFunctionStatic;
+}
+
+@JS()
+abstract class Foo {
+ external Bar get bar;
+}
+
+@JS()
+external Foo get foo;
diff --git a/tests/lib_2/html/js_function_getter_trust_types_test.dart b/tests/lib_2/html/js_function_getter_trust_types_test.dart
deleted file mode 100644
index c91d6b3..0000000
--- a/tests/lib_2/html/js_function_getter_trust_types_test.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2015, 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.
-
-// SharedOptions=--trust-type-annotations
-@JS()
-library js_function_getter_trust_types_test;
-
-import 'dart:html';
-
-import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import 'package:unittest/html_individual_config.dart';
-
-_injectJs() {
- document.body.append(new ScriptElement()
- ..type = 'text/javascript'
- ..innerHtml = r"""
- var bar = { };
-
- bar.nonFunctionStatic = function() {
- return arguments.length * 2;
- };
-
- bar.add = function(a, b) {
- return a + b;
- };
-
- var foo = { 'bar' : bar };
-""");
-}
-
-typedef int AddFn(int x, int y);
-
-@JS()
-class NotAFn {}
-
-@JS()
-abstract class Bar {
- external AddFn get add;
- external NotAFn get nonFunctionStatic;
-}
-
-@JS()
-abstract class Foo {
- external Bar get bar;
-}
-
-@JS()
-external Foo get foo;
-
-main() {
- _injectJs();
-
- useHtmlIndividualConfiguration();
-
- test('static nonFunctionStatic', () {
- expect(() => foo.bar.nonFunctionStatic(), throws);
- expect(() => foo.bar.nonFunctionStatic(0), throws);
- expect(() => foo.bar.nonFunctionStatic(0, 0), throws);
- expect(() => foo.bar.nonFunctionStatic(0, 0, 0, 0, 0, 0), throws);
- });
-
- test('typedef function', () {
- expect(() => foo.bar.add(4), throws);
- expect(() => foo.bar.add(4, 5, 10), throws);
- expect(foo.bar.add(4, 5), equals(9));
- });
-}
diff --git a/tests/lib_2/html/js_interop_constructor_name_div_test.dart b/tests/lib_2/html/js_interop_constructor_name/div_test.dart
similarity index 90%
rename from tests/lib_2/html/js_interop_constructor_name_div_test.dart
rename to tests/lib_2/html/js_interop_constructor_name/div_test.dart
index 869ff73..f24cfe6 100644
--- a/tests/lib_2/html/js_interop_constructor_name_div_test.dart
+++ b/tests/lib_2/html/js_interop_constructor_name/div_test.dart
@@ -10,7 +10,6 @@
import 'package:js/js.dart';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
@JS()
@@ -26,8 +25,6 @@
confuse(x) => x;
main() {
- useHtmlIndividualConfiguration();
-
test('dom-is-dom', () {
var e = confuse(new html.DivElement());
expect(e is html.DivElement, isTrue);
diff --git a/tests/lib_2/html/js_interop_constructor_name_test.html b/tests/lib_2/html/js_interop_constructor_name/div_test.html
similarity index 73%
rename from tests/lib_2/html/js_interop_constructor_name_test.html
rename to tests/lib_2/html/js_interop_constructor_name/div_test.html
index 04399e4..31aad5e 100644
--- a/tests/lib_2/html/js_interop_constructor_name_test.html
+++ b/tests/lib_2/html/js_interop_constructor_name/div_test.html
@@ -3,7 +3,7 @@
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="dart.unittest" content="full-stack-traces">
- <title> js_interop_constructor_name_test </title>
+ <title> div_test </title>
<style>
.unittest-table { font-family:monospace; border:1px; }
.unittest-pass { background: #6b3;}
@@ -12,9 +12,9 @@
</style>
</head>
<body>
- <h1> Running js_interop_constructor_name_test </h1>
+ <h1> Running div_test </h1>
<script type="text/javascript"
- src="/root_dart/tests/html/js_interop_constructor_name_test_js.js"></script>
+ src="/root_dart/tests/lib_2/html/js_interop_constructor_name/test_js.js"></script>
<script type="text/javascript"
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
%TEST_SCRIPTS%
diff --git a/tests/lib_2/html/js_interop_constructor_name_error1_test.dart b/tests/lib_2/html/js_interop_constructor_name/error1_test.dart
similarity index 90%
rename from tests/lib_2/html/js_interop_constructor_name_error1_test.dart
rename to tests/lib_2/html/js_interop_constructor_name/error1_test.dart
index 9057129..06323e7 100644
--- a/tests/lib_2/html/js_interop_constructor_name_error1_test.dart
+++ b/tests/lib_2/html/js_interop_constructor_name/error1_test.dart
@@ -10,7 +10,6 @@
import 'package:js/js.dart';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
@JS()
@@ -26,8 +25,6 @@
confuse(x) => x;
main() {
- useHtmlIndividualConfiguration();
-
test('dom-is-js', () {
var e = confuse(new html.DivElement());
// Currently, HTML types are not [JavaScriptObject]s. We could change that
diff --git a/tests/lib_2/html/js_interop_constructor_name_test.html b/tests/lib_2/html/js_interop_constructor_name/error1_test.html
similarity index 73%
copy from tests/lib_2/html/js_interop_constructor_name_test.html
copy to tests/lib_2/html/js_interop_constructor_name/error1_test.html
index 04399e4..9c6566e 100644
--- a/tests/lib_2/html/js_interop_constructor_name_test.html
+++ b/tests/lib_2/html/js_interop_constructor_name/error1_test.html
@@ -3,7 +3,7 @@
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="dart.unittest" content="full-stack-traces">
- <title> js_interop_constructor_name_test </title>
+ <title> error1_test </title>
<style>
.unittest-table { font-family:monospace; border:1px; }
.unittest-pass { background: #6b3;}
@@ -12,9 +12,9 @@
</style>
</head>
<body>
- <h1> Running js_interop_constructor_name_test </h1>
+ <h1> Running error1_test </h1>
<script type="text/javascript"
- src="/root_dart/tests/html/js_interop_constructor_name_test_js.js"></script>
+ src="/root_dart/tests/lib_2/html/js_interop_constructor_name/test_js.js"></script>
<script type="text/javascript"
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
%TEST_SCRIPTS%
diff --git a/tests/lib_2/html/js_interop_constructor_name_error2_test.dart b/tests/lib_2/html/js_interop_constructor_name/error2_test.dart
similarity index 90%
rename from tests/lib_2/html/js_interop_constructor_name_error2_test.dart
rename to tests/lib_2/html/js_interop_constructor_name/error2_test.dart
index 6340f63..44c2226 100644
--- a/tests/lib_2/html/js_interop_constructor_name_error2_test.dart
+++ b/tests/lib_2/html/js_interop_constructor_name/error2_test.dart
@@ -10,7 +10,6 @@
import 'package:js/js.dart';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
@JS()
@@ -26,8 +25,6 @@
confuse(x) => x;
main() {
- useHtmlIndividualConfiguration();
-
test('String-is-not-js', () {
var e = confuse('kombucha');
// A String should not be a JS interop type. The type test flags are added
diff --git a/tests/lib_2/html/js_interop_constructor_name_test.html b/tests/lib_2/html/js_interop_constructor_name/error2_test.html
similarity index 73%
copy from tests/lib_2/html/js_interop_constructor_name_test.html
copy to tests/lib_2/html/js_interop_constructor_name/error2_test.html
index 04399e4..7e1b64f 100644
--- a/tests/lib_2/html/js_interop_constructor_name_test.html
+++ b/tests/lib_2/html/js_interop_constructor_name/error2_test.html
@@ -3,7 +3,7 @@
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="dart.unittest" content="full-stack-traces">
- <title> js_interop_constructor_name_test </title>
+ <title> error2_test </title>
<style>
.unittest-table { font-family:monospace; border:1px; }
.unittest-pass { background: #6b3;}
@@ -12,9 +12,9 @@
</style>
</head>
<body>
- <h1> Running js_interop_constructor_name_test </h1>
+ <h1> Running error2_test </h1>
<script type="text/javascript"
- src="/root_dart/tests/html/js_interop_constructor_name_test_js.js"></script>
+ src="/root_dart/tests/lib_2/html/js_interop_constructor_name/test_js.js"></script>
<script type="text/javascript"
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
%TEST_SCRIPTS%
diff --git a/tests/lib_2/html/js_interop_constructor_name_method_test.dart b/tests/lib_2/html/js_interop_constructor_name/method_test.dart
similarity index 91%
rename from tests/lib_2/html/js_interop_constructor_name_method_test.dart
rename to tests/lib_2/html/js_interop_constructor_name/method_test.dart
index f96895a..4de6adf 100644
--- a/tests/lib_2/html/js_interop_constructor_name_method_test.dart
+++ b/tests/lib_2/html/js_interop_constructor_name/method_test.dart
@@ -10,7 +10,6 @@
import 'package:js/js.dart';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
@JS()
@@ -26,8 +25,6 @@
confuse(x) => x;
main() {
- useHtmlIndividualConfiguration();
-
test('js-call-js-method', () {
var e = confuse(makeDiv('hello'));
expect(e.bar(), equals('hello'));
diff --git a/tests/lib_2/html/js_interop_constructor_name_test.html b/tests/lib_2/html/js_interop_constructor_name/method_test.html
similarity index 73%
copy from tests/lib_2/html/js_interop_constructor_name_test.html
copy to tests/lib_2/html/js_interop_constructor_name/method_test.html
index 04399e4..c38d07dd 100644
--- a/tests/lib_2/html/js_interop_constructor_name_test.html
+++ b/tests/lib_2/html/js_interop_constructor_name/method_test.html
@@ -3,7 +3,7 @@
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="dart.unittest" content="full-stack-traces">
- <title> js_interop_constructor_name_test </title>
+ <title> method_test </title>
<style>
.unittest-table { font-family:monospace; border:1px; }
.unittest-pass { background: #6b3;}
@@ -12,9 +12,9 @@
</style>
</head>
<body>
- <h1> Running js_interop_constructor_name_test </h1>
+ <h1> Running method_test </h1>
<script type="text/javascript"
- src="/root_dart/tests/html/js_interop_constructor_name_test_js.js"></script>
+ src="/root_dart/tests/lib_2/html/js_interop_constructor_name/test_js.js"></script>
<script type="text/javascript"
src="/root_dart/pkg/test_runner/lib/src/test_controller.js"></script>
%TEST_SCRIPTS%
diff --git a/tests/lib_2/html/js_interop_constructor_name/test_js.js b/tests/lib_2/html/js_interop_constructor_name/test_js.js
new file mode 100644
index 0000000..828cbc9
--- /dev/null
+++ b/tests/lib_2/html/js_interop_constructor_name/test_js.js
@@ -0,0 +1,20 @@
+(function() {
+
+ // A constructor function with the same name as a HTML element.
+ function HTMLDivElement(a) {
+ this.a = a;
+ }
+
+ HTMLDivElement.prototype.bar = function() {
+ return this.a;
+ }
+
+ HTMLDivElement.prototype.toString = function() {
+ return "HTMLDivElement(" + this.a + ")";
+ }
+
+ self.makeDiv = function(text) {
+ return new HTMLDivElement(text);
+ };
+
+})();
diff --git a/tests/lib_2/html/websocket_test.dart b/tests/lib_2/html/websocket_test.dart
index 4495850..2157e74 100644
--- a/tests/lib_2/html/websocket_test.dart
+++ b/tests/lib_2/html/websocket_test.dart
@@ -3,7 +3,6 @@
import 'dart:html';
import 'package:async_helper/async_minitest.dart';
-import 'package:expect/minitest.dart' as minitest;
main() {
group('supported', () {
@@ -13,15 +12,13 @@
});
group('websocket', () {
- var isWebSocket =
- minitest.predicate((x) => x is WebSocket, 'is a WebSocket');
- var expectation = WebSocket.supported ? minitest.returnsNormally : throws;
+ var expectation = WebSocket.supported ? returnsNormally : throws;
test('constructorTest', () {
- minitest.expect(() {
+ expect(() {
var socket = new WebSocket('ws://localhost/ws', 'chat');
expect(socket, isNotNull);
- minitest.expect(socket, isWebSocket);
+ expect(socket, isInstanceOf<WebSocket>());
}, expectation);
});
diff --git a/tests/lib_2/html/worker_functional_test.dart b/tests/lib_2/html/worker_functional_test.dart
new file mode 100644
index 0000000..497f808
--- /dev/null
+++ b/tests/lib_2/html/worker_functional_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, 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.
+
+library worker_test;
+
+import 'package:unittest/unittest.dart';
+import 'dart:html';
+
+main() {
+ var workerScript = '''postMessage('WorkerMessage');''';
+
+ test('unsupported', () {
+ if (!Worker.supported) {
+ expect(() => new Worker('worker.js'), throws);
+ } else {
+ new Worker('worker.js').onError.first.then(expectAsync((e) {
+ // This event is expected, "worker.js" doesn't exist. But the event
+ // *sometimes* propagates to window.onerror in Firefox which causes
+ // this test to fail, so let's stop any further propagation:
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ }));
+ }
+ });
+
+ if (!Worker.supported) return;
+
+ test('works', () {
+ // Use Blob to make a local URL so we don't have to have a separate file.
+ // This does not work on browsers using CSP (Content Security Policy).
+ var blob = new Blob([workerScript], 'text/javascript');
+ var url = Url.createObjectUrl(blob);
+ var worker = new Worker(url);
+ var test = expectAsync((e) {
+ expect(e.data, 'WorkerMessage');
+ });
+ worker.onMessage.first.then(test);
+ });
+}
diff --git a/tests/lib_2/html/worker_supported_test.dart b/tests/lib_2/html/worker_supported_test.dart
new file mode 100644
index 0000000..2196c02
--- /dev/null
+++ b/tests/lib_2/html/worker_supported_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, 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.
+
+library worker_test;
+
+import 'package:unittest/unittest.dart';
+import 'dart:html';
+
+main() {
+ test('supported', () {
+ expect(Worker.supported, isTrue);
+ });
+}
diff --git a/tests/lib_2/html/worker_test.dart b/tests/lib_2/html/worker_test.dart
deleted file mode 100644
index dc21b3b..0000000
--- a/tests/lib_2/html/worker_test.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2013, 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.
-
-library worker_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
-import 'dart:html';
-
-main() {
- useHtmlIndividualConfiguration();
-
- group('supported', () {
- test('supported', () {
- expect(Worker.supported, isTrue);
- });
- });
-
- var workerScript = '''postMessage('WorkerMessage');''';
-
- group('functional', () {
- test('unsupported', () {
- if (!Worker.supported) {
- expect(() => new Worker('worker.js'), throws);
- } else {
- new Worker('worker.js').onError.first.then(expectAsync((e) {
- // This event is expected, "worker.js" doesn't exist. But the event
- // *sometimes* propagates to window.onerror in Firefox which causes
- // this test to fail, so let's stop any further propagation:
- e.preventDefault();
- e.stopImmediatePropagation();
- }));
- }
- });
-
- if (!Worker.supported) {
- return;
- }
-
- test('works', () {
- // Use Blob to make a local URL so we don't have to have a separate file.
- // This does not work on browsers using CSP (Content Security Policy).
- var blob = new Blob([workerScript], 'text/javascript');
- var url = Url.createObjectUrl(blob);
- var worker = new Worker(url);
- var test = expectAsync((e) {
- expect(e.data, 'WorkerMessage');
- });
- worker.onMessage.first.then(test);
- });
- });
-}
diff --git a/tests/lib_2/isolate/scenarios/bad_resolve_package/bad_resolve_package_test.dart b/tests/lib_2/isolate/scenarios/bad_resolve_package/bad_resolve_package_test.dart
index d0be07e..5866729 100644
--- a/tests/lib_2/isolate/scenarios/bad_resolve_package/bad_resolve_package_test.dart
+++ b/tests/lib_2/isolate/scenarios/bad_resolve_package/bad_resolve_package_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
import 'dart:io';
import 'dart:isolate';
diff --git a/tests/lib_2/isolate/scenarios/package_relative_root/package_relative_root_test.dart b/tests/lib_2/isolate/scenarios/package_relative_root/package_relative_root_test.dart
index 3e28d99..034881b 100644
--- a/tests/lib_2/isolate/scenarios/package_relative_root/package_relative_root_test.dart
+++ b/tests/lib_2/isolate/scenarios/package_relative_root/package_relative_root_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
import 'dart:io';
import 'dart:isolate';
diff --git a/tests/lib_2/isolate/scenarios/package_relative_spec/package_relative_spec_test.dart b/tests/lib_2/isolate/scenarios/package_relative_spec/package_relative_spec_test.dart
index 22c65cca..9e5b603 100644
--- a/tests/lib_2/isolate/scenarios/package_relative_spec/package_relative_spec_test.dart
+++ b/tests/lib_2/isolate/scenarios/package_relative_spec/package_relative_spec_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
import 'dart:io';
import 'dart:isolate';
diff --git a/tests/lib_2/isolate/scenarios/short_package/short_package_test.dart b/tests/lib_2/isolate/scenarios/short_package/short_package_test.dart
index 88e98be..16ec032 100644
--- a/tests/lib_2/isolate/scenarios/short_package/short_package_test.dart
+++ b/tests/lib_2/isolate/scenarios/short_package/short_package_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
import 'dart:io';
import 'dart:isolate';
diff --git a/tests/lib_2/lib_2_analyzer.status b/tests/lib_2/lib_2_analyzer.status
deleted file mode 100644
index 113c571..0000000
--- a/tests/lib_2/lib_2_analyzer.status
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) 2017, 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.
-
-[ $compiler == dart2analyzer ]
-html/js_function_getter_trust_types_test: Skip # dart2js specific flags.
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 4752dc0..14a0a1a 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -55,7 +55,7 @@
html/file_sample_test: Skip # FileSystem not supported on FireFox.
html/fileapi_supported_test: Skip # FileSystem not supported on FireFox.
html/fileapi_supported_throws_test: Skip # FileSystem not supported on FireFox.
-html/history_test/history: Skip # Issue 22050
+html/history_test: Skip # Issue 22050
html/request_animation_frame_test: Skip # Async test hangs.
[ $compiler == dart2js && $runtime == safari ]
@@ -69,14 +69,14 @@
[ $compiler == dart2js && $checked ]
convert/utf85_test: Slow, Pass # Issue 12029.
-html/js_function_getter_trust_types_test: Skip # --trust-type-annotations incompatible with --checked
+html/js_function_getter_trust_types/function_test: Skip # --trust-type-annotations incompatible with --checked
[ $compiler == dart2js && $csp && ($runtime == chrome || $runtime == chromeOnAndroid || $runtime == ff || $runtime == safari) ]
html/event_customevent_test: SkipByDesign
html/js_array_test: SkipByDesign
html/js_dart_to_string_test: SkipByDesign
html/js_function_getter_test: SkipByDesign
-html/js_function_getter_trust_types_test: SkipByDesign
+html/js_function_getter_trust_types/function_test: SkipByDesign
html/js_interop_1_test: SkipByDesign
html/js_typed_interop_bind_this_test: SkipByDesign
html/js_typed_interop_callable_object_test: SkipByDesign
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index c203c9a..5e435c6 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -29,14 +29,7 @@
html/custom/created_callback_test: Skip # Issue 31577
html/custom/document_register_basic_test: Skip # Issue 31577
html/custom/document_register_template_test: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/construction: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/constructors: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/createElement with type extension: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/functional: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/namespaces: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/parsing: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/registration: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/single-parameter createElement: Skip # Issue 31577
+html/custom/document_register_type_extensions_test: Skip # Issue 31577
html/custom/element_upgrade_test: Skip # Issue 31577
html/custom/entered_left_view/.*: Skip # Issue 31577
html/custom/mirrors_2_test: Skip # Issue 31577
diff --git a/tests/lib_2/mirrors/field_metadata2_test.dart b/tests/lib_2/mirrors/field_metadata2_test.dart
deleted file mode 100644
index 60e1b6c..0000000
--- a/tests/lib_2/mirrors/field_metadata2_test.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// compile options: --emit-metadata
-// Copyright (c) 2017, 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.
-
-// Run essentially the same test, but with emit-metadata compile option,
-// which allows us to reflect on the fields.
-import 'dart:mirrors';
-import 'package:expect/expect.dart';
-
-import 'field_metadata_test.dart' as field_metadata_test;
-import 'field_metadata_test.dart' show Foo, Bar;
-
-void main() {
- // Make sure the other test still works.
- field_metadata_test.main();
-
- // Check that we can now reflect on the annotations.
- dynamic f = new Foo();
- var members = reflect(f).type.declarations;
- var x = members[#x] as VariableMirror;
- var bar = x.metadata.first.reflectee as Bar;
- Expect.equals(bar.name, 'bar');
-
- var y = members[#y] as VariableMirror;
- var baz = y.metadata.first.reflectee as Bar;
- Expect.equals(baz.name, 'baz');
-}
diff --git a/tests/lib_2/mirrors/metadata_constructed_constant_test.dart b/tests/lib_2/mirrors/metadata_constructed_constant_test.dart
index 16746a0..fc72601 100644
--- a/tests/lib_2/mirrors/metadata_constructed_constant_test.dart
+++ b/tests/lib_2/mirrors/metadata_constructed_constant_test.dart
@@ -1,4 +1,3 @@
-// compile options: --emit-metadata
// Copyright (c) 2013, 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.
diff --git a/tests/lib_2/mirrors/metadata_constructor_arguments_test.dart b/tests/lib_2/mirrors/metadata_constructor_arguments_test.dart
index bc459e9..361d067 100644
--- a/tests/lib_2/mirrors/metadata_constructor_arguments_test.dart
+++ b/tests/lib_2/mirrors/metadata_constructor_arguments_test.dart
@@ -1,4 +1,3 @@
-// compile options: --emit-metadata
// Copyright (c) 2013, 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.
diff --git a/tests/lib_2/mirrors/metadata_nested_constructor_call_test.dart b/tests/lib_2/mirrors/metadata_nested_constructor_call_test.dart
index d2edccc..bb26dcf 100644
--- a/tests/lib_2/mirrors/metadata_nested_constructor_call_test.dart
+++ b/tests/lib_2/mirrors/metadata_nested_constructor_call_test.dart
@@ -1,4 +1,3 @@
-// compile options: --emit-metadata
// Copyright (c) 2014, 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.
diff --git a/tests/standalone_2/package/package1_test.dart b/tests/standalone_2/package/package1_test.dart
index d038dd8..53c8828 100644
--- a/tests/standalone_2/package/package1_test.dart
+++ b/tests/standalone_2/package/package1_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library package1_test;
diff --git a/tests/standalone_2/package/package_test.dart b/tests/standalone_2/package/package_test.dart
index b606a23..4f7e52b 100644
--- a/tests/standalone_2/package/package_test.dart
+++ b/tests/standalone_2/package/package_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library package_test;
diff --git a/tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart b/tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart
index 166d803..53195a7 100644
--- a/tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart
+++ b/tests/standalone_2/package/scenarios/both_dir_and_file/both_dir_and_file_noimports_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library both_dir_and_file_noimports_test;
diff --git a/tests/standalone_2/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart b/tests/standalone_2/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart
index 7a530a2..f06fc56 100644
--- a/tests/standalone_2/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart
+++ b/tests/standalone_2/package/scenarios/both_dir_and_file/prefers_packages_file_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library prefers_packages_file_test;
diff --git a/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_discovery_test.dart b/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_discovery_test.dart
index f44e0de..5b5156e 100644
--- a/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_discovery_test.dart
+++ b/tests/standalone_2/package/scenarios/empty_packages_file/empty_packages_file_discovery_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library empty_packages_file_discovery_test;
diff --git a/tests/standalone_2/package/scenarios/packages_dir_only/packages/foo/foo.dart b/tests/standalone_2/package/scenarios/packages_dir_only/packages/foo/foo.dart
deleted file mode 100644
index fed9bd7..0000000
--- a/tests/standalone_2/package/scenarios/packages_dir_only/packages/foo/foo.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2015, 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.
-
-library foo;
-
-String bar = 'hello';
diff --git a/tests/standalone_2/package/scenarios/packages_dir_only/packages_dir_only_noimports_test.dart b/tests/standalone_2/package/scenarios/packages_dir_only/packages_dir_only_noimports_test.dart
deleted file mode 100644
index 230a8e9..0000000
--- a/tests/standalone_2/package/scenarios/packages_dir_only/packages_dir_only_noimports_test.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2015, 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.
-
-// PackageRoot=none
-
-library packages_dir_only_noimports_test;
-
-main() {}
diff --git a/tests/standalone_2/package/scenarios/packages_dir_only/packages_dir_only_test.dart b/tests/standalone_2/package/scenarios/packages_dir_only/packages_dir_only_test.dart
deleted file mode 100644
index afec5b5..0000000
--- a/tests/standalone_2/package/scenarios/packages_dir_only/packages_dir_only_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2015, 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.
-
-// PackageRoot=none
-
-library packages_dir_only_test;
-
-import 'package:foo/foo.dart' as foo;
-
-main() {
- if (foo.bar != 'hello') {
- throw new Exception('package "foo" was not resolved correctly');
- }
-}
diff --git a/tests/standalone_2/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_noimports_test.dart b/tests/standalone_2/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_noimports_test.dart
index c765fbe..d5194f1 100644
--- a/tests/standalone_2/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_noimports_test.dart
+++ b/tests/standalone_2/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_noimports_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library packages_file_in_parent_noimports_test;
diff --git a/tests/standalone_2/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_test.dart b/tests/standalone_2/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_test.dart
index 106b1af..0151f19 100644
--- a/tests/standalone_2/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_test.dart
+++ b/tests/standalone_2/package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library packages_file_in_parent_test;
diff --git a/tests/standalone_2/package/scenarios/packages_file_only/packages_file_only_noimports_test.dart b/tests/standalone_2/package/scenarios/packages_file_only/packages_file_only_noimports_test.dart
index 42b4c54..e495256 100644
--- a/tests/standalone_2/package/scenarios/packages_file_only/packages_file_only_noimports_test.dart
+++ b/tests/standalone_2/package/scenarios/packages_file_only/packages_file_only_noimports_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library packages_file_only_noimports_test;
diff --git a/tests/standalone_2/package/scenarios/packages_file_only/packages_file_only_test.dart b/tests/standalone_2/package/scenarios/packages_file_only/packages_file_only_test.dart
index 5339533..554f3b7 100644
--- a/tests/standalone_2/package/scenarios/packages_file_only/packages_file_only_test.dart
+++ b/tests/standalone_2/package/scenarios/packages_file_only/packages_file_only_test.dart
@@ -2,7 +2,7 @@
// 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.
-// PackageRoot=none
+// Packages=none
library packages_file_only_test;
diff --git a/tools/VERSION b/tools/VERSION
index 0ead456..62b6ed6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 8
PATCH 0
-PRERELEASE 12
+PRERELEASE 13
PRERELEASE_PATCH 0
ABI_VERSION 29
OLDEST_SUPPORTED_ABI_VERSION 29
diff --git a/tools/bots/apply_preapprovals.dart b/tools/bots/apply_preapprovals.dart
deleted file mode 100755
index 3b2bcef..0000000
--- a/tools/bots/apply_preapprovals.dart
+++ /dev/null
@@ -1,247 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2018, 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.
-
-// Applies pending pre-approvals for any changelists that have landed according
-// to the git history of HEAD.
-
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:args/args.dart';
-
-import 'results.dart';
-
-main(List<String> args) async {
- final parser = new ArgParser();
- parser.addFlag("dry",
- abbr: "n",
- help: "Don't write out the updated approvals.",
- negatable: false);
- parser.addMultiOption("apply-changelist",
- abbr: "A",
- help: "Apply this changelist even if it hasn't landed",
- splitCommas: false);
- parser.addFlag("help", help: "Show the program usage.", negatable: false);
- parser.addOption("upload",
- abbr: "u",
- help: "Upload the updated results to this cloud storage location");
-
- final options = parser.parse(args);
- if (options["help"]) {
- print("""
-Usage: apply_preapprovals.dart [OPTION]... APPROVALS
-Applies pending pre-approvals for any changelists that have landed according to
-the git history of HEAD.
-
-The options are as follows:
-
-${parser.usage}""");
- return;
- }
-
- final parameters = options.rest;
- if (parameters.length != 1) {
- print("error: Expected one parameter");
- exitCode = 2;
- return;
- }
-
- // Locate gsutil.py.
- gsutilPy = Platform.script
- .resolve("../../third_party/gsutil/gsutil.py")
- .toFilePath();
-
- final approvalsPath = parameters[0];
- final approvals = await loadResultsMap(approvalsPath);
-
- // Find the changelists with pre-approvals.
- final allChangelists = <String>{};
- for (final key in approvals.keys) {
- final record = approvals[key];
- final preapprovals =
- record.putIfAbsent("preapprovals", () => <String, dynamic>{});
- allChangelists.addAll(preapprovals.keys);
- }
- if (allChangelists.isEmpty) {
- print("No pre-approvals are pending");
- }
-
- // Find the order the pre-approved changelists landed in.
- final joinedChangelistsPattern = allChangelists.join("\\|");
- final pattern = "^Change-Id: \\($joinedChangelistsPattern\\)\$";
- final arguments = [
- "rev-list",
- "--pretty=medium",
- "--grep=$pattern",
- "--reverse",
- "HEAD"
- ];
- final processOutput = await Process.run("git", arguments, runInShell: true);
- if (processOutput.exitCode != 0) {
- throw new Exception("Failed to run git $arguments\n"
- "exitCode: ${processOutput.exitCode}\n"
- "stdout: ${processOutput.stdout}\n"
- "stderr: ${processOutput.stderr}");
- }
- final landedChangelists = <String>[];
- final commitOfChangelist = <String, String>{};
- String currentCommit;
- for (final line in LineSplitter.split(processOutput.stdout)) {
- if (line.startsWith("commit ")) {
- currentCommit = line.substring("commit ".length);
- } else if (line.startsWith(" Change-Id: ")) {
- final changeId = line.substring(" Change-Id: ".length);
- if (allChangelists.contains(changeId)) {
- landedChangelists.add(changeId);
- commitOfChangelist[changeId] = currentCommit;
- }
- }
- }
- if (processOutput.stdout != "") {
- print(processOutput.stdout);
- }
-
- // Report the status of each of the pre-approved changelists.
- final unlandedChangelists =
- allChangelists.difference(landedChangelists.toSet());
- for (final changelist in unlandedChangelists) {
- final changelistUrl = "https://dart-review.googlesource.com/q/$changelist";
- print("Pending: Changelist $changelistUrl hasn't landed yet");
- }
- if (allChangelists.isNotEmpty && landedChangelists.isEmpty) {
- print("No pre-approved changelists have landed.");
- }
- for (final changelist in landedChangelists) {
- final changelistUrl = "https://dart-review.googlesource.com/q/$changelist";
- final commit = commitOfChangelist[changelist];
- print("Landed: Changelist $changelistUrl landed in commit $commit");
- }
- for (final changelist in options["apply-changelist"]) {
- final changelistUrl = "https://dart-review.googlesource.com/q/$changelist";
- print("Force applying: Pretending $changelistUrl has landed");
- landedChangelists.add(changelist);
- }
-
- // Apply the pre-approvals for landed changes.
- bool updated = false;
- final conflictsForKey = <String, List<String>>{};
- final changelistsWithMergeConflicts = <String>{};
- int totalNumberOfPreapprovals = 0;
- int totalNumberOfMergeConflicts = 0;
- for (final changelist in landedChangelists) {
- final changelistUrl = "https://dart-review.googlesource.com/q/$changelist";
- final commit = commitOfChangelist[changelist];
- print("\nApplying pre-approvals for changelist "
- "$changelistUrl landed in commit $commit");
- int numberOfPreapprovals = 0;
- int numberOfMergeConflicts = 0;
- for (final key in approvals.keys) {
- final record = approvals[key];
- final preapprovals = record["preapprovals"];
- final preapproval = preapprovals.remove(changelist);
- if (preapproval == null) continue;
- updated = true;
- final conflicts = conflictsForKey.putIfAbsent(key, () => <String>[]);
- if (record["result"] == preapproval["from"]) {
- print("$changelist: $key: "
- "${record["result"]} -> ${preapproval["result"]}");
- conflicts.add("$changelist/$commit had changed approval from "
- "${record["result"]} to ${preapproval["result"]}");
- record["result"] = preapproval["result"];
- record["matches"] = preapproval["matches"];
- record["expected"] = preapproval["expected"];
- record["approver"] = preapproval["preapprover"];
- record["approved_at"] = preapproval["preapproved_at"];
- numberOfPreapprovals++;
- totalNumberOfPreapprovals++;
- } else {
- print("$changelist: $key: MERGE CONFLICT:");
- for (final conflict in conflicts) {
- print(" * $conflict");
- }
- print(" * MERGE CONFLICT: Cannot change approval from "
- "${preapproval["from"]} to ${preapproval["result"]} "
- "because it's currently ${record["result"]}");
- changelistsWithMergeConflicts.add(changelist);
- numberOfMergeConflicts++;
- totalNumberOfMergeConflicts++;
- }
- }
- if (0 < numberOfPreapprovals) {
- print("$numberOfPreapprovals "
- "pre-approvals applied from $changelistUrl commit $commit");
- }
- if (0 < numberOfMergeConflicts) {
- print("Warning: $numberOfMergeConflicts "
- "merge conflicts in pre-approvals for $changelistUrl commit $commit");
- }
- }
-
- // Expire old pre-approvals.
- final now = new DateTime.now().toUtc();
- final expiredChangelists = <String>{};
- for (final record in approvals.values) {
- final preapprovals = record["preapprovals"];
- final changelists = preapprovals.keys.toList();
- for (final changelist in changelists) {
- final preapproval = preapprovals[changelist];
- final expires = DateTime.parse(preapproval["expires"]);
- if (expires.isBefore(now)) {
- updated = true;
- preapprovals.remove(changelist);
- expiredChangelists.add(changelist);
- }
- }
- }
- if (expiredChangelists.isNotEmpty) {
- print("");
- }
- for (final changelist in expiredChangelists) {
- final changelistUrl = "https://dart-review.googlesource.com/q/$changelist";
- print("Expired: Pre-approvals for changelist $changelistUrl have expired");
- }
-
- // Format a final report.
- print("");
- final landedChangelistsCount = landedChangelists.length;
- if (0 < landedChangelistsCount) {
- print("$landedChangelistsCount changelists have landed");
- }
- final expiredChangelistsCount = expiredChangelists.length;
- if (0 < expiredChangelistsCount) {
- print("$expiredChangelistsCount changelists have expired");
- }
- final unlandedChangelistsCount =
- unlandedChangelists.length - expiredChangelistsCount;
- if (0 < unlandedChangelistsCount) {
- print("$unlandedChangelistsCount changelists are pending");
- }
- if (0 < totalNumberOfPreapprovals) {
- print("$totalNumberOfPreapprovals pre-approvals applied");
- }
- if (0 < totalNumberOfPreapprovals) {
- print("Warning: $totalNumberOfMergeConflicts "
- "pre-approvals had merge conflicts");
- }
-
- // Save the updated approvals and upload them to cloud storage.
- print("");
- if (!updated) {
- print("Approvals are unchanged");
- return;
- }
- if (options["dry"]) {
- print("Dry run, not saving the updated approvals");
- return;
- }
- await new File(approvalsPath).writeAsString(
- approvals.values.map((data) => jsonEncode(data) + "\n").join(""));
- print("Wrote updated approvals to $approvalsPath");
- if (options["upload"] != null) {
- print("Uploading updated approvals to ${options["upload"]}...");
- await cpGsutil(approvalsPath, options["upload"]);
- print("Uploaded updated approvals to ${options["upload"]}");
- }
-}
diff --git a/tools/bots/get_builder_status.dart b/tools/bots/get_builder_status.dart
index 9ec200e..cb0d3c4 100755
--- a/tools/bots/get_builder_status.dart
+++ b/tools/bots/get_builder_status.dart
@@ -16,12 +16,20 @@
import 'package:http/http.dart' as http;
const numAttempts = 20;
+const failuresPerConfiguration = 20;
const queryUrl = 'https://firestore.googleapis.com/v1/'
'projects/dart-ci/databases/(default)/documents:runQuery';
String builder;
+String builderBase;
+int buildNumber;
String token;
+List<String> configurations;
+Map<String, List<Map<String, dynamic>>> failures = {};
http.Client client;
+String get buildTable => builder.endsWith('-try') ? 'try_builds' : 'builds';
+String get resultsTable => builder.endsWith('-try') ? 'try_results' : 'results';
+
bool booleanFieldOrFalse(Map<String, dynamic> document, String field) {
Map<String, dynamic> fieldObject = document['fields'][field];
if (fieldObject == null) return false;
@@ -54,42 +62,15 @@
}
builder = options['builder'];
- final buildNumber = options['build_number'];
- final table = builder.endsWith('-try') ? 'try_builds' : 'builds';
+ buildNumber = int.parse(options['build_number']);
+ builderBase = builder.replaceFirst(RegExp('-try\$'), '');
token = await File(options['auth_token']).readAsString();
client = http.Client();
- final query = {
- 'from': [
- {'collectionId': table}
- ],
- 'limit': 1,
- 'where': {
- 'compositeFilter': {
- 'op': 'AND',
- 'filters': [
- {
- 'fieldFilter': {
- 'field': {'fieldPath': 'build_number'},
- 'op': 'EQUAL',
- 'value': {'integerValue': buildNumber}
- }
- },
- {
- 'fieldFilter': {
- 'field': {'fieldPath': 'builder'},
- 'op': 'EQUAL',
- 'value': {'stringValue': builder}
- }
- }
- ]
- }
- }
- };
for (int count = 0; count < numAttempts; ++count) {
if (count > 0) {
await Future.delayed(Duration(seconds: 10));
}
- final response = await runFirestoreQuery(query);
+ final response = await runFirestoreQuery(buildQuery());
if (response.statusCode == HttpStatus.ok) {
final documents = jsonDecode(response.body);
final document = documents.first['document'];
@@ -102,11 +83,11 @@
print('No unapproved new failures');
if (activeFailures == true) {
print('There are unapproved failures from previous builds');
- await printResultsFeedLink();
+ await printResults();
}
} else {
print('There are unapproved new failures on this build');
- await printResultsFeedLink();
+ await printResults();
}
exit((success && (activeFailures != true)) ? 0 : 1);
}
@@ -135,48 +116,198 @@
exit(2);
}
-void printResultsFeedLink() async {
+void printResults() async {
if (builder.endsWith('-try')) return;
- final query = {
- 'from': [
- {'collectionId': 'configurations'}
- ],
- 'where': {
- 'fieldFilter': {
- 'field': {'fieldPath': 'builder'},
- 'op': 'EQUAL',
- 'value': {'stringValue': builder}
- }
- }
- };
- final response = await runFirestoreQuery(query);
+ configurations = await getConfigurations();
+ await printActiveFailures();
+ await printResultsFeedLink();
+}
+
+Future<List<String>> getConfigurations() async {
+ final response = await runFirestoreQuery(configurationsQuery());
if (response.statusCode == HttpStatus.ok) {
final documents = jsonDecode(response.body);
final groups = <String>{
for (Map document in documents)
if (document.containsKey('document'))
- document['document']['name'].split('/').last.split('-').first
+ document['document']['name'].split('/').last
};
- String fragment = [
- 'showLatestFailures=true',
- 'showUnapprovedOnly=true',
- if (groups.isNotEmpty) 'configurationGroups=${groups.join(',')}'
- ].join('&');
- final link = 'https://dart-ci.firebaseapp.com/#$fragment';
- print('Failures link: $link');
- } else {
- print('HTTP status ${response.statusCode} received '
- 'when fetching configurations for results feed link');
- print('HTTP response: ${response.body}');
+ return groups.toList();
+ }
+ print('Could not fetch configurations for $builderBase');
+ return [];
+}
+
+Map<int, Future<String>> commitHashes = {};
+Future<String> commitHash(int index) =>
+ commitHashes.putIfAbsent(index, () => fetchCommitHash(index));
+
+Future<String> fetchCommitHash(int index) async {
+ final response = await runFirestoreQuery(commitQuery(index));
+ if (response.statusCode == HttpStatus.ok) {
+ final document = jsonDecode(response.body).first['document'];
+ if (document != null) {
+ return document['name'].split('/').last;
+ }
+ }
+ print('Could not fetch commit with index $index');
+ return 'missing hash for commit $index';
+}
+
+Future<void> printActiveFailures() async {
+ for (final configuration in configurations) {
+ final response =
+ await runFirestoreQuery(unapprovedFailuresQuery(configuration));
+ if (response.statusCode == HttpStatus.ok) {
+ final documents = jsonDecode(response.body);
+ for (final documentItem in documents) {
+ final document = documentItem['document'];
+ if (document == null) continue;
+ final fields = document['fields'];
+ failures.putIfAbsent(configuration, () => []).add({
+ 'name': fields['name']['stringValue'],
+ 'start': int.parse(fields['blamelist_start_index']['integerValue']),
+ 'end': int.parse(fields['blamelist_end_index']['integerValue']),
+ 'result': fields['result']['stringValue'],
+ 'expected': fields['expected']['stringValue'],
+ 'previous': fields['previous_result']['stringValue'],
+ });
+ }
+ }
+ }
+ for (final configuration in failures.keys) {
+ print('($configuration):');
+ for (final failure in failures[configuration]) {
+ print([
+ ' ',
+ failure['name'],
+ ' (',
+ failure['previous'],
+ ' -> ',
+ failure['result'],
+ ', expected ',
+ failure['expected'],
+ ') at ',
+ (await commitHash(failure['start'])).substring(0, 6),
+ if (failure['start'] != failure['end']) ...[
+ '..',
+ (await commitHash(failure['end'])).substring(0, 6)
+ ]
+ ].join(''));
+ }
}
}
-Future<http.Response> runFirestoreQuery(Map<String, dynamic> query) {
- final json = jsonEncode({'structuredQuery': query});
+void printResultsFeedLink() async {
+ if (builder.endsWith('-try')) return;
+ final groups = {
+ for (final configuration in configurations) configuration.split('-').first
+ };
+ String fragment = [
+ 'showLatestFailures=true',
+ 'showUnapprovedOnly=true',
+ if (groups.isNotEmpty) 'configurationGroups=${groups.join(',')}'
+ ].join('&');
+ final link = 'https://dart-ci.firebaseapp.com/#$fragment';
+ print('\nFailures link: $link');
+}
+
+Future<http.Response> runFirestoreQuery(String query) {
final headers = {
'Authorization': 'Bearer $token',
'Accept': 'application/json',
'Content-Type': 'application/json'
};
- return client.post(queryUrl, headers: headers, body: json);
+ return client.post(queryUrl, headers: headers, body: query);
}
+
+String buildQuery() => jsonEncode({
+ 'structuredQuery': {
+ 'from': [
+ {'collectionId': buildTable}
+ ],
+ 'limit': 1,
+ 'where': {
+ 'compositeFilter': {
+ 'op': 'AND',
+ 'filters': [
+ {
+ 'fieldFilter': {
+ 'field': {'fieldPath': 'build_number'},
+ 'op': 'EQUAL',
+ 'value': {'integerValue': buildNumber}
+ }
+ },
+ {
+ 'fieldFilter': {
+ 'field': {'fieldPath': 'builder'},
+ 'op': 'EQUAL',
+ 'value': {'stringValue': builder}
+ }
+ }
+ ]
+ }
+ }
+ }
+ });
+
+String configurationsQuery() => jsonEncode({
+ 'structuredQuery': {
+ 'from': [
+ {'collectionId': 'configurations'}
+ ],
+ 'where': {
+ 'fieldFilter': {
+ 'field': {'fieldPath': 'builder'},
+ 'op': 'EQUAL',
+ 'value': {'stringValue': builderBase}
+ }
+ }
+ }
+ });
+
+String unapprovedFailuresQuery(String configuration) => jsonEncode({
+ 'structuredQuery': {
+ 'from': [
+ {'collectionId': resultsTable}
+ ],
+ 'limit': failuresPerConfiguration,
+ 'where': {
+ 'compositeFilter': {
+ 'op': 'AND',
+ 'filters': [
+ {
+ 'fieldFilter': {
+ 'field': {'fieldPath': 'active_configurations'},
+ 'op': 'ARRAY_CONTAINS',
+ 'value': {'stringValue': configuration}
+ }
+ },
+ {
+ 'fieldFilter': {
+ 'field': {'fieldPath': 'approved'},
+ 'op': 'EQUAL',
+ 'value': {'booleanValue': false}
+ }
+ }
+ ]
+ }
+ }
+ }
+ });
+
+String commitQuery(int index) => jsonEncode({
+ 'structuredQuery': {
+ 'from': [
+ {'collectionId': 'commits'}
+ ],
+ 'limit': 1,
+ 'where': {
+ 'fieldFilter': {
+ 'field': {'fieldPath': 'index'},
+ 'op': 'EQUAL',
+ 'value': {'integerValue': index}
+ }
+ }
+ }
+ });
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index ae16586..f233f772 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -529,7 +529,7 @@
"non-nullable"
],
"dart2js-options": [
- "--no-runtime-null-safety"
+ "--no-null-safety"
],
"use-sdk": true
}
@@ -582,14 +582,14 @@
"host-checked": true
}
},
- "dart2js-hostasserts-weak-(linux|mac|win)-x64-d8": {
+ "dart2js-hostasserts-weak-(linux|mac|win)-x64-(d8|chrome)": {
"options": {
"builder-tag": "dart2js-weak",
"enable-experiment": [
"non-nullable"
],
"dart2js-options": [
- "--no-runtime-null-safety"
+ "--no-null-safety"
],
"host-checked": true
}
@@ -1302,6 +1302,15 @@
"shards": 6
},
{
+ "name": "vm co19_2 tests",
+ "arguments": [
+ "-ndartkp-weak-asserts-${system}-${mode}-${arch}",
+ "co19_2"
+ ],
+ "fileset": "vm-kernel-nnbd",
+ "shards": 10
+ },
+ {
"name": "vm weak tests with asserts",
"arguments": [
"-ndartkp-weak-asserts-${system}-${mode}-${arch}",
@@ -1315,10 +1324,44 @@
},
{
"builders": [
+ "vm-kernel-precomp-linux-release-x64"
+ ],
+ "meta": {
+ "description": "This configuration is used by the vm kernel precomp linux release builders. (includes co19_2 testing)"
+ },
+ "steps": [
+ {
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": [
+ "runtime_kernel",
+ "dart_precompiled_runtime"
+ ]
+ },
+ {
+ "name": "vm tests",
+ "arguments": [
+ "-ndartkp-${system}-${mode}-${arch}"
+ ],
+ "fileset": "vm-kernel",
+ "shards": 6
+ },
+ {
+ "name": "vm co19_2 tests",
+ "arguments": [
+ "-ndartkp-${system}-${mode}-${arch}",
+ "co19_2"
+ ],
+ "fileset": "vm-kernel",
+ "shards": 10
+ }
+ ]
+ },
+ {
+ "builders": [
"vm-kernel-precomp-linux-product-x64",
"vm-kernel-precomp-linux-release-simarm",
"vm-kernel-precomp-linux-release-simarm64",
- "vm-kernel-precomp-linux-release-x64",
"vm-kernel-precomp-mac-release-simarm64",
"vm-kernel-precomp-win-release-x64"
],
@@ -2519,6 +2562,26 @@
],
"shards": 6,
"fileset": "dart2js_hostasserts_nnbd"
+ },
+ {
+ "name": "dart2js legacy weak lib tests",
+ "arguments": [
+ "-ndart2js-hostasserts-weak-linux-x64-chrome",
+ "--dart2js-batch",
+ "lib_2"
+ ],
+ "shards": 3,
+ "fileset": "dart2js_hostasserts_nnbd"
+ },
+ {
+ "name": "dart2js legacy weak co19 tests",
+ "arguments": [
+ "-ndart2js-hostasserts-weak-linux-x64-chrome",
+ "--dart2js-batch",
+ "co19_2"
+ ],
+ "shards": 6,
+ "fileset": "dart2js_hostasserts_nnbd"
}
]
},
@@ -2833,20 +2896,22 @@
"name": "analyze nnbd strong tests enable-asserts",
"arguments": [
"-nanalyzer-asserts-strong-${system}",
+ "corelib",
"ffi",
"language",
- "lib/mirrors",
- "standalone/io"
+ "lib",
+ "standalone"
]
},
{
"name": "analyze nnbd weak tests enable-asserts",
"arguments": [
"-nanalyzer-asserts-weak-${system}",
+ "corelib",
"ffi",
"language",
- "lib/mirrors",
- "standalone/io"
+ "lib",
+ "standalone"
]
},
{
diff --git a/tools/patches/flutter-engine/0299903f3e78ab6eb1d7d5ed1a70a039b3646913.patch b/tools/patches/flutter-engine/0299903f3e78ab6eb1d7d5ed1a70a039b3646913.patch
deleted file mode 100644
index d7249cf..0000000
--- a/tools/patches/flutter-engine/0299903f3e78ab6eb1d7d5ed1a70a039b3646913.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/DEPS b/DEPS
-index f2b3cc9..88557e8 100644
---- a/DEPS
-+++ b/DEPS
-@@ -72,6 +72,6 @@ vars = {
- 'dart_oauth2_tag': '1.2.1',
- 'dart_observatory_pub_packages_rev': '0894122173b0f98eb08863a7712e78407d4477bc',
-- 'dart_package_config_tag': '2453cd2e78c2db56ee2669ced17ce70dd00bf576',
-+ 'dart_package_config_tag': '3401e2897b3cf46e64966e2ba19ed7032501cf41',
- 'dart_package_resolver_tag': '1.0.10',
- 'dart_path_tag': '1.6.2',
- 'dart_pedantic_tag': 'v1.8.0',
-
diff --git a/tools/patches/flutter-engine/06c3d7ad3a33b7c4d42067c1a24c9279c321071f.patch b/tools/patches/flutter-engine/06c3d7ad3a33b7c4d42067c1a24c9279c321071f.patch
deleted file mode 100644
index 3e47909..0000000
--- a/tools/patches/flutter-engine/06c3d7ad3a33b7c4d42067c1a24c9279c321071f.patch
+++ /dev/null
@@ -1,221 +0,0 @@
-diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc
-index 96ac6facd..b649ca834 100644
---- a/runtime/dart_isolate.cc
-+++ b/runtime/dart_isolate.cc
-@@ -163,7 +163,7 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
- }
-
- auto* isolate_data = static_cast<std::shared_ptr<DartIsolate>*>(
-- Dart_IsolateData(dart_isolate));
-+ Dart_IsolateGroupData(dart_isolate));
- if (isolate_data->get() != this) {
- return false;
- }
-@@ -174,7 +174,7 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
- // We are entering a new scope (for the first time since initialization) and
- // we want to restore the current scope to null when we exit out of this
- // method. This balances the implicit Dart_EnterIsolate call made by
-- // Dart_CreateIsolate (which calls the Initialize).
-+ // Dart_CreateIsolateGroup (which calls the Initialize).
- Dart_ExitIsolate();
-
- tonic::DartIsolateScope scope(isolate());
-@@ -636,8 +636,8 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
- return service_isolate->isolate();
- }
-
--// |Dart_IsolateCreateCallback|
--Dart_Isolate DartIsolate::DartIsolateCreateCallback(
-+// |Dart_IsolateGroupCreateCallback|
-+Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
- const char* advisory_script_uri,
- const char* advisory_script_entrypoint,
- const char* package_root,
-@@ -720,14 +720,16 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
- }
-
- // Create the Dart VM isolate and give it the embedder object as the baton.
-- Dart_Isolate isolate = Dart_CreateIsolate(
-+ Dart_Isolate isolate = Dart_CreateIsolateGroup(
- advisory_script_uri, //
- advisory_script_entrypoint, //
- (*embedder_isolate)->GetIsolateSnapshot()->GetDataMapping(),
- (*embedder_isolate)->GetIsolateSnapshot()->GetInstructionsMapping(),
- (*embedder_isolate)->GetSharedSnapshot()->GetDataMapping(),
- (*embedder_isolate)->GetSharedSnapshot()->GetInstructionsMapping(), flags,
-- embedder_isolate.get(), error);
-+ embedder_isolate.get(), // isolate_group_data
-+ embedder_isolate.get(), // isolate_data
-+ error);
-
- if (isolate == nullptr) {
- FML_DLOG(ERROR) << *error;
-@@ -775,10 +777,10 @@ void DartIsolate::DartIsolateShutdownCallback(
- isolate_group_data->get()->OnShutdownCallback();
- }
-
--// |Dart_IsolateCleanupCallback|
--void DartIsolate::DartIsolateCleanupCallback(
-- std::shared_ptr<DartIsolate>* isolate_data) {
-- delete isolate_data;
-+// |Dart_IsolateGroupCleanupCallback|
-+void DartIsolate::DartIsolateGroupCleanupCallback(
-+ std::shared_ptr<DartIsolate>* isolate_group_data) {
-+ delete isolate_group_data;
- }
-
- fml::RefPtr<const DartSnapshot> DartIsolate::GetIsolateSnapshot() const {
-diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h
-index 60412972a..453810b1b 100644
---- a/runtime/dart_isolate.h
-+++ b/runtime/dart_isolate.h
-@@ -156,8 +156,8 @@ class DartIsolate : public UIDartState {
-
- void OnShutdownCallback();
-
-- // |Dart_IsolateCreateCallback|
-- static Dart_Isolate DartIsolateCreateCallback(
-+ // |Dart_IsolateGroupCreateCallback|
-+ static Dart_Isolate DartIsolateGroupCreateCallback(
- const char* advisory_script_uri,
- const char* advisory_script_entrypoint,
- const char* package_root,
-@@ -189,9 +189,9 @@ class DartIsolate : public UIDartState {
- std::shared_ptr<DartIsolate>* isolate_group_data,
- std::shared_ptr<DartIsolate>* isolate_data);
-
-- // |Dart_IsolateCleanupCallback|
-- static void DartIsolateCleanupCallback(
-- std::shared_ptr<DartIsolate>* embedder_isolate);
-+ // |Dart_IsolateGroupCleanupCallback|
-+ static void DartIsolateGroupCleanupCallback(
-+ std::shared_ptr<DartIsolate>* isolate_group_data);
-
- FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate);
- };
-diff --git a/runtime/dart_vm.cc b/runtime/dart_vm.cc
-index 903e74b15..555d0c9ee 100644
---- a/runtime/dart_vm.cc
-+++ b/runtime/dart_vm.cc
-@@ -366,12 +366,13 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
- params.vm_snapshot_data = vm_data_->GetVMSnapshot().GetDataMapping();
- params.vm_snapshot_instructions =
- vm_data_->GetVMSnapshot().GetInstructionsMapping();
-- params.create = reinterpret_cast<decltype(params.create)>(
-- DartIsolate::DartIsolateCreateCallback);
-- params.shutdown = reinterpret_cast<decltype(params.shutdown)>(
-- DartIsolate::DartIsolateShutdownCallback);
-- params.cleanup = reinterpret_cast<decltype(params.cleanup)>(
-- DartIsolate::DartIsolateCleanupCallback);
-+ params.create_group = reinterpret_cast<decltype(params.create_group)>(
-+ DartIsolate::DartIsolateGroupCreateCallback);
-+ params.shutdown_isolate =
-+ reinterpret_cast<decltype(params.shutdown_isolate)>(
-+ DartIsolate::DartIsolateShutdownCallback);
-+ params.cleanup_group = reinterpret_cast<decltype(params.cleanup_group)>(
-+ DartIsolate::DartIsolateGroupCleanupCallback);
- params.thread_exit = ThreadExitCallback;
- params.get_service_assets = GetVMServiceAssetsArchiveCallback;
- params.entropy_source = dart::bin::GetEntropy;
-diff --git a/shell/platform/fuchsia/dart/dart_component_controller.cc b/shell/platform/fuchsia/dart/dart_component_controller.cc
-index 1c4f71050..c8e7cc5ab 100644
---- a/shell/platform/fuchsia/dart/dart_component_controller.cc
-+++ b/shell/platform/fuchsia/dart/dart_component_controller.cc
-@@ -324,12 +324,13 @@ bool DartComponentController::CreateIsolate(
- auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState(
- namespace_fd, [this](Dart_Handle result) { MessageEpilogue(result); }));
-
-- isolate_ = Dart_CreateIsolate(
-+ isolate_ = Dart_CreateIsolateGroup(
- url_.c_str(), label_.c_str(), isolate_snapshot_data,
- isolate_snapshot_instructions, shared_snapshot_data,
-- shared_snapshot_instructions, nullptr /* flags */, state, &error);
-+ shared_snapshot_instructions, nullptr /* flags */,
-+ state /* isolate_group_data */, state /* isolate_data */, &error);
- if (!isolate_) {
-- FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", error);
-+ FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", error);
- return false;
- }
-
-diff --git a/shell/platform/fuchsia/dart/dart_runner.cc b/shell/platform/fuchsia/dart/dart_runner.cc
-index 200500d2c..b9ded3ac4 100644
---- a/shell/platform/fuchsia/dart/dart_runner.cc
-+++ b/shell/platform/fuchsia/dart/dart_runner.cc
-@@ -61,13 +61,13 @@ const char* kDartVMArgs[] = {
- // clang-format on
- };
-
--Dart_Isolate IsolateCreateCallback(const char* uri,
-- const char* name,
-- const char* package_root,
-- const char* package_config,
-- Dart_IsolateFlags* flags,
-- void* callback_data,
-- char** error) {
-+Dart_Isolate IsolateGroupCreateCallback(const char* uri,
-+ const char* name,
-+ const char* package_root,
-+ const char* package_config,
-+ Dart_IsolateFlags* flags,
-+ void* callback_data,
-+ char** error) {
- if (std::string(uri) == DART_VM_SERVICE_ISOLATE_NAME) {
- #if defined(DART_PRODUCT)
- *error = strdup("The service isolate is not implemented in product mode");
-@@ -81,7 +81,7 @@ Dart_Isolate IsolateCreateCallback(const char* uri,
- return NULL;
- }
-
--void IsolateShutdownCallback(void* callback_data) {
-+void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
- // The service isolate (and maybe later the kernel isolate) doesn't have an
- // async loop.
- auto dispatcher = async_get_default_dispatcher();
-@@ -92,8 +92,8 @@ void IsolateShutdownCallback(void* callback_data) {
- }
- }
-
--void IsolateCleanupCallback(void* callback_data) {
-- delete static_cast<std::shared_ptr<tonic::DartState>*>(callback_data);
-+void IsolateGroupCleanupCallback(void* isolate_group_data) {
-+ delete static_cast<std::shared_ptr<tonic::DartState>*>(isolate_group_data);
- }
-
- void RunApplication(
-@@ -167,9 +167,9 @@ DartRunner::DartRunner() : context_(sys::ComponentContext::Create()) {
- params.vm_snapshot_data = vm_snapshot_data_.address();
- params.vm_snapshot_instructions = vm_snapshot_instructions_.address();
- #endif
-- params.create = IsolateCreateCallback;
-- params.shutdown = IsolateShutdownCallback;
-- params.cleanup = IsolateCleanupCallback;
-+ params.create_group = IsolateGroupCreateCallback;
-+ params.shutdown_isolate = IsolateShutdownCallback;
-+ params.cleanup_group = IsolateGroupCleanupCallback;
- params.entropy_source = EntropySource;
- #if !defined(DART_PRODUCT)
- params.get_service_assets = GetVMServiceAssetsArchiveCallback;
-diff --git a/shell/platform/fuchsia/dart/service_isolate.cc b/shell/platform/fuchsia/dart/service_isolate.cc
-index 2e6eda265..5287d638f 100644
---- a/shell/platform/fuchsia/dart/service_isolate.cc
-+++ b/shell/platform/fuchsia/dart/service_isolate.cc
-@@ -123,14 +123,14 @@ Dart_Isolate CreateServiceIsolate(const char* uri,
- #endif
-
- auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState());
-- Dart_Isolate isolate = Dart_CreateIsolate(
-+ Dart_Isolate isolate = Dart_CreateIsolateGroup(
- uri, DART_VM_SERVICE_ISOLATE_NAME, mapped_isolate_snapshot_data.address(),
- mapped_isolate_snapshot_instructions.address(),
- mapped_shared_snapshot_data.address(),
-- mapped_shared_snapshot_instructions.address(), nullptr /* flags */, state,
-- error);
-+ mapped_shared_snapshot_instructions.address(), nullptr /* flags */,
-+ state /* isolate_group_data */, state /* isolate_data */, error);
- if (!isolate) {
-- FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", *error);
-+ FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", *error);
- return nullptr;
- }
-
diff --git a/tools/patches/flutter-engine/1e43d65d4ab6cb8b79562d83550d5e37f33abb50.patch b/tools/patches/flutter-engine/1e43d65d4ab6cb8b79562d83550d5e37f33abb50.patch
deleted file mode 100644
index bceade5..0000000
--- a/tools/patches/flutter-engine/1e43d65d4ab6cb8b79562d83550d5e37f33abb50.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-diff --git a/DEPS b/DEPS
-index c395874b2..36f4de34b 100644
---- a/DEPS
-+++ b/DEPS
-@@ -96,6 +96,7 @@ vars = {
- 'dart_term_glyph_tag': '1.0.1',
- 'dart_test_reflective_loader_tag': '0.1.8',
- 'dart_test_tag': 'test-v1.6.4',
-+ 'dart_tflite_native_rev': '712b8a93fbb4caf83ffed37f154da88c2a517a91',
- 'dart_typed_data_tag': '1.1.6',
- 'dart_usage_tag': '3.4.0',
- 'dart_watcher_rev': '0.9.7+12-pub',
-@@ -343,6 +344,9 @@ deps = {
- 'src/third_party/dart/third_party/pkg/test':
- Var('dart_git') + '/test.git' + '@' + Var('dart_test_tag'),
-
-+ 'src/third_party/dart/third_party/pkg/tflite_native':
-+ Var('dart_git') + '/tflite_native.git' + '@' + Var('dart_tflite_native_rev'),
-+
- 'src/third_party/dart/third_party/pkg/test_reflective_loader':
- Var('dart_git') + '/test_reflective_loader.git' + '@' + Var('dart_test_reflective_loader_tag'),
-
-@@ -491,6 +495,16 @@ deps = {
- 'dep_type': 'cipd',
- },
-
-+ 'src/third_party/dart/pkg/analysis_server/language_model': {
-+ 'packages': [
-+ {
-+ 'package': 'dart/language_model',
-+ 'version': 'gABkW8D_-f45it57vQ_ZTKFwev16RcCjvrdTCytEnQgC',
-+ }
-+ ],
-+ 'dep_type': 'cipd',
-+ },
-+
- 'src/flutter/third_party/gn': {
- 'packages': [
- {
diff --git a/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch b/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch
deleted file mode 100644
index d4fdc59..0000000
--- a/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch
+++ /dev/null
@@ -1,232 +0,0 @@
-diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc
-index b649ca834..e181dd55b 100644
---- a/runtime/dart_isolate.cc
-+++ b/runtime/dart_isolate.cc
-@@ -163,7 +163,7 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
- }
-
- auto* isolate_data = static_cast<std::shared_ptr<DartIsolate>*>(
-- Dart_IsolateGroupData(dart_isolate));
-+ Dart_IsolateData(dart_isolate));
- if (isolate_data->get() != this) {
- return false;
- }
-@@ -174,7 +174,7 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
- // We are entering a new scope (for the first time since initialization) and
- // we want to restore the current scope to null when we exit out of this
- // method. This balances the implicit Dart_EnterIsolate call made by
-- // Dart_CreateIsolateGroup (which calls the Initialize).
-+ // Dart_CreateIsolate (which calls the Initialize).
- Dart_ExitIsolate();
-
- tonic::DartIsolateScope scope(isolate());
-@@ -636,8 +636,8 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
- return service_isolate->isolate();
- }
-
--// |Dart_IsolateGroupCreateCallback|
--Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
-+// |Dart_IsolateCreateCallback|
-+Dart_Isolate DartIsolate::DartIsolateCreateCallback(
- const char* advisory_script_uri,
- const char* advisory_script_entrypoint,
- const char* package_root,
-@@ -720,16 +720,14 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
- }
-
- // Create the Dart VM isolate and give it the embedder object as the baton.
-- Dart_Isolate isolate = Dart_CreateIsolateGroup(
-+ Dart_Isolate isolate = Dart_CreateIsolate(
- advisory_script_uri, //
- advisory_script_entrypoint, //
- (*embedder_isolate)->GetIsolateSnapshot()->GetDataMapping(),
- (*embedder_isolate)->GetIsolateSnapshot()->GetInstructionsMapping(),
- (*embedder_isolate)->GetSharedSnapshot()->GetDataMapping(),
- (*embedder_isolate)->GetSharedSnapshot()->GetInstructionsMapping(), flags,
-- embedder_isolate.get(), // isolate_group_data
-- embedder_isolate.get(), // isolate_data
-- error);
-+ embedder_isolate.get(), error);
-
- if (isolate == nullptr) {
- FML_DLOG(ERROR) << *error;
-@@ -772,15 +770,14 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
-
- // |Dart_IsolateShutdownCallback|
- void DartIsolate::DartIsolateShutdownCallback(
-- std::shared_ptr<DartIsolate>* isolate_group_data,
-- std::shared_ptr<DartIsolate>* isolate_data) {
-- isolate_group_data->get()->OnShutdownCallback();
-+ std::shared_ptr<DartIsolate>* embedder_isolate) {
-+ embedder_isolate->get()->OnShutdownCallback();
- }
-
--// |Dart_IsolateGroupCleanupCallback|
--void DartIsolate::DartIsolateGroupCleanupCallback(
-- std::shared_ptr<DartIsolate>* isolate_group_data) {
-- delete isolate_group_data;
-+// |Dart_IsolateCleanupCallback|
-+void DartIsolate::DartIsolateCleanupCallback(
-+ std::shared_ptr<DartIsolate>* embedder_isolate) {
-+ delete embedder_isolate;
- }
-
- fml::RefPtr<const DartSnapshot> DartIsolate::GetIsolateSnapshot() const {
-diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h
-index 453810b1b..407852dc2 100644
---- a/runtime/dart_isolate.h
-+++ b/runtime/dart_isolate.h
-@@ -156,8 +156,8 @@ class DartIsolate : public UIDartState {
-
- void OnShutdownCallback();
-
-- // |Dart_IsolateGroupCreateCallback|
-- static Dart_Isolate DartIsolateGroupCreateCallback(
-+ // |Dart_IsolateCreateCallback|
-+ static Dart_Isolate DartIsolateCreateCallback(
- const char* advisory_script_uri,
- const char* advisory_script_entrypoint,
- const char* package_root,
-@@ -186,12 +186,11 @@ class DartIsolate : public UIDartState {
-
- // |Dart_IsolateShutdownCallback|
- static void DartIsolateShutdownCallback(
-- std::shared_ptr<DartIsolate>* isolate_group_data,
-- std::shared_ptr<DartIsolate>* isolate_data);
-+ std::shared_ptr<DartIsolate>* embedder_isolate);
-
-- // |Dart_IsolateGroupCleanupCallback|
-- static void DartIsolateGroupCleanupCallback(
-- std::shared_ptr<DartIsolate>* isolate_group_data);
-+ // |Dart_IsolateCleanupCallback|
-+ static void DartIsolateCleanupCallback(
-+ std::shared_ptr<DartIsolate>* embedder_isolate);
-
- FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate);
- };
-diff --git a/runtime/dart_vm.cc b/runtime/dart_vm.cc
-index 555d0c9ee..903e74b15 100644
---- a/runtime/dart_vm.cc
-+++ b/runtime/dart_vm.cc
-@@ -366,13 +366,12 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
- params.vm_snapshot_data = vm_data_->GetVMSnapshot().GetDataMapping();
- params.vm_snapshot_instructions =
- vm_data_->GetVMSnapshot().GetInstructionsMapping();
-- params.create_group = reinterpret_cast<decltype(params.create_group)>(
-- DartIsolate::DartIsolateGroupCreateCallback);
-- params.shutdown_isolate =
-- reinterpret_cast<decltype(params.shutdown_isolate)>(
-- DartIsolate::DartIsolateShutdownCallback);
-- params.cleanup_group = reinterpret_cast<decltype(params.cleanup_group)>(
-- DartIsolate::DartIsolateGroupCleanupCallback);
-+ params.create = reinterpret_cast<decltype(params.create)>(
-+ DartIsolate::DartIsolateCreateCallback);
-+ params.shutdown = reinterpret_cast<decltype(params.shutdown)>(
-+ DartIsolate::DartIsolateShutdownCallback);
-+ params.cleanup = reinterpret_cast<decltype(params.cleanup)>(
-+ DartIsolate::DartIsolateCleanupCallback);
- params.thread_exit = ThreadExitCallback;
- params.get_service_assets = GetVMServiceAssetsArchiveCallback;
- params.entropy_source = dart::bin::GetEntropy;
-diff --git a/shell/platform/fuchsia/dart/dart_component_controller.cc b/shell/platform/fuchsia/dart/dart_component_controller.cc
-index c8e7cc5ab..1c4f71050 100644
---- a/shell/platform/fuchsia/dart/dart_component_controller.cc
-+++ b/shell/platform/fuchsia/dart/dart_component_controller.cc
-@@ -324,13 +324,12 @@ bool DartComponentController::CreateIsolate(
- auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState(
- namespace_fd, [this](Dart_Handle result) { MessageEpilogue(result); }));
-
-- isolate_ = Dart_CreateIsolateGroup(
-+ isolate_ = Dart_CreateIsolate(
- url_.c_str(), label_.c_str(), isolate_snapshot_data,
- isolate_snapshot_instructions, shared_snapshot_data,
-- shared_snapshot_instructions, nullptr /* flags */,
-- state /* isolate_group_data */, state /* isolate_data */, &error);
-+ shared_snapshot_instructions, nullptr /* flags */, state, &error);
- if (!isolate_) {
-- FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", error);
-+ FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", error);
- return false;
- }
-
-diff --git a/shell/platform/fuchsia/dart/dart_runner.cc b/shell/platform/fuchsia/dart/dart_runner.cc
-index b9ded3ac4..200500d2c 100644
---- a/shell/platform/fuchsia/dart/dart_runner.cc
-+++ b/shell/platform/fuchsia/dart/dart_runner.cc
-@@ -61,13 +61,13 @@ const char* kDartVMArgs[] = {
- // clang-format on
- };
-
--Dart_Isolate IsolateGroupCreateCallback(const char* uri,
-- const char* name,
-- const char* package_root,
-- const char* package_config,
-- Dart_IsolateFlags* flags,
-- void* callback_data,
-- char** error) {
-+Dart_Isolate IsolateCreateCallback(const char* uri,
-+ const char* name,
-+ const char* package_root,
-+ const char* package_config,
-+ Dart_IsolateFlags* flags,
-+ void* callback_data,
-+ char** error) {
- if (std::string(uri) == DART_VM_SERVICE_ISOLATE_NAME) {
- #if defined(DART_PRODUCT)
- *error = strdup("The service isolate is not implemented in product mode");
-@@ -81,7 +81,7 @@ Dart_Isolate IsolateGroupCreateCallback(const char* uri,
- return NULL;
- }
-
--void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
-+void IsolateShutdownCallback(void* callback_data) {
- // The service isolate (and maybe later the kernel isolate) doesn't have an
- // async loop.
- auto dispatcher = async_get_default_dispatcher();
-@@ -92,8 +92,8 @@ void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
- }
- }
-
--void IsolateGroupCleanupCallback(void* isolate_group_data) {
-- delete static_cast<std::shared_ptr<tonic::DartState>*>(isolate_group_data);
-+void IsolateCleanupCallback(void* callback_data) {
-+ delete static_cast<std::shared_ptr<tonic::DartState>*>(callback_data);
- }
-
- void RunApplication(
-@@ -167,9 +167,9 @@ DartRunner::DartRunner() : context_(sys::ComponentContext::Create()) {
- params.vm_snapshot_data = vm_snapshot_data_.address();
- params.vm_snapshot_instructions = vm_snapshot_instructions_.address();
- #endif
-- params.create_group = IsolateGroupCreateCallback;
-- params.shutdown_isolate = IsolateShutdownCallback;
-- params.cleanup_group = IsolateGroupCleanupCallback;
-+ params.create = IsolateCreateCallback;
-+ params.shutdown = IsolateShutdownCallback;
-+ params.cleanup = IsolateCleanupCallback;
- params.entropy_source = EntropySource;
- #if !defined(DART_PRODUCT)
- params.get_service_assets = GetVMServiceAssetsArchiveCallback;
-diff --git a/shell/platform/fuchsia/dart/service_isolate.cc b/shell/platform/fuchsia/dart/service_isolate.cc
-index 5287d638f..2e6eda265 100644
---- a/shell/platform/fuchsia/dart/service_isolate.cc
-+++ b/shell/platform/fuchsia/dart/service_isolate.cc
-@@ -123,14 +123,14 @@ Dart_Isolate CreateServiceIsolate(const char* uri,
- #endif
-
- auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState());
-- Dart_Isolate isolate = Dart_CreateIsolateGroup(
-+ Dart_Isolate isolate = Dart_CreateIsolate(
- uri, DART_VM_SERVICE_ISOLATE_NAME, mapped_isolate_snapshot_data.address(),
- mapped_isolate_snapshot_instructions.address(),
- mapped_shared_snapshot_data.address(),
-- mapped_shared_snapshot_instructions.address(), nullptr /* flags */,
-- state /* isolate_group_data */, state /* isolate_data */, error);
-+ mapped_shared_snapshot_instructions.address(), nullptr /* flags */, state,
-+ error);
- if (!isolate) {
-- FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", *error);
-+ FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", *error);
- return nullptr;
- }
-
diff --git a/tools/patches/flutter-engine/6a65ea9cad4b014f88d2f1be1b321db493725a1c.patch b/tools/patches/flutter-engine/6a65ea9cad4b014f88d2f1be1b321db493725a1c.patch
deleted file mode 100644
index a565233..0000000
--- a/tools/patches/flutter-engine/6a65ea9cad4b014f88d2f1be1b321db493725a1c.patch
+++ /dev/null
@@ -1,622 +0,0 @@
-diff --git a/DEPS b/DEPS
-index 3e0e5d6dc52a..50e2d0298e18 100644
---- a/DEPS
-+++ b/DEPS
-@@ -42,8 +42,8 @@ vars = {
- 'dart_async_tag': '2.0.8',
- 'dart_bazel_worker_tag': 'bazel_worker-v0.1.20',
- 'dart_boolean_selector_tag': '1.0.4',
-- 'dart_boringssl_gen_rev': 'bbf52f18f425e29b1185f2f6753bec02ed8c5880',
-- 'dart_boringssl_rev': '702e2b6d3831486535e958f262a05c75a5cb312e',
-+ 'dart_boringssl_gen_rev': 'b9e27cff1ff0803e97ab1f88764a83be4aa94a6d',
-+ 'dart_boringssl_rev': '4dfd5af70191b068aebe567b8e29ce108cee85ce',
- 'dart_charcode_tag': 'v1.1.2',
- 'dart_cli_util_rev': '4ad7ccbe3195fd2583b30f86a86697ef61e80f41',
- 'dart_collection_tag': '1.14.11',
-diff --git a/ci/licenses_golden/licenses_third_party b/ci/licenses_golden/licenses_third_party
-index 13daa0f54247..e516f2420475 100644
---- a/ci/licenses_golden/licenses_third_party
-+++ b/ci/licenses_golden/licenses_third_party
-@@ -1,4 +1,4 @@
--Signature: bc14a6c15e2ed1c6819d722a808248b9
-+Signature: 5f2b1df54ae6e4ec5836a1d12bf7c70e
-
- UNUSED LICENSES:
-
-@@ -3256,6 +3256,7 @@ FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/bn/rsaz_exp.c
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/bn/rsaz_exp.h
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/ec/p256-x86_64.c
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/ec/p256-x86_64.h
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/fips_shared.lds
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/intcheck1.png
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/intcheck2.png
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/intcheck3.png
-@@ -3280,6 +3281,32 @@ FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCryp
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20170615.docx!/word/styles.xml
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20170615.docx!/word/theme/theme1.xml
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20170615.docx!/word/webSettings.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/[Content_Types].xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/_rels/.rels
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/customXml/_rels/item1.xml.rels
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/customXml/item1.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/customXml/itemProps1.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/docProps/app.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/docProps/core.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/docProps/thumbnail.emf
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/_rels/document.xml.rels
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/document.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/endnotes.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/fontTable.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/footer1.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/footer2.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/footer3.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/footnotes.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/header1.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/header2.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/header3.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/media/image1.png
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/media/image2.png
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/numbering.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/settings.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/styles.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/theme/theme1.xml
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx!/word/webSettings.xml
- FILE: ../../../third_party/boringssl/src/crypto/obj/obj_mac.num
- FILE: ../../../third_party/boringssl/src/crypto/poly1305/poly1305_arm_asm.S
- FILE: ../../../third_party/boringssl/src/crypto/rsa_extra/rsa_print.c
-@@ -3293,9 +3320,9 @@ FILE: ../../../third_party/boringssl/src/crypto/x509/some_names2.pem
- FILE: ../../../third_party/boringssl/src/crypto/x509/some_names3.pem
- FILE: ../../../third_party/boringssl/src/crypto/x509/x509_time_test.cc
- FILE: ../../../third_party/boringssl/src/crypto/x509v3/v3_ocsp.c
--FILE: ../../../third_party/boringssl/src/fipstools/run_cavp.go
--FILE: ../../../third_party/boringssl/src/infra/config/cq.cfg
-+FILE: ../../../third_party/boringssl/src/go.mod
- FILE: ../../../third_party/boringssl/src/ssl/bio_ssl.cc
-+FILE: ../../../third_party/boringssl/src/ssl/ssl_c_test.c
- FILE: ../../../third_party/boringssl/src/util/all_tests.json
- FILE: ../../../third_party/boringssl/src/util/bot/UPDATING
- FILE: ../../../third_party/boringssl/src/util/bot/cmake-linux64.tar.gz.sha1
-@@ -3304,10 +3331,19 @@ FILE: ../../../third_party/boringssl/src/util/bot/cmake-win32.zip.sha1
- FILE: ../../../third_party/boringssl/src/util/bot/nasm-win32.exe.sha1
- FILE: ../../../third_party/boringssl/src/util/bot/perl-win32.zip.sha1
- FILE: ../../../third_party/boringssl/src/util/bot/sde-linux64.tar.bz2.sha1
-+FILE: ../../../third_party/boringssl/src/util/bot/sde-win32.tar.bz2.sha1
- FILE: ../../../third_party/boringssl/src/util/bot/yasm-win32.exe.sha1
- FILE: ../../../third_party/boringssl/src/util/doc.config
- FILE: ../../../third_party/boringssl/src/util/doc.go
--FILE: ../../../third_party/boringssl/src/util/fipstools/delocate.peg.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/acvp/acvptool/acvp.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/acvp/acvptool/acvp/acvp.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/acvp/acvptool/interactive.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/acvp/acvptool/parser.peg
-+FILE: ../../../third_party/boringssl/src/util/fipstools/acvp/acvptool/parser.peg.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/acvp/acvptool/subprocess/hash.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/acvp/acvptool/subprocess/subprocess.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/run_cavp.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/delocate/delocate.peg.go
- FILE: ../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart
- FILE: ../../../third_party/dart/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart
- ----------------------------------------------------------------------------------------------------
-@@ -3462,6 +3498,28 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
-
-+The code in third_party/sike also carries the MIT license:
-+
-+Copyright (c) Microsoft Corporation. All rights reserved.
-+
-+Permission is hereby granted, free of charge, to any person obtaining a copy
-+of this software and associated documentation files (the "Software"), to deal
-+in the Software without restriction, including without limitation the rights
-+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+copies of the Software, and to permit persons to whom the Software is
-+furnished to do so, subject to the following conditions:
-+
-+The above copyright notice and this permission notice shall be included in all
-+copies or substantial portions of the Software.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+SOFTWARE
-+
- Licenses for support code
-
- Parts of the TLS test suite are under the Go license. This code is not included
-@@ -4049,7 +4107,6 @@ FILE: ../../../third_party/boringssl/src/include/openssl/chacha.h
- FILE: ../../../third_party/boringssl/src/include/openssl/crypto.h
- FILE: ../../../third_party/boringssl/src/include/openssl/engine.h
- FILE: ../../../third_party/boringssl/src/include/openssl/hkdf.h
--FILE: ../../../third_party/boringssl/src/include/openssl/lhash_macros.h
- FILE: ../../../third_party/boringssl/src/include/openssl/objects.h
- FILE: ../../../third_party/boringssl/src/include/openssl/opensslconf.h
- FILE: ../../../third_party/boringssl/src/include/openssl/opensslv.h
-@@ -4226,41 +4283,41 @@ FILE: ../../../third_party/boringssl/src/crypto/rand_extra/rand_extra.c
- FILE: ../../../third_party/boringssl/src/crypto/x509/make_many_constraints.go
- FILE: ../../../third_party/boringssl/src/decrepit/cfb/cfb.c
- FILE: ../../../third_party/boringssl/src/decrepit/cfb/cfb_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_aes_gcm_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_aes_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_ctr_drbg_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_ecdsa2_keypair_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_ecdsa2_pkv_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_ecdsa2_siggen_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_ecdsa2_sigver_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_hmac_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_keywrap_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_main.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_rsa2_keygen_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_rsa2_siggen_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_rsa2_sigver_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_sha_monte_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_sha_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_tdes_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_test_util.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_test_util.h
--FILE: ../../../third_party/boringssl/src/fipstools/test_fips.c
- FILE: ../../../third_party/boringssl/src/include/openssl/is_boringssl.h
- FILE: ../../../third_party/boringssl/src/include/openssl/span.h
- FILE: ../../../third_party/boringssl/src/ssl/span_test.cc
- FILE: ../../../third_party/boringssl/src/ssl/ssl_versions.cc
- FILE: ../../../third_party/boringssl/src/tool/file.cc
- FILE: ../../../third_party/boringssl/src/tool/sign.cc
-+FILE: ../../../third_party/boringssl/src/util/ar/ar.go
- FILE: ../../../third_party/boringssl/src/util/check_imported_libraries.go
- FILE: ../../../third_party/boringssl/src/util/convert_comments.go
- FILE: ../../../third_party/boringssl/src/util/embed_test_data.go
--FILE: ../../../third_party/boringssl/src/util/fipstools/ar.go
- FILE: ../../../third_party/boringssl/src/util/fipstools/break-hash.go
--FILE: ../../../third_party/boringssl/src/util/fipstools/const.go
--FILE: ../../../third_party/boringssl/src/util/fipstools/delocate.go
--FILE: ../../../third_party/boringssl/src/util/fipstools/delocate.peg
--FILE: ../../../third_party/boringssl/src/util/fipstools/delocate_test.go
--FILE: ../../../third_party/boringssl/src/util/fipstools/inject-hash.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_aes_gcm_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_aes_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_ctr_drbg_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_ecdsa2_keypair_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_ecdsa2_pkv_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_ecdsa2_siggen_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_ecdsa2_sigver_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_hmac_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_keywrap_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_main.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_rsa2_keygen_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_rsa2_siggen_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_rsa2_sigver_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_sha_monte_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_sha_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_tdes_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_test_util.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_test_util.h
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/test_fips.c
-+FILE: ../../../third_party/boringssl/src/util/fipstools/delocate/delocate.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/delocate/delocate.peg
-+FILE: ../../../third_party/boringssl/src/util/fipstools/delocate/delocate_test.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/fipscommon/const.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/inject_hash/inject_hash.go
- ----------------------------------------------------------------------------------------------------
- Copyright (c) 2017, Google Inc.
-
-@@ -4281,26 +4338,48 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- LIBRARY: boringssl
- ORIGIN: ../../../third_party/boringssl/src/crypto/bytestring/unicode.c
- TYPE: LicenseType.unknown
-+FILE: ../../../third_party/boringssl/src/crypto/abi_self_test.cc
- FILE: ../../../third_party/boringssl/src/crypto/bytestring/unicode.c
- FILE: ../../../third_party/boringssl/src/crypto/chacha/internal.h
- FILE: ../../../third_party/boringssl/src/crypto/cipher_extra/e_aesccm.c
- FILE: ../../../third_party/boringssl/src/crypto/cpu-aarch64-fuchsia.c
-+FILE: ../../../third_party/boringssl/src/crypto/cpu-arm-linux.h
-+FILE: ../../../third_party/boringssl/src/crypto/cpu-arm-linux_test.cc
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/bn/div_extra.c
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/bn/gcd_extra.c
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/ec/felem.c
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/ec/make_p256-x86_64-table.go
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/ec/make_p256-x86_64-tests.go
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/ec/scalar.c
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/ec/simple_mul.c
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/md5/internal.h
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/md5/md5_test.cc
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/sha/internal.h
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/sha/sha_test.cc
- FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/tls/internal.h
-+FILE: ../../../third_party/boringssl/src/crypto/hrss/hrss.c
-+FILE: ../../../third_party/boringssl/src/crypto/hrss/hrss_test.cc
-+FILE: ../../../third_party/boringssl/src/crypto/hrss/internal.h
-+FILE: ../../../third_party/boringssl/src/crypto/impl_dispatch_test.cc
- FILE: ../../../third_party/boringssl/src/crypto/pem/pem_test.cc
-+FILE: ../../../third_party/boringssl/src/crypto/rand_extra/rand_test.cc
- FILE: ../../../third_party/boringssl/src/crypto/self_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_kas_test.cc
--FILE: ../../../third_party/boringssl/src/fipstools/cavp_tlskdf_test.cc
-+FILE: ../../../third_party/boringssl/src/crypto/stack/stack_test.cc
-+FILE: ../../../third_party/boringssl/src/crypto/x509v3/internal.h
- FILE: ../../../third_party/boringssl/src/include/openssl/e_os2.h
-+FILE: ../../../third_party/boringssl/src/include/openssl/hrss.h
- FILE: ../../../third_party/boringssl/src/ssl/handoff.cc
-+FILE: ../../../third_party/boringssl/src/third_party/sike/sike_test.cc
-+FILE: ../../../third_party/boringssl/src/util/ar/ar_test.go
- FILE: ../../../third_party/boringssl/src/util/check_filenames.go
- FILE: ../../../third_party/boringssl/src/util/convert_wycheproof.go
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_kas_test.cc
-+FILE: ../../../third_party/boringssl/src/util/fipstools/cavp/cavp_tlskdf_test.cc
-+FILE: ../../../third_party/boringssl/src/util/godeps.go
-+FILE: ../../../third_party/boringssl/src/util/make_prefix_headers.go
-+FILE: ../../../third_party/boringssl/src/util/read_symbols.go
-+FILE: ../../../third_party/boringssl/src/util/testresult/testresult.go
- ----------------------------------------------------------------------------------------------------
- Copyright (c) 2018, Google Inc.
-
-@@ -5647,6 +5726,33 @@ in the file LICENSE in the source distribution or at
- https://www.openssl.org/source/license.html
- ====================================================================================================
-
-+====================================================================================================
-+LIBRARY: boringssl
-+ORIGIN: ../../../third_party/boringssl/src/crypto/fipsmodule/fips_shared_support.c
-+TYPE: LicenseType.unknown
-+FILE: ../../../third_party/boringssl/src/crypto/fipsmodule/fips_shared_support.c
-+FILE: ../../../third_party/boringssl/src/crypto/siphash/siphash.c
-+FILE: ../../../third_party/boringssl/src/crypto/siphash/siphash_test.cc
-+FILE: ../../../third_party/boringssl/src/decrepit/blowfish/blowfish_test.cc
-+FILE: ../../../third_party/boringssl/src/decrepit/cast/cast_test.cc
-+FILE: ../../../third_party/boringssl/src/include/openssl/siphash.h
-+FILE: ../../../third_party/boringssl/src/util/fipstools/acvp/modulewrapper/modulewrapper.cc
-+----------------------------------------------------------------------------------------------------
-+Copyright (c) 2019, Google Inc.
-+
-+Permission to use, copy, modify, and/or distribute this software for any
-+purpose with or without fee is hereby granted, provided that the above
-+copyright notice and this permission notice appear in all copies.
-+
-+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-+OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+====================================================================================================
-+
- ====================================================================================================
- LIBRARY: boringssl
- ORIGIN: ../../../third_party/boringssl/src/crypto/fipsmodule/modes/cbc.c
-@@ -5880,6 +5986,27 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- OF THE POSSIBILITY OF SUCH DAMAGE.
- ====================================================================================================
-
-+====================================================================================================
-+LIBRARY: boringssl
-+ORIGIN: ../../../third_party/boringssl/src/crypto/hrss/asm/poly_rq_mul.S
-+TYPE: LicenseType.unknown
-+FILE: ../../../third_party/boringssl/src/crypto/hrss/asm/poly_rq_mul.S
-+----------------------------------------------------------------------------------------------------
-+Copyright (c) 2017, the HRSS authors.
-+
-+Permission to use, copy, modify, and/or distribute this software for any
-+purpose with or without fee is hereby granted, provided that the above
-+copyright notice and this permission notice appear in all copies.
-+
-+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-+OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+====================================================================================================
-+
- ====================================================================================================
- LIBRARY: boringssl
- ORIGIN: ../../../third_party/boringssl/src/crypto/pem/pem_all.c
-@@ -6620,6 +6747,10 @@ LIBRARY: boringssl
- ORIGIN: ../../../third_party/boringssl/src/third_party/fiat/LICENSE
- TYPE: LicenseType.mit
- FILE: ../../../third_party/boringssl/src/third_party/fiat/METADATA
-+FILE: ../../../third_party/boringssl/src/third_party/fiat/curve25519_32.h
-+FILE: ../../../third_party/boringssl/src/third_party/fiat/curve25519_64.h
-+FILE: ../../../third_party/boringssl/src/third_party/fiat/p256_32.h
-+FILE: ../../../third_party/boringssl/src/third_party/fiat/p256_64.h
- ----------------------------------------------------------------------------------------------------
- The MIT License (MIT)
-
-@@ -6705,17 +6836,17 @@ SOFTWARE.
- LIBRARY: boringssl
- ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/LICENSE
- TYPE: LicenseType.bsd
--FILE: ../../../third_party/boringssl/src/third_party/googletest/CHANGES
- FILE: ../../../third_party/boringssl/src/third_party/googletest/CONTRIBUTORS
- FILE: ../../../third_party/boringssl/src/third_party/googletest/METADATA
-+FILE: ../../../third_party/boringssl/src/third_party/googletest/cmake/Config.cmake.in
- FILE: ../../../third_party/boringssl/src/third_party/googletest/cmake/gtest.pc.in
- FILE: ../../../third_party/boringssl/src/third_party/googletest/cmake/gtest_main.pc.in
-+FILE: ../../../third_party/boringssl/src/third_party/googletest/cmake/libgtest.la.in
- FILE: ../../../third_party/boringssl/src/third_party/googletest/codegear/gtest.cbproj
- FILE: ../../../third_party/boringssl/src/third_party/googletest/codegear/gtest.groupproj
- FILE: ../../../third_party/boringssl/src/third_party/googletest/codegear/gtest_main.cbproj
- FILE: ../../../third_party/boringssl/src/third_party/googletest/codegear/gtest_unittest.cbproj
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-param-test.h
--FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-param-test.h.pump
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-test-part.h
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-filepath.h
- FILE: ../../../third_party/boringssl/src/third_party/googletest/msvc/2010/gtest-md.sln
-@@ -6823,10 +6954,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ====================================================================================================
- LIBRARY: boringssl
--ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-printers.h
-+ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-matchers.h
- TYPE: LicenseType.bsd
-+FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-matchers.h
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-printers.h
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-spi.h
-+FILE: ../../../third_party/boringssl/src/third_party/googletest/src/gtest-matchers.cc
- FILE: ../../../third_party/boringssl/src/third_party/googletest/src/gtest-printers.cc
- ----------------------------------------------------------------------------------------------------
- Copyright 2007, Google Inc.
-@@ -6995,47 +7128,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ====================================================================================================
- LIBRARY: boringssl
--ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-linked_ptr.h
--TYPE: LicenseType.bsd
--FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-linked_ptr.h
------------------------------------------------------------------------------------------------------
--Copyright 2003 Google Inc.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
-- * Redistributions of source code must retain the above copyright
--notice, this list of conditions and the following disclaimer.
-- * Redistributions in binary form must reproduce the above
--copyright notice, this list of conditions and the following disclaimer
--in the documentation and/or other materials provided with the
--distribution.
-- * Neither the name of Google Inc. nor the names of its
--contributors may be used to endorse or promote products derived from
--this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
--"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
--LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
--A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
--OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
--SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
--LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
--DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
--THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
--OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--====================================================================================================
--
--====================================================================================================
--LIBRARY: boringssl
--ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-param-util-generated.h
-+ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-param-util.h
- TYPE: LicenseType.bsd
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/gtest-typed-test.h
--FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-param-util-generated.h
--FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-param-util-generated.h.pump
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-param-util.h
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-type-util.h
- FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-type-util.h.pump
-@@ -7077,13 +7172,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ====================================================================================================
- LIBRARY: boringssl
--ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-tuple.h
-+ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/samples/sample10_unittest.cc
- TYPE: LicenseType.bsd
--FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-tuple.h
--FILE: ../../../third_party/boringssl/src/third_party/googletest/include/gtest/internal/gtest-tuple.h.pump
-+FILE: ../../../third_party/boringssl/src/third_party/googletest/samples/sample10_unittest.cc
-+FILE: ../../../third_party/boringssl/src/third_party/googletest/samples/sample9_unittest.cc
- ----------------------------------------------------------------------------------------------------
--Copyright 2009 Google Inc.
--All Rights Reserved.
-+Copyright 2009 Google Inc. All Rights Reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
-@@ -7114,38 +7208,39 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ====================================================================================================
- LIBRARY: boringssl
--ORIGIN: ../../../third_party/boringssl/src/third_party/googletest/samples/sample10_unittest.cc
--TYPE: LicenseType.bsd
--FILE: ../../../third_party/boringssl/src/third_party/googletest/samples/sample10_unittest.cc
--FILE: ../../../third_party/boringssl/src/third_party/googletest/samples/sample9_unittest.cc
-+ORIGIN: ../../../third_party/boringssl/src/third_party/sike/LICENSE
-+TYPE: LicenseType.mit
-+FILE: ../../../third_party/boringssl/src/third_party/sike/asm/fp_generic.c
-+FILE: ../../../third_party/boringssl/src/third_party/sike/curve_params.c
-+FILE: ../../../third_party/boringssl/src/third_party/sike/fpx.c
-+FILE: ../../../third_party/boringssl/src/third_party/sike/fpx.h
-+FILE: ../../../third_party/boringssl/src/third_party/sike/isogeny.c
-+FILE: ../../../third_party/boringssl/src/third_party/sike/isogeny.h
-+FILE: ../../../third_party/boringssl/src/third_party/sike/sike.c
-+FILE: ../../../third_party/boringssl/src/third_party/sike/sike.h
-+FILE: ../../../third_party/boringssl/src/third_party/sike/utils.h
- ----------------------------------------------------------------------------------------------------
--Copyright 2009 Google Inc. All Rights Reserved.
-+MIT License
-
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
-+Copyright (c) Microsoft Corporation. All rights reserved.
-
-- * Redistributions of source code must retain the above copyright
--notice, this list of conditions and the following disclaimer.
-- * Redistributions in binary form must reproduce the above
--copyright notice, this list of conditions and the following disclaimer
--in the documentation and/or other materials provided with the
--distribution.
-- * Neither the name of Google Inc. nor the names of its
--contributors may be used to endorse or promote products derived from
--this software without specific prior written permission.
-+Permission is hereby granted, free of charge, to any person obtaining a copy
-+of this software and associated documentation files (the "Software"), to deal
-+in the Software without restriction, including without limitation the rights
-+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+copies of the Software, and to permit persons to whom the Software is
-+furnished to do so, subject to the following conditions:
-
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
--"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
--LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
--A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
--OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
--SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
--LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
--DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
--THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
--OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+The above copyright notice and this permission notice shall be included in all
-+copies or substantial portions of the Software.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+SOFTWARE
- ====================================================================================================
-
- ====================================================================================================
-@@ -7155,8 +7250,11 @@ TYPE: LicenseType.unknown
- FILE: ../../../third_party/boringssl/ios-aarch64/crypto/chacha/chacha-armv8.S
- FILE: ../../../third_party/boringssl/ios-aarch64/crypto/fipsmodule/aesv8-armx64.S
- FILE: ../../../third_party/boringssl/ios-aarch64/crypto/fipsmodule/armv8-mont.S
-+FILE: ../../../third_party/boringssl/ios-aarch64/crypto/fipsmodule/ghash-neon-armv8.S
- FILE: ../../../third_party/boringssl/ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S
- FILE: ../../../third_party/boringssl/ios-aarch64/crypto/fipsmodule/sha1-armv8.S
-+FILE: ../../../third_party/boringssl/ios-aarch64/crypto/fipsmodule/vpaes-armv8.S
-+FILE: ../../../third_party/boringssl/ios-aarch64/crypto/third_party/sike/asm/fp-armv8.S
- FILE: ../../../third_party/boringssl/ios-arm/crypto/chacha/chacha-armv4.S
- FILE: ../../../third_party/boringssl/ios-arm/crypto/fipsmodule/aesv8-armx32.S
- FILE: ../../../third_party/boringssl/ios-arm/crypto/fipsmodule/armv4-mont.S
-@@ -7166,8 +7264,11 @@ FILE: ../../../third_party/boringssl/ios-arm/crypto/fipsmodule/sha1-armv4-large.
- FILE: ../../../third_party/boringssl/linux-aarch64/crypto/chacha/chacha-armv8.S
- FILE: ../../../third_party/boringssl/linux-aarch64/crypto/fipsmodule/aesv8-armx64.S
- FILE: ../../../third_party/boringssl/linux-aarch64/crypto/fipsmodule/armv8-mont.S
-+FILE: ../../../third_party/boringssl/linux-aarch64/crypto/fipsmodule/ghash-neon-armv8.S
- FILE: ../../../third_party/boringssl/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S
- FILE: ../../../third_party/boringssl/linux-aarch64/crypto/fipsmodule/sha1-armv8.S
-+FILE: ../../../third_party/boringssl/linux-aarch64/crypto/fipsmodule/vpaes-armv8.S
-+FILE: ../../../third_party/boringssl/linux-aarch64/crypto/third_party/sike/asm/fp-armv8.S
- FILE: ../../../third_party/boringssl/linux-arm/crypto/chacha/chacha-armv4.S
- FILE: ../../../third_party/boringssl/linux-arm/crypto/fipsmodule/aesv8-armx32.S
- FILE: ../../../third_party/boringssl/linux-arm/crypto/fipsmodule/armv4-mont.S
-@@ -7181,6 +7282,7 @@ FILE: ../../../third_party/boringssl/linux-x86/crypto/fipsmodule/aes-586.S
- FILE: ../../../third_party/boringssl/linux-x86/crypto/fipsmodule/aesni-x86.S
- FILE: ../../../third_party/boringssl/linux-x86/crypto/fipsmodule/bn-586.S
- FILE: ../../../third_party/boringssl/linux-x86/crypto/fipsmodule/co-586.S
-+FILE: ../../../third_party/boringssl/linux-x86/crypto/fipsmodule/ghash-ssse3-x86.S
- FILE: ../../../third_party/boringssl/linux-x86/crypto/fipsmodule/ghash-x86.S
- FILE: ../../../third_party/boringssl/linux-x86/crypto/fipsmodule/md5-586.S
- FILE: ../../../third_party/boringssl/linux-x86/crypto/fipsmodule/sha1-586.S
-@@ -7194,10 +7296,11 @@ FILE: ../../../third_party/boringssl/linux-x86_64/crypto/cipher_extra/chacha20_p
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/aes-x86_64.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S
--FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/bsaes-x86_64.S
-+FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/md5-x86_64.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/p256-x86_64-asm.S
-+FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/rsaz-avx2.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha1-x86_64.S
-@@ -7206,11 +7309,13 @@ FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/sha512-x86_6
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont.S
- FILE: ../../../third_party/boringssl/linux-x86_64/crypto/fipsmodule/x86_64-mont5.S
-+FILE: ../../../third_party/boringssl/linux-x86_64/crypto/third_party/sike/asm/fp-x86_64.S
- FILE: ../../../third_party/boringssl/mac-x86/crypto/chacha/chacha-x86.S
- FILE: ../../../third_party/boringssl/mac-x86/crypto/fipsmodule/aes-586.S
- FILE: ../../../third_party/boringssl/mac-x86/crypto/fipsmodule/aesni-x86.S
- FILE: ../../../third_party/boringssl/mac-x86/crypto/fipsmodule/bn-586.S
- FILE: ../../../third_party/boringssl/mac-x86/crypto/fipsmodule/co-586.S
-+FILE: ../../../third_party/boringssl/mac-x86/crypto/fipsmodule/ghash-ssse3-x86.S
- FILE: ../../../third_party/boringssl/mac-x86/crypto/fipsmodule/ghash-x86.S
- FILE: ../../../third_party/boringssl/mac-x86/crypto/fipsmodule/md5-586.S
- FILE: ../../../third_party/boringssl/mac-x86/crypto/fipsmodule/sha1-586.S
-@@ -7224,10 +7329,11 @@ FILE: ../../../third_party/boringssl/mac-x86_64/crypto/cipher_extra/chacha20_pol
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/aes-x86_64.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S
--FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/bsaes-x86_64.S
-+FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/md5-x86_64.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/p256-x86_64-asm.S
-+FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/rsaz-avx2.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha1-x86_64.S
-@@ -7236,11 +7342,13 @@ FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/sha512-x86_64.
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont.S
- FILE: ../../../third_party/boringssl/mac-x86_64/crypto/fipsmodule/x86_64-mont5.S
-+FILE: ../../../third_party/boringssl/mac-x86_64/crypto/third_party/sike/asm/fp-x86_64.S
- FILE: ../../../third_party/boringssl/win-x86/crypto/chacha/chacha-x86.asm
- FILE: ../../../third_party/boringssl/win-x86/crypto/fipsmodule/aes-586.asm
- FILE: ../../../third_party/boringssl/win-x86/crypto/fipsmodule/aesni-x86.asm
- FILE: ../../../third_party/boringssl/win-x86/crypto/fipsmodule/bn-586.asm
- FILE: ../../../third_party/boringssl/win-x86/crypto/fipsmodule/co-586.asm
-+FILE: ../../../third_party/boringssl/win-x86/crypto/fipsmodule/ghash-ssse3-x86.asm
- FILE: ../../../third_party/boringssl/win-x86/crypto/fipsmodule/ghash-x86.asm
- FILE: ../../../third_party/boringssl/win-x86/crypto/fipsmodule/md5-586.asm
- FILE: ../../../third_party/boringssl/win-x86/crypto/fipsmodule/sha1-586.asm
-@@ -7254,10 +7362,11 @@ FILE: ../../../third_party/boringssl/win-x86_64/crypto/cipher_extra/chacha20_pol
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/aes-x86_64.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm
--FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/bsaes-x86_64.asm
-+FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-ssse3-x86_64.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/md5-x86_64.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/p256-x86_64-asm.asm
-+FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/p256_beeu-x86_64-asm.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/rsaz-avx2.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/sha1-x86_64.asm
-@@ -7266,6 +7375,7 @@ FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/sha512-x86_64.
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/vpaes-x86_64.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont.asm
- FILE: ../../../third_party/boringssl/win-x86_64/crypto/fipsmodule/x86_64-mont5.asm
-+FILE: ../../../third_party/boringssl/win-x86_64/crypto/third_party/sike/asm/fp-x86_64.asm
- ----------------------------------------------------------------------------------------------------
- <THIS BLOCK INTENTIONALLY LEFT BLANK>
- ====================================================================================================
-@@ -23186,4 +23296,4 @@ freely, subject to the following restrictions:
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- ====================================================================================================
--Total license count: 361
-+Total license count: 362
-diff --git a/tools/licenses/lib/main.dart b/tools/licenses/lib/main.dart
-index 19117b13b4fc..3088076b8661 100644
---- a/tools/licenses/lib/main.dart
-+++ b/tools/licenses/lib/main.dart
-@@ -1889,7 +1889,7 @@ class _RepositoryBoringSSLDirectory extends _RepositoryDirectory {
- _RepositoryDirectory createSubdirectory(fs.Directory entry) {
- if (entry.name == 'src')
- return _RepositoryBoringSSLSourceDirectory(this, entry);
-- return super.createSubdirectory(entry);
-+ return _RepositoryBoringSSLDirectory(this, entry);
- }
- }
-
diff --git a/tools/patches/flutter-engine/6e2b3f0326bc15ad938319cbbb151f183d064609.patch b/tools/patches/flutter-engine/6e2b3f0326bc15ad938319cbbb151f183d064609.patch
deleted file mode 100644
index 2c8dada..0000000
--- a/tools/patches/flutter-engine/6e2b3f0326bc15ad938319cbbb151f183d064609.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/DEPS b/DEPS
-index 6205f1b6d..5c1cbf3bc 100644
---- a/DEPS
-+++ b/DEPS
-@@ -72,7 +72,7 @@ vars = {
- 'dart_mustache_tag': '5e81b12215566dbe2473b2afd01a8a8aedd56ad9',
- 'dart_oauth2_tag': '1.2.1',
- 'dart_observatory_pub_packages_rev': '0894122173b0f98eb08863a7712e78407d4477bc',
-- 'dart_package_config_tag': '1.0.5',
-+ 'dart_package_config_tag': '2453cd2e78c2db56ee2669ced17ce70dd00bf576',
- 'dart_package_resolver_tag': '1.0.10',
- 'dart_path_tag': '1.6.2',
- 'dart_pedantic_tag': 'v1.8.0',
diff --git a/tools/patches/flutter-engine/8ba6f7e2eb8ac44b6de3e87a3062d1c8e34b6cc1.patch b/tools/patches/flutter-engine/8ba6f7e2eb8ac44b6de3e87a3062d1c8e34b6cc1.patch
deleted file mode 100644
index 56ac868..0000000
--- a/tools/patches/flutter-engine/8ba6f7e2eb8ac44b6de3e87a3062d1c8e34b6cc1.patch
+++ /dev/null
@@ -1,330 +0,0 @@
-From 6fefdfc884fb7858bd8cd981e1fdb493da8088b4 Mon Sep 17 00:00:00 2001
-From: Alexander Aprelev <aam@google.com>
-Date: Mon, 7 Oct 2019 23:13:33 -0700
-Subject: [PATCH] 2
-
----
- BUILD.gn | 2 +-
- ci/analyze.sh | 6 +-
- .../.gitignore | 0
- flutter_frontend_server/BUILD.gn | 63 +++++++++++++++++
- .../README.md | 0
- .../bin/starter.dart | 2 +-
- .../lib/server.dart | 2 +-
- .../package_incremental.py | 8 +--
- .../pubspec.yaml | 0
- frontend_server/BUILD.gn | 68 ++-----------------
- tools/generate_package_files.py | 2 +-
- 11 files changed, 80 insertions(+), 73 deletions(-)
- rename {frontend_server => flutter_frontend_server}/.gitignore (100%)
- create mode 100644 flutter_frontend_server/BUILD.gn
- rename {frontend_server => flutter_frontend_server}/README.md (100%)
- rename {frontend_server => flutter_frontend_server}/bin/starter.dart (76%)
- rename {frontend_server => flutter_frontend_server}/lib/server.dart (98%)
- rename {frontend_server => flutter_frontend_server}/package_incremental.py (94%)
- rename {frontend_server => flutter_frontend_server}/pubspec.yaml (100%)
-
-diff --git a/BUILD.gn b/BUILD.gn
-index b894fe26f..e4ce1dea1 100644
---- a/BUILD.gn
-+++ b/BUILD.gn
-@@ -42,7 +42,7 @@ group("flutter") {
- if (!is_fuchsia && !is_fuchsia_host) {
- if (current_toolchain == host_toolchain) {
- public_deps += [
-- "$flutter_root/frontend_server",
-+ "$flutter_root/flutter_frontend_server:frontend_server",
- "//third_party/dart:create_sdk",
- ]
-
-diff --git a/ci/analyze.sh b/ci/analyze.sh
-index 9ee12a913..6b48c9447 100755
---- a/ci/analyze.sh
-+++ b/ci/analyze.sh
-@@ -18,11 +18,11 @@ if [ -n "$RESULTS" ]; then
- exit 1;
- fi
-
--echo "Analyzing frontend_server..."
-+echo "Analyzing flutter_frontend_server..."
- RESULTS=`dartanalyzer \
-- --packages=flutter/frontend_server/.packages \
-+ --packages=flutter/flutter_frontend_server/.packages \
- --options flutter/analysis_options.yaml \
-- flutter/frontend_server \
-+ flutter/flutter_frontend_server \
- 2>&1 \
- | grep -Ev "No issues found!" \
- | grep -Ev "Analyzing.+frontend_server"`
-diff --git a/frontend_server/.gitignore b/flutter_frontend_server/.gitignore
-similarity index 100%
-rename from frontend_server/.gitignore
-rename to flutter_frontend_server/.gitignore
-diff --git a/flutter_frontend_server/BUILD.gn b/flutter_frontend_server/BUILD.gn
-new file mode 100644
-index 000000000..37740acaa
---- /dev/null
-+++ b/flutter_frontend_server/BUILD.gn
-@@ -0,0 +1,63 @@
-+# Copyright 2013 The Flutter Authors. All rights reserved.
-+# Use of this source code is governed by a BSD-style license that can be
-+# found in the LICENSE file.
-+
-+if (!is_fuchsia_host && !is_fuchsia) {
-+ import("//third_party/dart/utils/application_snapshot.gni")
-+
-+ frontend_server_files =
-+ exec_script("//third_party/dart/tools/list_dart_files.py",
-+ [
-+ "absolute",
-+ rebase_path("."),
-+ ],
-+ "list lines")
-+
-+ frontend_server_files +=
-+ exec_script("//third_party/dart/tools/list_dart_files.py",
-+ [
-+ "absolute",
-+ rebase_path("../../third_party/dart/pkg"),
-+ ],
-+ "list lines")
-+
-+ application_snapshot("frontend_server") {
-+ main_dart = "bin/starter.dart"
-+ deps = [
-+ ":package_incremental_compiler",
-+ "$flutter_root/lib/snapshot:kernel_platform_files",
-+ ]
-+ dot_packages = rebase_path(".packages")
-+ flutter_patched_sdk = rebase_path("$root_out_dir/flutter_patched_sdk")
-+ training_args = [
-+ "--train",
-+ "--sdk-root=$flutter_patched_sdk",
-+ rebase_path(main_dart),
-+ ]
-+
-+ inputs = frontend_server_files
-+ }
-+
-+ # For flutter/flutter#36738 we make the source files available so that
-+ # we can generate a local frontend_server snapshot in the tools cache.
-+ action("package_incremental_compiler") {
-+ script = "$flutter_root/flutter_frontend_server/package_incremental.py"
-+
-+ inputs = frontend_server_files
-+
-+ outputs = [
-+ "$root_gen_dir/dart-pkg/frontend_server/pubspec.yaml",
-+ "$root_gen_dir/dart-pkg/vm/pubspec.yaml",
-+ "$root_gen_dir/dart-pkg/build_integration/pubspec.yaml",
-+ "$root_gen_dir/dart-pkg/front_end/pubspec.yaml",
-+ "$root_gen_dir/dart-pkg/kernel/pubspec.yaml",
-+ "$root_gen_dir/dart-pkg/dev_compiler/pubspec.yaml",
-+ ]
-+
-+ args = [
-+ "--input-root=" + rebase_path("//third_party/dart/pkg"),
-+ "--output-root=" + rebase_path("$root_gen_dir/dart-pkg"),
-+ "--frontend-server=" + rebase_path("$flutter_root"),
-+ ]
-+ }
-+}
-diff --git a/frontend_server/README.md b/flutter_frontend_server/README.md
-similarity index 100%
-rename from frontend_server/README.md
-rename to flutter_frontend_server/README.md
-diff --git a/frontend_server/bin/starter.dart b/flutter_frontend_server/bin/starter.dart
-similarity index 76%
-rename from frontend_server/bin/starter.dart
-rename to flutter_frontend_server/bin/starter.dart
-index da85e5575..862a8a7ea 100644
---- a/frontend_server/bin/starter.dart
-+++ b/flutter_frontend_server/bin/starter.dart
-@@ -2,7 +2,7 @@ library frontend_server;
-
- import 'dart:io';
-
--import 'package:frontend_server/server.dart';
-+import 'package:flutter_frontend_server/server.dart';
-
- void main(List<String> args) async {
- final int exitCode = await starter(args);
-diff --git a/frontend_server/lib/server.dart b/flutter_frontend_server/lib/server.dart
-similarity index 98%
-rename from frontend_server/lib/server.dart
-rename to flutter_frontend_server/lib/server.dart
-index 8e34efa93..24894c878 100644
---- a/frontend_server/lib/server.dart
-+++ b/flutter_frontend_server/lib/server.dart
-@@ -11,7 +11,7 @@ import 'package:args/args.dart';
- import 'package:path/path.dart' as path;
-
- import 'package:vm/incremental_compiler.dart';
--import 'package:vm/frontend_server.dart' as frontend
-+import 'package:frontend_server/frontend_server.dart' as frontend
- show
- FrontendCompiler,
- CompilerInterface,
-diff --git a/frontend_server/package_incremental.py b/flutter_frontend_server/package_incremental.py
-similarity index 94%
-rename from frontend_server/package_incremental.py
-rename to flutter_frontend_server/package_incremental.py
-index 63b019a33..a8b424260 100755
---- a/frontend_server/package_incremental.py
-+++ b/flutter_frontend_server/package_incremental.py
-@@ -15,7 +15,7 @@ PACKAGES = [
- "kernel",
- "front_end",
- "dev_compiler",
-- "frontend_server",
-+ "flutter_frontend_server",
- ]
-
- VM_PUBSPEC = r'''name: vm
-@@ -41,7 +41,7 @@ dependencies:
- meta: any
- '''
-
--FRONTEND_SERVER_PUBSPEC = r'''name: frontend_server
-+FLUTTER_FRONTEND_SERVER_PUBSPEC = r'''name: flutter_frontend_server
- version: 0.0.1
- environment:
- sdk: ">=2.2.2 <3.0.0"
-@@ -87,7 +87,7 @@ dependencies:
- PUBSPECS = {
- 'vm': VM_PUBSPEC,
- 'build_integration': BUILD_INTEGRATION_PUBSPEC,
-- 'frontend_server': FRONTEND_SERVER_PUBSPEC,
-+ 'flutter_frontend_server': FLUTTER_FRONTEND_SERVER_PUBSPEC,
- 'kernel': KERNEL_PUBSPEC,
- 'front_end': FRONT_END_PUBSPEC,
- 'dev_compiler': DEV_COMPILER_PUBSPEC,
-@@ -103,7 +103,7 @@ def main():
- for package in PACKAGES:
- base = args.input
- # Handle different path for frontend_server
-- if package == 'frontend_server':
-+ if package == 'flutter_frontend_server':
- base = args.frontend
- package_root = os.path.join(base, package)
- for root, directories, files in os.walk(package_root):
-diff --git a/frontend_server/pubspec.yaml b/flutter_frontend_server/pubspec.yaml
-similarity index 100%
-rename from frontend_server/pubspec.yaml
-rename to flutter_frontend_server/pubspec.yaml
-diff --git a/frontend_server/BUILD.gn b/frontend_server/BUILD.gn
-index 330f1e394..6cb8ce88f 100644
---- a/frontend_server/BUILD.gn
-+++ b/frontend_server/BUILD.gn
-@@ -6,9 +6,9 @@ if (is_fuchsia_host || is_fuchsia) {
- import("//build/dart/dart_library.gni")
- import("//build/dart/dart_tool.gni")
-
-- dart_library("frontend_server") {
-+ dart_library("flutter_frontend_server") {
- disable_analysis = true
-- package_name = "frontend_server"
-+ package_name = "flutter_frontend_server"
-
- sources = [
- "server.dart",
-@@ -19,6 +19,7 @@ if (is_fuchsia_host || is_fuchsia) {
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/usage",
- "//third_party/dart/pkg/build_integration",
-+ "//third_party/dart/pkg/frontend_server",
- "//third_party/dart/pkg/front_end",
- "//third_party/dart/pkg/kernel",
- "//third_party/dart/pkg/vm",
-@@ -27,72 +28,15 @@ if (is_fuchsia_host || is_fuchsia) {
-
- dart_tool("frontend_server_tool") {
- main_dart = "bin/starter.dart"
-- source_dir = "."
-+ source_dir = "../flutter_frontend_server"
- disable_analysis = true
- output_name = "frontend_server"
-
- sources = []
-
- deps = [
-- ":frontend_server",
-- ]
-- }
--} else {
-- import("//third_party/dart/utils/application_snapshot.gni")
--
-- frontend_server_files =
-- exec_script("//third_party/dart/tools/list_dart_files.py",
-- [
-- "absolute",
-- rebase_path("."),
-- ],
-- "list lines")
--
-- frontend_server_files +=
-- exec_script("//third_party/dart/tools/list_dart_files.py",
-- [
-- "absolute",
-- rebase_path("../../third_party/dart/pkg"),
-- ],
-- "list lines")
--
-- application_snapshot("frontend_server") {
-- main_dart = "bin/starter.dart"
-- deps = [
-- ":package_incremental_compiler",
-- "$flutter_root/lib/snapshot:kernel_platform_files",
-- ]
-- dot_packages = rebase_path(".packages")
-- flutter_patched_sdk = rebase_path("$root_out_dir/flutter_patched_sdk")
-- training_args = [
-- "--train",
-- "--sdk-root=$flutter_patched_sdk",
-- rebase_path(main_dart),
-- ]
--
-- inputs = frontend_server_files
-- }
--
-- # For flutter/flutter#36738 we make the source files available so that
-- # we can generate a local frontend_server snapshot in the tools cache.
-- action("package_incremental_compiler") {
-- script = "$flutter_root/frontend_server/package_incremental.py"
--
-- inputs = frontend_server_files
--
-- outputs = [
-- "$root_gen_dir/dart-pkg/frontend_server/pubspec.yaml",
-- "$root_gen_dir/dart-pkg/vm/pubspec.yaml",
-- "$root_gen_dir/dart-pkg/build_integration/pubspec.yaml",
-- "$root_gen_dir/dart-pkg/front_end/pubspec.yaml",
-- "$root_gen_dir/dart-pkg/kernel/pubspec.yaml",
-- "$root_gen_dir/dart-pkg/dev_compiler/pubspec.yaml",
-- ]
--
-- args = [
-- "--input-root=" + rebase_path("//third_party/dart/pkg"),
-- "--output-root=" + rebase_path("$root_gen_dir/dart-pkg"),
-- "--frontend-server=" + rebase_path("$flutter_root"),
-+ ":flutter_frontend_server",
- ]
- }
- }
-+
-diff --git a/tools/generate_package_files.py b/tools/generate_package_files.py
-index 13399b126..1eb1e6f6c 100644
---- a/tools/generate_package_files.py
-+++ b/tools/generate_package_files.py
-@@ -10,7 +10,7 @@ import os
- import shutil
-
- ALL_PACKAGES = {
-- 'frontend_server': [],
-+ 'flutter_frontend_server': [],
- }
-
- SRC_DIR = os.getcwd()
---
-2.23.0.581.g78d2f28ef7-goog
-
diff --git a/tools/patches/flutter-engine/a61c775db81ef2a389d5aee6236176362b082d58.patch b/tools/patches/flutter-engine/a61c775db81ef2a389d5aee6236176362b082d58.patch
deleted file mode 100644
index 8e96c95..0000000
--- a/tools/patches/flutter-engine/a61c775db81ef2a389d5aee6236176362b082d58.patch
+++ /dev/null
@@ -1,613 +0,0 @@
-diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc
-index 2db8ae2c7cd5..dcbe05f66691 100644
---- a/runtime/dart_isolate.cc
-+++ b/runtime/dart_isolate.cc
-@@ -32,7 +32,6 @@ namespace flutter {
- std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
- const Settings& settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- TaskRunners task_runners,
- std::unique_ptr<Window> window,
- fml::WeakPtr<IOManager> io_manager,
-@@ -58,7 +57,6 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
- std::shared_ptr<DartIsolate>(new DartIsolate(
- settings, // settings
- std::move(isolate_snapshot), // isolate snapshot
-- std::move(shared_snapshot), // shared snapshot
- task_runners, // task runners
- std::move(io_manager), // IO manager
- std::move(image_decoder), // Image Decoder
-@@ -102,7 +100,6 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
-
- DartIsolate::DartIsolate(const Settings& settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- TaskRunners task_runners,
- fml::WeakPtr<IOManager> io_manager,
- fml::WeakPtr<ImageDecoder> image_decoder,
-@@ -123,7 +120,6 @@ DartIsolate::DartIsolate(const Settings& settings,
- DartVMRef::GetIsolateNameServer()),
- settings_(settings),
- isolate_snapshot_(std::move(isolate_snapshot)),
-- shared_snapshot_(std::move(shared_snapshot)),
- child_isolate_preparer_(std::move(child_isolate_preparer)),
- isolate_create_callback_(isolate_create_callback),
- isolate_shutdown_callback_(isolate_shutdown_callback) {
-@@ -592,7 +588,6 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
- DartIsolate::CreateRootIsolate(
- vm_data->GetSettings(), // settings
- vm_data->GetIsolateSnapshot(), // isolate snapshot
-- vm_data->GetSharedSnapshot(), // shared snapshot
- null_task_runners, // task runners
- nullptr, // window
- {}, // IO Manager
-@@ -705,7 +700,6 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
- std::shared_ptr<DartIsolate>(new DartIsolate(
- (*raw_embedder_isolate)->GetSettings(), // settings
- (*raw_embedder_isolate)->GetIsolateSnapshot(), // isolate_snapshot
-- (*raw_embedder_isolate)->GetSharedSnapshot(), // shared_snapshot
- null_task_runners, // task_runners
- fml::WeakPtr<IOManager>{}, // io_manager
- fml::WeakPtr<ImageDecoder>{}, // io_manager
-@@ -724,9 +718,7 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
- advisory_script_uri, //
- advisory_script_entrypoint, //
- (*embedder_isolate)->GetIsolateSnapshot()->GetDataMapping(),
-- (*embedder_isolate)->GetIsolateSnapshot()->GetInstructionsMapping(),
-- (*embedder_isolate)->GetSharedSnapshot()->GetDataMapping(),
-- (*embedder_isolate)->GetSharedSnapshot()->GetInstructionsMapping(), flags,
-+ (*embedder_isolate)->GetIsolateSnapshot()->GetInstructionsMapping(), flags,
- embedder_isolate.get(), // isolate_group_data
- embedder_isolate.get(), // isolate_group
- error);
-@@ -791,10 +783,6 @@ fml::RefPtr<const DartSnapshot> DartIsolate::GetIsolateSnapshot() const {
- return isolate_snapshot_;
- }
-
--fml::RefPtr<const DartSnapshot> DartIsolate::GetSharedSnapshot() const {
-- return shared_snapshot_;
--}
--
- std::weak_ptr<DartIsolate> DartIsolate::GetWeakIsolatePtr() {
- return std::static_pointer_cast<DartIsolate>(shared_from_this());
- }
-diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h
-index e7ab9b30243c..2abaa11fe011 100644
---- a/runtime/dart_isolate.h
-+++ b/runtime/dart_isolate.h
-@@ -143,10 +143,6 @@ class DartIsolate : public UIDartState {
- /// usually obtained from the
- /// DartVMData associated with the
- /// running Dart VM instance.
-- /// @param[in] shared_snapshot The shared snapshot. This is
-- /// usually obtained from the
-- /// DartVMData associated with the
-- /// running Dart VM instance.
- /// @param[in] task_runners The task runners used by the
- /// isolate. Via UI bindings, the
- /// isolate will use the IO task
-@@ -192,7 +188,6 @@ class DartIsolate : public UIDartState {
- static std::weak_ptr<DartIsolate> CreateRootIsolate(
- const Settings& settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- TaskRunners task_runners,
- std::unique_ptr<Window> window,
- fml::WeakPtr<IOManager> io_manager,
-@@ -385,14 +380,6 @@ class DartIsolate : public UIDartState {
- ///
- fml::RefPtr<const DartSnapshot> GetIsolateSnapshot() const;
-
-- //----------------------------------------------------------------------------
-- /// @brief Get the shared snapshot used to launch this isolate. This is
-- /// referenced by any child isolates launched by the root isolate.
-- ///
-- /// @return The shared snapshot.
-- ///
-- fml::RefPtr<const DartSnapshot> GetSharedSnapshot() const;
--
- //----------------------------------------------------------------------------
- /// @brief A weak pointer to the Dart isolate instance. This instance may
- /// only be used on the task runner that created the root isolate.
-@@ -428,7 +415,6 @@ class DartIsolate : public UIDartState {
- Phase phase_ = Phase::Unknown;
- const Settings settings_;
- const fml::RefPtr<const DartSnapshot> isolate_snapshot_;
-- const fml::RefPtr<const DartSnapshot> shared_snapshot_;
- std::vector<std::shared_ptr<const fml::Mapping>> kernel_buffers_;
- std::vector<std::unique_ptr<AutoFireClosure>> shutdown_callbacks_;
- ChildIsolatePreparer child_isolate_preparer_ = nullptr;
-@@ -438,7 +424,6 @@ class DartIsolate : public UIDartState {
-
- DartIsolate(const Settings& settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- TaskRunners task_runners,
- fml::WeakPtr<IOManager> io_manager,
- fml::WeakPtr<ImageDecoder> image_decoder,
-diff --git a/runtime/dart_isolate_unittests.cc b/runtime/dart_isolate_unittests.cc
-index 83a140737324..4d860f82d781 100644
---- a/runtime/dart_isolate_unittests.cc
-+++ b/runtime/dart_isolate_unittests.cc
-@@ -38,7 +38,6 @@ TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) {
- auto weak_isolate = DartIsolate::CreateRootIsolate(
- vm_data->GetSettings(), // settings
- vm_data->GetIsolateSnapshot(), // isolate snapshot
-- vm_data->GetSharedSnapshot(), // shared snapshot
- std::move(task_runners), // task runners
- nullptr, // window
- {}, // io manager
-@@ -71,7 +70,6 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) {
- auto weak_isolate = DartIsolate::CreateRootIsolate(
- vm_data->GetSettings(), // settings
- vm_data->GetIsolateSnapshot(), // isolate snapshot
-- vm_data->GetSharedSnapshot(), // shared snapshot
- std::move(task_runners), // task runners
- nullptr, // window
- {}, // io manager
-@@ -181,7 +179,6 @@ static void RunDartCodeInIsolate(DartVMRef& vm_ref,
- auto weak_isolate = DartIsolate::CreateRootIsolate(
- vm_data->GetSettings(), // settings
- vm_data->GetIsolateSnapshot(), // isolate snapshot
-- vm_data->GetSharedSnapshot(), // shared snapshot
- std::move(task_runners), // task runners
- nullptr, // window
- {}, // io manager
-diff --git a/runtime/dart_lifecycle_unittests.cc b/runtime/dart_lifecycle_unittests.cc
-index 7a607b7be26f..7a35c96167e5 100644
---- a/runtime/dart_lifecycle_unittests.cc
-+++ b/runtime/dart_lifecycle_unittests.cc
-@@ -53,7 +53,6 @@ static std::shared_ptr<DartIsolate> CreateAndRunRootIsolate(
- auto isolate_weak = DartIsolate::CreateRootIsolate(
- vm.GetSettings(), // settings
- vm.GetIsolateSnapshot(), // isolate_snapshot
-- vm.GetSharedSnapshot(), // shared_snapshot
- runners, // task_runners
- {}, // window
- {}, // io_manager
-diff --git a/runtime/dart_snapshot.cc b/runtime/dart_snapshot.cc
-index acebcd3493d8..a5df79bb136c 100644
---- a/runtime/dart_snapshot.cc
-+++ b/runtime/dart_snapshot.cc
-@@ -181,10 +181,6 @@ fml::RefPtr<DartSnapshot> DartSnapshot::IsolateSnapshotFromSettings(
- return nullptr;
- }
-
--fml::RefPtr<DartSnapshot> DartSnapshot::Empty() {
-- return fml::MakeRefCounted<DartSnapshot>(nullptr, nullptr);
--}
--
- DartSnapshot::DartSnapshot(std::shared_ptr<const fml::Mapping> data,
- std::shared_ptr<const fml::Mapping> instructions)
- : data_(std::move(data)), instructions_(std::move(instructions)) {}
-diff --git a/runtime/dart_snapshot.h b/runtime/dart_snapshot.h
-index 162710ff2a6a..97038aac4aee 100644
---- a/runtime/dart_snapshot.h
-+++ b/runtime/dart_snapshot.h
-@@ -102,17 +102,6 @@ class DartSnapshot : public fml::RefCountedThreadSafe<DartSnapshot> {
- static fml::RefPtr<DartSnapshot> IsolateSnapshotFromSettings(
- const Settings& settings);
-
-- //----------------------------------------------------------------------------
-- /// @brief An empty an invalid snapshot. This is used as a placeholder
-- /// for certain optional snapshots.
-- ///
-- /// @bug Now that shared snapshots are no longer required, consider
-- /// removing this constructor.
-- ///
-- /// @return An invalid empty snapshot.
-- ///
-- static fml::RefPtr<DartSnapshot> Empty();
--
- //----------------------------------------------------------------------------
- /// @brief Determines if this snapshot contains a heap component. Since
- /// the instructions component is optional, the method does not
-diff --git a/runtime/dart_vm.cc b/runtime/dart_vm.cc
-index 37f8e690f737..0c18ba8da702 100644
---- a/runtime/dart_vm.cc
-+++ b/runtime/dart_vm.cc
-@@ -232,12 +232,10 @@ std::shared_ptr<DartVM> DartVM::Create(
- Settings settings,
- fml::RefPtr<DartSnapshot> vm_snapshot,
- fml::RefPtr<DartSnapshot> isolate_snapshot,
-- fml::RefPtr<DartSnapshot> shared_snapshot,
- std::shared_ptr<IsolateNameServer> isolate_name_server) {
- auto vm_data = DartVMData::Create(settings, //
- std::move(vm_snapshot), //
-- std::move(isolate_snapshot), //
-- std::move(shared_snapshot) //
-+ std::move(isolate_snapshot) //
- );
-
- if (!vm_data) {
-diff --git a/runtime/dart_vm.h b/runtime/dart_vm.h
-index 40b8dc4a242e..ac84fe77020d 100644
---- a/runtime/dart_vm.h
-+++ b/runtime/dart_vm.h
-@@ -162,7 +162,6 @@ class DartVM {
- Settings settings,
- fml::RefPtr<DartSnapshot> vm_snapshot,
- fml::RefPtr<DartSnapshot> isolate_snapshot,
-- fml::RefPtr<DartSnapshot> shared_snapshot,
- std::shared_ptr<IsolateNameServer> isolate_name_server);
-
- DartVM(std::shared_ptr<const DartVMData> data,
-diff --git a/runtime/dart_vm_data.cc b/runtime/dart_vm_data.cc
-index e14c998daa74..b93d9ba9ad03 100644
---- a/runtime/dart_vm_data.cc
-+++ b/runtime/dart_vm_data.cc
-@@ -9,8 +9,7 @@ namespace flutter {
- std::shared_ptr<const DartVMData> DartVMData::Create(
- Settings settings,
- fml::RefPtr<DartSnapshot> vm_snapshot,
-- fml::RefPtr<DartSnapshot> isolate_snapshot,
-- fml::RefPtr<DartSnapshot> shared_snapshot) {
-+ fml::RefPtr<DartSnapshot> isolate_snapshot) {
- if (!vm_snapshot || !vm_snapshot->IsValid()) {
- // Caller did not provide a valid VM snapshot. Attempt to infer one
- // from the settings.
-@@ -33,30 +32,19 @@ std::shared_ptr<const DartVMData> DartVMData::Create(
- }
- }
-
-- if (!shared_snapshot || !shared_snapshot->IsValid()) {
-- shared_snapshot = DartSnapshot::Empty();
-- if (!shared_snapshot) {
-- FML_LOG(ERROR) << "Shared snapshot invalid.";
-- return {};
-- }
-- }
--
- return std::shared_ptr<const DartVMData>(new DartVMData(
- std::move(settings), //
- std::move(vm_snapshot), //
-- std::move(isolate_snapshot), //
-- std::move(shared_snapshot) //
-+ std::move(isolate_snapshot) //
- ));
- }
-
- DartVMData::DartVMData(Settings settings,
- fml::RefPtr<const DartSnapshot> vm_snapshot,
-- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot)
-+ fml::RefPtr<const DartSnapshot> isolate_snapshot)
- : settings_(settings),
- vm_snapshot_(vm_snapshot),
-- isolate_snapshot_(isolate_snapshot),
-- shared_snapshot_(shared_snapshot) {}
-+ isolate_snapshot_(isolate_snapshot) {}
-
- DartVMData::~DartVMData() = default;
-
-@@ -72,8 +60,4 @@ fml::RefPtr<const DartSnapshot> DartVMData::GetIsolateSnapshot() const {
- return isolate_snapshot_;
- }
-
--fml::RefPtr<const DartSnapshot> DartVMData::GetSharedSnapshot() const {
-- return shared_snapshot_;
--}
--
- } // namespace flutter
-diff --git a/runtime/dart_vm_data.h b/runtime/dart_vm_data.h
-index 95c4565e2ef7..0f054bf55f3d 100644
---- a/runtime/dart_vm_data.h
-+++ b/runtime/dart_vm_data.h
-@@ -15,8 +15,7 @@ class DartVMData {
- static std::shared_ptr<const DartVMData> Create(
- Settings settings,
- fml::RefPtr<DartSnapshot> vm_snapshot,
-- fml::RefPtr<DartSnapshot> isolate_snapshot,
-- fml::RefPtr<DartSnapshot> shared_snapshot);
-+ fml::RefPtr<DartSnapshot> isolate_snapshot);
-
- ~DartVMData();
-
-@@ -26,18 +25,14 @@ class DartVMData {
-
- fml::RefPtr<const DartSnapshot> GetIsolateSnapshot() const;
-
-- fml::RefPtr<const DartSnapshot> GetSharedSnapshot() const;
--
- private:
- const Settings settings_;
- const fml::RefPtr<const DartSnapshot> vm_snapshot_;
- const fml::RefPtr<const DartSnapshot> isolate_snapshot_;
-- const fml::RefPtr<const DartSnapshot> shared_snapshot_;
-
- DartVMData(Settings settings,
- fml::RefPtr<const DartSnapshot> vm_snapshot,
-- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot);
-+ fml::RefPtr<const DartSnapshot> isolate_snapshot);
-
- FML_DISALLOW_COPY_AND_ASSIGN(DartVMData);
- };
-diff --git a/runtime/dart_vm_lifecycle.cc b/runtime/dart_vm_lifecycle.cc
-index 717a0546a280..41a3da606abb 100644
---- a/runtime/dart_vm_lifecycle.cc
-+++ b/runtime/dart_vm_lifecycle.cc
-@@ -43,8 +43,7 @@ DartVMRef::~DartVMRef() {
-
- DartVMRef DartVMRef::Create(Settings settings,
- fml::RefPtr<DartSnapshot> vm_snapshot,
-- fml::RefPtr<DartSnapshot> isolate_snapshot,
-- fml::RefPtr<DartSnapshot> shared_snapshot) {
-+ fml::RefPtr<DartSnapshot> isolate_snapshot) {
- std::scoped_lock lifecycle_lock(gVMMutex);
-
- if (!settings.leak_vm) {
-@@ -78,7 +77,6 @@ DartVMRef DartVMRef::Create(Settings settings,
- auto vm = DartVM::Create(std::move(settings), //
- std::move(vm_snapshot), //
- std::move(isolate_snapshot), //
-- std::move(shared_snapshot), //
- isolate_name_server //
- );
-
-diff --git a/runtime/dart_vm_lifecycle.h b/runtime/dart_vm_lifecycle.h
-index 5ce6cf7a5777..d89b6d7cb43d 100644
---- a/runtime/dart_vm_lifecycle.h
-+++ b/runtime/dart_vm_lifecycle.h
-@@ -29,8 +29,7 @@ class DartVMRef {
- FML_WARN_UNUSED_RESULT
- static DartVMRef Create(Settings settings,
- fml::RefPtr<DartSnapshot> vm_snapshot = nullptr,
-- fml::RefPtr<DartSnapshot> isolate_snapshot = nullptr,
-- fml::RefPtr<DartSnapshot> shared_snapshot = nullptr);
-+ fml::RefPtr<DartSnapshot> isolate_snapshot = nullptr);
-
- DartVMRef(DartVMRef&&);
-
-diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc
-index 61415ec4124c..a63843fedf66 100644
---- a/runtime/runtime_controller.cc
-+++ b/runtime/runtime_controller.cc
-@@ -18,7 +18,6 @@ RuntimeController::RuntimeController(
- RuntimeDelegate& p_client,
- DartVM* p_vm,
- fml::RefPtr<const DartSnapshot> p_isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> p_shared_snapshot,
- TaskRunners p_task_runners,
- fml::WeakPtr<IOManager> p_io_manager,
- fml::WeakPtr<ImageDecoder> p_image_decoder,
-@@ -31,7 +30,6 @@ RuntimeController::RuntimeController(
- : RuntimeController(p_client,
- p_vm,
- std::move(p_isolate_snapshot),
-- std::move(p_shared_snapshot),
- std::move(p_task_runners),
- std::move(p_io_manager),
- std::move(p_image_decoder),
-@@ -47,7 +45,6 @@ RuntimeController::RuntimeController(
- RuntimeDelegate& p_client,
- DartVM* p_vm,
- fml::RefPtr<const DartSnapshot> p_isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> p_shared_snapshot,
- TaskRunners p_task_runners,
- fml::WeakPtr<IOManager> p_io_manager,
- fml::WeakPtr<ImageDecoder> p_image_decoder,
-@@ -61,7 +58,6 @@ RuntimeController::RuntimeController(
- : client_(p_client),
- vm_(p_vm),
- isolate_snapshot_(std::move(p_isolate_snapshot)),
-- shared_snapshot_(std::move(p_shared_snapshot)),
- task_runners_(p_task_runners),
- io_manager_(p_io_manager),
- image_decoder_(p_image_decoder),
-@@ -78,7 +74,6 @@ RuntimeController::RuntimeController(
- auto strong_root_isolate =
- DartIsolate::CreateRootIsolate(vm_->GetVMData()->GetSettings(), //
- isolate_snapshot_, //
-- shared_snapshot_, //
- task_runners_, //
- std::make_unique<Window>(this), //
- io_manager_, //
-@@ -139,7 +134,6 @@ std::unique_ptr<RuntimeController> RuntimeController::Clone() const {
- client_, //
- vm_, //
- isolate_snapshot_, //
-- shared_snapshot_, //
- task_runners_, //
- io_manager_, //
- image_decoder_, //
-diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h
-index 665f0e17dbb5..98a87f6f5d09 100644
---- a/runtime/runtime_controller.h
-+++ b/runtime/runtime_controller.h
-@@ -32,7 +32,6 @@ class RuntimeController final : public WindowClient {
- RuntimeDelegate& client,
- DartVM* vm,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- TaskRunners task_runners,
- fml::WeakPtr<IOManager> io_manager,
- fml::WeakPtr<ImageDecoder> iamge_decoder,
-@@ -128,7 +127,6 @@ class RuntimeController final : public WindowClient {
- RuntimeDelegate& client_;
- DartVM* const vm_;
- fml::RefPtr<const DartSnapshot> isolate_snapshot_;
-- fml::RefPtr<const DartSnapshot> shared_snapshot_;
- TaskRunners task_runners_;
- fml::WeakPtr<IOManager> io_manager_;
- fml::WeakPtr<ImageDecoder> image_decoder_;
-@@ -146,7 +144,6 @@ class RuntimeController final : public WindowClient {
- RuntimeDelegate& client,
- DartVM* vm,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- TaskRunners task_runners,
- fml::WeakPtr<IOManager> io_manager,
- fml::WeakPtr<ImageDecoder> image_decoder,
-diff --git a/shell/common/engine.cc b/shell/common/engine.cc
-index fd424a369eeb..7ad3a432a52c 100644
---- a/shell/common/engine.cc
-+++ b/shell/common/engine.cc
-@@ -39,7 +39,6 @@ Engine::Engine(Delegate& delegate,
- const PointerDataDispatcherMaker& dispatcher_maker,
- DartVM& vm,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- TaskRunners task_runners,
- Settings settings,
- std::unique_ptr<Animator> animator,
-@@ -61,7 +60,6 @@ Engine::Engine(Delegate& delegate,
- *this, // runtime delegate
- &vm, // VM
- std::move(isolate_snapshot), // isolate snapshot
-- std::move(shared_snapshot), // shared snapshot
- task_runners_, // task runners
- std::move(io_manager), // io manager
- image_decoder_.GetWeakPtr(), // image decoder
-diff --git a/shell/common/engine.h b/shell/common/engine.h
-index 2e4fd41964bb..dde92dbc6d26 100644
---- a/shell/common/engine.h
-+++ b/shell/common/engine.h
-@@ -249,8 +249,6 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
- /// created when the engine is created. This
- /// requires access to the isolate snapshot
- /// upfront.
-- /// @param[in] shared_snapshot The portion of the isolate snapshot shared
-- /// among multiple isolates.
- // TODO(chinmaygarde): This is probably redundant now that the IO manager is
- // it's own object.
- /// @param[in] task_runners The task runners used by the shell that
-@@ -276,7 +274,6 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
- const PointerDataDispatcherMaker& dispatcher_maker,
- DartVM& vm,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- TaskRunners task_runners,
- Settings settings,
- std::unique_ptr<Animator> animator,
-diff --git a/shell/common/shell.cc b/shell/common/shell.cc
-index bf185a6b3661..fbc2457d56bd 100644
---- a/shell/common/shell.cc
-+++ b/shell/common/shell.cc
-@@ -45,7 +45,6 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
- TaskRunners task_runners,
- Settings settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- Shell::CreateCallback<PlatformView> on_create_platform_view,
- Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
- if (!task_runners.IsValid()) {
-@@ -124,7 +123,6 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
- shell = shell.get(), //
- &dispatcher_maker, //
- isolate_snapshot = std::move(isolate_snapshot), //
-- shared_snapshot = std::move(shared_snapshot), //
- vsync_waiter = std::move(vsync_waiter), //
- &weak_io_manager_future //
- ]() mutable {
-@@ -141,7 +139,6 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
- dispatcher_maker, //
- *shell->GetDartVM(), //
- std::move(isolate_snapshot), //
-- std::move(shared_snapshot), //
- task_runners, //
- shell->GetSettings(), //
- std::move(animator), //
-@@ -227,7 +224,6 @@ std::unique_ptr<Shell> Shell::Create(
- return Shell::Create(std::move(task_runners), //
- std::move(settings), //
- vm_data->GetIsolateSnapshot(), // isolate snapshot
-- DartSnapshot::Empty(), // shared snapshot
- std::move(on_create_platform_view), //
- std::move(on_create_rasterizer), //
- std::move(vm) //
-@@ -238,7 +234,6 @@ std::unique_ptr<Shell> Shell::Create(
- TaskRunners task_runners,
- Settings settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- Shell::CreateCallback<PlatformView> on_create_platform_view,
- Shell::CreateCallback<Rasterizer> on_create_rasterizer,
- DartVMRef vm) {
-@@ -262,7 +257,6 @@ std::unique_ptr<Shell> Shell::Create(
- task_runners = std::move(task_runners), //
- settings, //
- isolate_snapshot = std::move(isolate_snapshot), //
-- shared_snapshot = std::move(shared_snapshot), //
- on_create_platform_view, //
- on_create_rasterizer //
- ]() mutable {
-@@ -270,7 +264,6 @@ std::unique_ptr<Shell> Shell::Create(
- std::move(task_runners), //
- settings, //
- std::move(isolate_snapshot), //
-- std::move(shared_snapshot), //
- on_create_platform_view, //
- on_create_rasterizer //
- );
-diff --git a/shell/common/shell.h b/shell/common/shell.h
-index e4ee6960389a..cc3ed8fdc448 100644
---- a/shell/common/shell.h
-+++ b/shell/common/shell.h
-@@ -139,9 +139,6 @@ class Shell final : public PlatformView::Delegate,
- /// @param[in] isolate_snapshot A custom isolate snapshot. Takes
- /// precedence over any snapshots
- /// specified in the settings.
-- /// @param[in] shared_snapshot A custom shared snapshot. Takes
-- /// precedence over any snapshots
-- /// specified in the settings.
- /// @param[in] on_create_platform_view The callback that must return a
- /// platform view. This will be called on
- /// the platform task runner before this
-@@ -164,7 +161,6 @@ class Shell final : public PlatformView::Delegate,
- TaskRunners task_runners,
- Settings settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- CreateCallback<PlatformView> on_create_platform_view,
- CreateCallback<Rasterizer> on_create_rasterizer,
- DartVMRef vm);
-@@ -375,7 +371,6 @@ class Shell final : public PlatformView::Delegate,
- TaskRunners task_runners,
- Settings settings,
- fml::RefPtr<const DartSnapshot> isolate_snapshot,
-- fml::RefPtr<const DartSnapshot> shared_snapshot,
- Shell::CreateCallback<PlatformView> on_create_platform_view,
- Shell::CreateCallback<Rasterizer> on_create_rasterizer);
-
-diff --git a/shell/platform/fuchsia/dart_runner/dart_component_controller.cc b/shell/platform/fuchsia/dart_runner/dart_component_controller.cc
-index 37cef7bce6f7..e5bd774fc4e3 100644
---- a/shell/platform/fuchsia/dart_runner/dart_component_controller.cc
-+++ b/shell/platform/fuchsia/dart_runner/dart_component_controller.cc
-@@ -314,8 +314,7 @@ bool DartComponentController::CreateIsolate(
-
- isolate_ = Dart_CreateIsolateGroup(
- url_.c_str(), label_.c_str(), isolate_snapshot_data,
-- isolate_snapshot_instructions, nullptr /* shared_snapshot_data */,
-- nullptr /* shared_snapshot_instructions */, nullptr /* flags */, state,
-+ isolate_snapshot_instructions, nullptr /* flags */, state,
- state, &error);
- if (!isolate_) {
- FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", error);
-diff --git a/shell/platform/fuchsia/dart_runner/service_isolate.cc b/shell/platform/fuchsia/dart_runner/service_isolate.cc
-index d22c4df286b6..40719ab81c94 100644
---- a/shell/platform/fuchsia/dart_runner/service_isolate.cc
-+++ b/shell/platform/fuchsia/dart_runner/service_isolate.cc
-@@ -107,8 +107,7 @@ Dart_Isolate CreateServiceIsolate(const char* uri,
- Dart_Isolate isolate = Dart_CreateIsolateGroup(
- uri, DART_VM_SERVICE_ISOLATE_NAME, mapped_isolate_snapshot_data.address(),
- mapped_isolate_snapshot_instructions.address(),
-- nullptr /* shared_snapshot_data */,
-- nullptr /* shared_snapshot_instructions */, nullptr /* flags */, state,
-+ nullptr /* flags */, state,
- state, error);
- if (!isolate) {
- FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", *error);
-diff --git a/shell/platform/fuchsia/flutter/engine.cc b/shell/platform/fuchsia/flutter/engine.cc
-index 75dbf497b8d8..d002049996df 100644
---- a/shell/platform/fuchsia/flutter/engine.cc
-+++ b/shell/platform/fuchsia/flutter/engine.cc
-@@ -227,7 +227,6 @@ Engine::Engine(Delegate& delegate,
- task_runners, // host task runners
- settings_, // shell launch settings
- std::move(isolate_snapshot), // isolate snapshot
-- flutter::DartSnapshot::Empty(), // shared snapshot
- on_create_platform_view, // platform view create callback
- on_create_rasterizer, // rasterizer create callback
- std::move(vm) // vm reference
diff --git a/tools/patches/flutter-engine/b48c8b1d1c9050734c0491f4e36b7d61ef005233.patch b/tools/patches/flutter-engine/b48c8b1d1c9050734c0491f4e36b7d61ef005233.patch
deleted file mode 100644
index 1e357de..0000000
--- a/tools/patches/flutter-engine/b48c8b1d1c9050734c0491f4e36b7d61ef005233.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/frontend_server/lib/server.dart b/frontend_server/lib/server.dart
-index 44a3d69b9..9620a5de0 100644
---- a/frontend_server/lib/server.dart
-+++ b/frontend_server/lib/server.dart
-@@ -85,11 +85,6 @@ Future<int> starter(
- StringSink output,
- }) async {
- ArgResults options;
-- frontend.argParser
-- ..addFlag('track-widget-creation',
-- help: 'Run a kernel transformer to track creation locations for widgets.',
-- defaultsTo: false);
--
- try {
- options = frontend.argParser.parse(args);
- } catch (error) {
diff --git a/tools/patches/flutter-engine/cb80ea7ba9124fd42a34c1d021232113e20d21b1.patch b/tools/patches/flutter-engine/cb80ea7ba9124fd42a34c1d021232113e20d21b1.patch
deleted file mode 100644
index 6151279..0000000
--- a/tools/patches/flutter-engine/cb80ea7ba9124fd42a34c1d021232113e20d21b1.patch
+++ /dev/null
@@ -1,1305 +0,0 @@
-diff --git a/lib/snapshot/libraries.json b/lib/snapshot/libraries.json
-index b6ffcef58..c4783158b 100644
---- a/lib/snapshot/libraries.json
-+++ b/lib/snapshot/libraries.json
-@@ -4,69 +4,69 @@
- "flutter": {
- "libraries": {
- "_builtin": {
-- "uri": "../../../third_party/dart/runtime/bin/builtin.dart"
-+ "uri": "../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
- },
- "core": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/core_patch.dart",
-- "../../../third_party/dart/runtime/lib/array.dart",
-- "../../../third_party/dart/runtime/lib/array_patch.dart",
-- "../../../third_party/dart/runtime/lib/bigint_patch.dart",
-- "../../../third_party/dart/runtime/lib/bool_patch.dart",
-- "../../../third_party/dart/runtime/lib/date_patch.dart",
-- "../../../third_party/dart/runtime/lib/double.dart",
-- "../../../third_party/dart/runtime/lib/double_patch.dart",
-- "../../../third_party/dart/runtime/lib/errors_patch.dart",
-- "../../../third_party/dart/runtime/lib/expando_patch.dart",
-- "../../../third_party/dart/runtime/lib/function.dart",
-- "../../../third_party/dart/runtime/lib/function_patch.dart",
-- "../../../third_party/dart/runtime/lib/growable_array.dart",
-- "../../../third_party/dart/runtime/lib/identical_patch.dart",
-- "../../../third_party/dart/runtime/lib/immutable_map.dart",
-- "../../../third_party/dart/runtime/lib/integers.dart",
-- "../../../third_party/dart/runtime/lib/integers_patch.dart",
-- "../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
-- "../../../third_party/dart/runtime/lib/lib_prefix.dart",
-- "../../../third_party/dart/runtime/lib/map_patch.dart",
-- "../../../third_party/dart/runtime/lib/null_patch.dart",
-- "../../../third_party/dart/runtime/lib/object_patch.dart",
-- "../../../third_party/dart/runtime/lib/regexp_patch.dart",
-- "../../../third_party/dart/runtime/lib/stacktrace.dart",
-- "../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
-- "../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
-- "../../../third_party/dart/runtime/lib/string_patch.dart",
-- "../../../third_party/dart/runtime/lib/type_patch.dart",
-- "../../../third_party/dart/runtime/lib/uri_patch.dart",
-- "../../../third_party/dart/runtime/lib/weak_property.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/core/core.dart"
- },
- "async": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/async_patch.dart",
-- "../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
-- "../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
-- "../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/async/async.dart"
- },
- "collection": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/collection_patch.dart",
-- "../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/collection/collection.dart"
- },
- "ffi": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
-- "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
-- "../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- },
- "typed_data": {
-- "patches": "../../../third_party/dart/runtime/lib/typed_data_patch.dart",
-+ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
- "uri": "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
- },
- "nativewrappers": {
-@@ -74,24 +74,24 @@
- },
- "mirrors": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/mirrors_patch.dart",
-- "../../../third_party/dart/runtime/lib/mirrors_impl.dart",
-- "../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- },
- "developer": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/developer.dart",
-- "../../../third_party/dart/runtime/lib/profiler.dart",
-- "../../../third_party/dart/runtime/lib/timeline.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/developer/developer.dart"
- },
- "isolate": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/isolate_patch.dart",
-- "../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- },
-@@ -100,48 +100,48 @@
- },
- "wasm": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- },
- "io": {
- "patches": [
-- "../../../third_party/dart/runtime/bin/common_patch.dart",
-- "../../../third_party/dart/runtime/bin/directory_patch.dart",
-- "../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
-- "../../../third_party/dart/runtime/bin/file_patch.dart",
-- "../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
-- "../../../third_party/dart/runtime/bin/filter_patch.dart",
-- "../../../third_party/dart/runtime/bin/io_service_patch.dart",
-- "../../../third_party/dart/runtime/bin/namespace_patch.dart",
-- "../../../third_party/dart/runtime/bin/platform_patch.dart",
-- "../../../third_party/dart/runtime/bin/process_patch.dart",
-- "../../../third_party/dart/runtime/bin/socket_patch.dart",
-- "../../../third_party/dart/runtime/bin/stdio_patch.dart",
-- "../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
-- "../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/io/io.dart"
- },
- "_internal": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/internal_patch.dart",
-- "../../../third_party/dart/runtime/lib/class_id_fasta.dart",
-- "../../../third_party/dart/runtime/lib/print_patch.dart",
-- "../../../third_party/dart/runtime/lib/symbol_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
- "../../../third_party/dart/sdk/lib/internal/patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/internal/internal.dart"
- },
- "convert": {
-- "patches": "../../../third_party/dart/runtime/lib/convert_patch.dart",
-+ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
- "uri": "../../../third_party/dart/sdk/lib/convert/convert.dart"
- },
- "profiler": {
- "uri": "../../../third_party/dart/sdk/lib/profiler/profiler.dart"
- },
- "math": {
-- "patches": "../../../third_party/dart/runtime/lib/math_patch.dart",
-+ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
- "uri": "../../../third_party/dart/sdk/lib/math/math.dart"
- },
- "_http": {
-diff --git a/lib/snapshot/libraries.yaml b/lib/snapshot/libraries.yaml
-index 392e0500b..7269819f7 100644
---- a/lib/snapshot/libraries.yaml
-+++ b/lib/snapshot/libraries.yaml
-@@ -14,87 +14,87 @@
- flutter:
- libraries:
- _builtin:
-- uri: "../../../third_party/dart/runtime/bin/builtin.dart"
-+ uri: "../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
-
- _internal:
- uri: "../../../third_party/dart/sdk/lib/internal/internal.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/internal_patch.dart"
-- - "../../../third_party/dart/runtime/lib/class_id_fasta.dart"
-- - "../../../third_party/dart/runtime/lib/print_patch.dart"
-- - "../../../third_party/dart/runtime/lib/symbol_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
- - "../../../third_party/dart/sdk/lib/internal/patch.dart"
-
- async:
- uri: "../../../third_party/dart/sdk/lib/async/async.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/async_patch.dart"
-- - "../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
-- - "../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
-- - "../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
-
- collection:
- uri: "../../../third_party/dart/sdk/lib/collection/collection.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/collection_patch.dart"
-- - "../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
-
- convert:
- uri: "../../../third_party/dart/sdk/lib/convert/convert.dart"
-- patches: "../../../third_party/dart/runtime/lib/convert_patch.dart"
-+ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
-
- core:
- uri: "../../../third_party/dart/sdk/lib/core/core.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/core_patch.dart"
-- - "../../../third_party/dart/runtime/lib/array.dart"
-- - "../../../third_party/dart/runtime/lib/array_patch.dart"
-- - "../../../third_party/dart/runtime/lib/bigint_patch.dart"
-- - "../../../third_party/dart/runtime/lib/bool_patch.dart"
-- - "../../../third_party/dart/runtime/lib/date_patch.dart"
-- - "../../../third_party/dart/runtime/lib/double.dart"
-- - "../../../third_party/dart/runtime/lib/double_patch.dart"
-- - "../../../third_party/dart/runtime/lib/errors_patch.dart"
-- - "../../../third_party/dart/runtime/lib/expando_patch.dart"
-- - "../../../third_party/dart/runtime/lib/function.dart"
-- - "../../../third_party/dart/runtime/lib/function_patch.dart"
-- - "../../../third_party/dart/runtime/lib/growable_array.dart"
-- - "../../../third_party/dart/runtime/lib/identical_patch.dart"
-- - "../../../third_party/dart/runtime/lib/immutable_map.dart"
-- - "../../../third_party/dart/runtime/lib/integers.dart"
-- - "../../../third_party/dart/runtime/lib/integers_patch.dart"
-- - "../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
-- - "../../../third_party/dart/runtime/lib/lib_prefix.dart"
-- - "../../../third_party/dart/runtime/lib/map_patch.dart"
-- - "../../../third_party/dart/runtime/lib/null_patch.dart"
-- - "../../../third_party/dart/runtime/lib/object_patch.dart"
-- - "../../../third_party/dart/runtime/lib/regexp_patch.dart"
-- - "../../../third_party/dart/runtime/lib/stacktrace.dart"
-- - "../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
-- - "../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
-- - "../../../third_party/dart/runtime/lib/string_patch.dart"
-- - "../../../third_party/dart/runtime/lib/type_patch.dart"
-- - "../../../third_party/dart/runtime/lib/uri_patch.dart"
-- - "../../../third_party/dart/runtime/lib/weak_property.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
-
- developer:
- uri: "../../../third_party/dart/sdk/lib/developer/developer.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/developer.dart"
-- - "../../../third_party/dart/runtime/lib/profiler.dart"
-- - "../../../third_party/dart/runtime/lib/timeline.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
-
- ffi:
- uri: "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
-- - "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
-- - "../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
-
- wasm:
- uri: "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
-
- _http:
- uri: "../../../third_party/dart/sdk/lib/_http/http.dart"
-@@ -102,37 +102,37 @@ flutter:
- io:
- uri: "../../../third_party/dart/sdk/lib/io/io.dart"
- patches:
-- - "../../../third_party/dart/runtime/bin/common_patch.dart"
-- - "../../../third_party/dart/runtime/bin/directory_patch.dart"
-- - "../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
-- - "../../../third_party/dart/runtime/bin/file_patch.dart"
-- - "../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
-- - "../../../third_party/dart/runtime/bin/filter_patch.dart"
-- - "../../../third_party/dart/runtime/bin/io_service_patch.dart"
-- - "../../../third_party/dart/runtime/bin/namespace_patch.dart"
-- - "../../../third_party/dart/runtime/bin/platform_patch.dart"
-- - "../../../third_party/dart/runtime/bin/process_patch.dart"
-- - "../../../third_party/dart/runtime/bin/socket_patch.dart"
-- - "../../../third_party/dart/runtime/bin/stdio_patch.dart"
-- - "../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
-- - "../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
-
- isolate:
- uri: "../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/isolate_patch.dart"
-- - "../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
-
- math:
- uri: "../../../third_party/dart/sdk/lib/math/math.dart"
-- patches: "../../../third_party/dart/runtime/lib/math_patch.dart"
-+ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
-
- mirrors:
- uri: "../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/mirrors_patch.dart"
-- - "../../../third_party/dart/runtime/lib/mirrors_impl.dart"
-- - "../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
-
- nativewrappers:
- uri: "../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
-@@ -142,7 +142,7 @@ flutter:
-
- typed_data:
- uri: "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
-- patches: "../../../third_party/dart/runtime/lib/typed_data_patch.dart"
-+ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
-
- ui:
- uri: "../../lib/ui/ui.dart"
-diff --git a/shell/platform/fuchsia/dart_runner/kernel/libraries.json b/shell/platform/fuchsia/dart_runner/kernel/libraries.json
-index 0abe212e6..24c664852 100644
---- a/shell/platform/fuchsia/dart_runner/kernel/libraries.json
-+++ b/shell/platform/fuchsia/dart_runner/kernel/libraries.json
-@@ -1,43 +1,43 @@
- {
- "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
-- "comment:1": "Instead modify 'shell/platform/fuchsia/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
-+ "comment:1": "Instead modify 'flutter/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
- "dart_runner": {
- "libraries": {
- "_builtin": {
-- "uri": "../../../../../../third_party/dart/runtime/bin/builtin.dart"
-+ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
- },
- "core": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/core_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/array.dart",
-- "../../../../../../third_party/dart/runtime/lib/array_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/bool_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/date_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/double.dart",
-- "../../../../../../third_party/dart/runtime/lib/double_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/errors_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/expando_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/function.dart",
-- "../../../../../../third_party/dart/runtime/lib/function_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/growable_array.dart",
-- "../../../../../../third_party/dart/runtime/lib/identical_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/immutable_map.dart",
-- "../../../../../../third_party/dart/runtime/lib/integers.dart",
-- "../../../../../../third_party/dart/runtime/lib/integers_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart",
-- "../../../../../../third_party/dart/runtime/lib/map_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/null_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/object_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/stacktrace.dart",
-- "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/string_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/type_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/uri_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/core/core.dart"
- },
-@@ -46,30 +46,30 @@
- },
- "async": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/async_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/async/async.dart"
- },
- "collection": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/collection_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
- },
- "ffi": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- },
- "typed_data": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
- },
- "nativewrappers": {
-@@ -77,24 +77,24 @@
- },
- "mirrors": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
-- "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- },
- "developer": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/developer.dart",
-- "../../../../../../third_party/dart/runtime/lib/profiler.dart",
-- "../../../../../../third_party/dart/runtime/lib/timeline.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
- },
- "isolate": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- },
-@@ -103,48 +103,48 @@
- },
- "wasm": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- },
- "io": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/bin/common_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/directory_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/file_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/filter_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/platform_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/process_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/socket_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/io/io.dart"
- },
- "_internal": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/internal_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
-- "../../../../../../third_party/dart/runtime/lib/print_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
- "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
- },
- "convert": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/convert_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
- },
- "profiler": {
- "uri": "../../../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
- },
- "math": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/math_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/math/math.dart"
- },
- "_http": {
-diff --git a/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml b/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
-index cab901e60..5e1f638cd 100644
---- a/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
-+++ b/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
-@@ -14,87 +14,87 @@
- dart_runner:
- libraries:
- _builtin:
-- uri: "../../../../../../third_party/dart/runtime/bin/builtin.dart"
-+ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
-
- _internal:
- uri: "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/internal_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
-- - "../../../../../../third_party/dart/runtime/lib/print_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
- - "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
-
- async:
- uri: "../../../../../../third_party/dart/sdk/lib/async/async.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/async_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
-
- collection:
- uri: "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/collection_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
-
- convert:
- uri: "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/convert_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
-
- core:
- uri: "../../../../../../third_party/dart/sdk/lib/core/core.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/core_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/array.dart"
-- - "../../../../../../third_party/dart/runtime/lib/array_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/bool_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/date_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/double.dart"
-- - "../../../../../../third_party/dart/runtime/lib/double_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/errors_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/expando_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/function.dart"
-- - "../../../../../../third_party/dart/runtime/lib/function_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/growable_array.dart"
-- - "../../../../../../third_party/dart/runtime/lib/identical_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/immutable_map.dart"
-- - "../../../../../../third_party/dart/runtime/lib/integers.dart"
-- - "../../../../../../third_party/dart/runtime/lib/integers_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart"
-- - "../../../../../../third_party/dart/runtime/lib/map_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/null_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/object_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/stacktrace.dart"
-- - "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/string_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/type_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/uri_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
-
- developer:
- uri: "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/developer.dart"
-- - "../../../../../../third_party/dart/runtime/lib/profiler.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timeline.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
-
- ffi:
- uri: "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
-
- wasm:
- uri: "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
-
- _http:
- uri: "../../../../../../third_party/dart/sdk/lib/_http/http.dart"
-@@ -102,37 +102,37 @@ dart_runner:
- io:
- uri: "../../../../../../third_party/dart/sdk/lib/io/io.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/bin/common_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/directory_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/file_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/filter_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/platform_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/process_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/socket_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
-
- isolate:
- uri: "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
-
- math:
- uri: "../../../../../../third_party/dart/sdk/lib/math/math.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/math_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
-
- mirrors:
- uri: "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
-- - "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
-
- nativewrappers:
- uri: "../../../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
-@@ -142,7 +142,7 @@ dart_runner:
-
- typed_data:
- uri: "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
-
- fuchsia.builtin:
- uri: "../../../../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart"
-diff --git a/shell/platform/fuchsia/flutter/kernel/libraries.json b/shell/platform/fuchsia/flutter/kernel/libraries.json
-index 5a4602d8c..a8436200f 100644
---- a/shell/platform/fuchsia/flutter/kernel/libraries.json
-+++ b/shell/platform/fuchsia/flutter/kernel/libraries.json
-@@ -1,43 +1,43 @@
- {
- "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
-- "comment:1": "Instead modify 'shell/platform/fuchsia/flutter/kernel/libraries.yaml' and follow the instructions therein.",
-+ "comment:1": "Instead modify 'flutter/shell/platform/fuchsia/flutter/kernel/libraries.yaml' and follow the instructions therein.",
- "flutter_runner": {
- "libraries": {
- "_builtin": {
-- "uri": "../../../../../../third_party/dart/runtime/bin/builtin.dart"
-+ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
- },
- "core": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/core_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/array.dart",
-- "../../../../../../third_party/dart/runtime/lib/array_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/bool_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/date_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/double.dart",
-- "../../../../../../third_party/dart/runtime/lib/double_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/errors_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/expando_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/function.dart",
-- "../../../../../../third_party/dart/runtime/lib/function_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/growable_array.dart",
-- "../../../../../../third_party/dart/runtime/lib/identical_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/immutable_map.dart",
-- "../../../../../../third_party/dart/runtime/lib/integers.dart",
-- "../../../../../../third_party/dart/runtime/lib/integers_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart",
-- "../../../../../../third_party/dart/runtime/lib/map_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/null_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/object_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/stacktrace.dart",
-- "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/string_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/type_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/uri_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/core/core.dart"
- },
-@@ -46,30 +46,30 @@
- },
- "async": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/async_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/async/async.dart"
- },
- "collection": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/collection_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
- },
- "ffi": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- },
- "typed_data": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
- },
- "nativewrappers": {
-@@ -77,24 +77,24 @@
- },
- "mirrors": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
-- "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- },
- "developer": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/developer.dart",
-- "../../../../../../third_party/dart/runtime/lib/profiler.dart",
-- "../../../../../../third_party/dart/runtime/lib/timeline.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
- },
- "isolate": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- },
-@@ -103,48 +103,48 @@
- },
- "wasm": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- },
- "io": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/bin/common_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/directory_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/file_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/filter_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/platform_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/process_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/socket_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/io/io.dart"
- },
- "_internal": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/internal_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
-- "../../../../../../third_party/dart/runtime/lib/print_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
- "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
- },
- "convert": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/convert_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
- },
- "profiler": {
- "uri": "../../../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
- },
- "math": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/math_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/math/math.dart"
- },
- "_http": {
-@@ -160,7 +160,7 @@
- "uri": "../../../../../../flutter/lib/ui/ui.dart"
- },
- "vmservice_io": {
-- "uri": "../../../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
-+ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/vmservice/vmservice_io.dart"
- }
- }
- }
-diff --git a/shell/platform/fuchsia/flutter/kernel/libraries.yaml b/shell/platform/fuchsia/flutter/kernel/libraries.yaml
-index f8385ca29..05b7f4f9f 100644
---- a/shell/platform/fuchsia/flutter/kernel/libraries.yaml
-+++ b/shell/platform/fuchsia/flutter/kernel/libraries.yaml
-@@ -14,87 +14,87 @@
- flutter_runner:
- libraries:
- _builtin:
-- uri: "../../../../../../third_party/dart/runtime/bin/builtin.dart"
-+ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
-
- _internal:
- uri: "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/internal_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
-- - "../../../../../../third_party/dart/runtime/lib/print_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
- - "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
-
- async:
- uri: "../../../../../../third_party/dart/sdk/lib/async/async.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/async_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
-
- collection:
- uri: "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/collection_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
-
- convert:
- uri: "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/convert_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
-
- core:
- uri: "../../../../../../third_party/dart/sdk/lib/core/core.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/core_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/array.dart"
-- - "../../../../../../third_party/dart/runtime/lib/array_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/bool_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/date_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/double.dart"
-- - "../../../../../../third_party/dart/runtime/lib/double_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/errors_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/expando_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/function.dart"
-- - "../../../../../../third_party/dart/runtime/lib/function_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/growable_array.dart"
-- - "../../../../../../third_party/dart/runtime/lib/identical_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/immutable_map.dart"
-- - "../../../../../../third_party/dart/runtime/lib/integers.dart"
-- - "../../../../../../third_party/dart/runtime/lib/integers_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart"
-- - "../../../../../../third_party/dart/runtime/lib/map_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/null_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/object_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/stacktrace.dart"
-- - "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/string_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/type_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/uri_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
-
- developer:
- uri: "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/developer.dart"
-- - "../../../../../../third_party/dart/runtime/lib/profiler.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timeline.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
-
- ffi:
- uri: "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
-
- wasm:
- uri: "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
-
- _http:
- uri: "../../../../../../third_party/dart/sdk/lib/_http/http.dart"
-@@ -102,37 +102,37 @@ flutter_runner:
- io:
- uri: "../../../../../../third_party/dart/sdk/lib/io/io.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/bin/common_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/directory_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/file_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/filter_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/platform_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/process_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/socket_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
-
- isolate:
- uri: "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
-
- math:
- uri: "../../../../../../third_party/dart/sdk/lib/math/math.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/math_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
-
- mirrors:
- uri: "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
-- - "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
-
- nativewrappers:
- uri: "../../../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
-@@ -142,7 +142,7 @@ flutter_runner:
-
- typed_data:
- uri: "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
-
- fuchsia.builtin:
- uri: "../../../../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart"
-@@ -160,4 +160,4 @@ flutter_runner:
- uri: "../../../../../../third_party/dart/sdk/lib/vmservice/vmservice.dart"
-
- vmservice_io:
-- uri: "../../../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
-+ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/vmservice/vmservice_io.dart"
diff --git a/tools/patches/flutter-engine/e7e45599cb1a74ff88d7d00a33f25029e42df757.patch b/tools/patches/flutter-engine/e7e45599cb1a74ff88d7d00a33f25029e42df757.patch
new file mode 100644
index 0000000..2ae1b31
--- /dev/null
+++ b/tools/patches/flutter-engine/e7e45599cb1a74ff88d7d00a33f25029e42df757.patch
@@ -0,0 +1,32 @@
+diff --git a/third_party/tonic/dart_persistent_value.cc b/third_party/tonic/dart_persistent_value.cc
+index 9ed6f70f3532..3bc46505d31f 100644
+--- a/third_party/tonic/dart_persistent_value.cc
++++ b/third_party/tonic/dart_persistent_value.cc
+@@ -43,8 +43,12 @@ void DartPersistentValue::Clear() {
+ return;
+ }
+
+- DartIsolateScope scope(dart_state->isolate());
+- Dart_DeletePersistentHandle(value_);
++ if (Dart_CurrentIsolateGroup()) {
++ Dart_DeletePersistentHandle(value_);
++ } else {
++ DartIsolateScope scope(dart_state->isolate());
++ Dart_DeletePersistentHandle(value_);
++ }
+ dart_state_.reset();
+ value_ = nullptr;
+ }
+diff --git a/third_party/tonic/dart_wrappable.cc b/third_party/tonic/dart_wrappable.cc
+index 42c8fff2805b..89064ac8eef7 100644
+--- a/third_party/tonic/dart_wrappable.cc
++++ b/third_party/tonic/dart_wrappable.cc
+@@ -37,7 +37,7 @@ void DartWrappable::ClearDartWrapper() {
+ TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(wrapper, kPeerIndex, 0)));
+ TONIC_CHECK(
+ !LogIfError(Dart_SetNativeInstanceField(wrapper, kWrapperInfoIndex, 0)));
+- Dart_DeleteWeakPersistentHandle(Dart_CurrentIsolate(), dart_wrapper_);
++ Dart_DeleteWeakPersistentHandle(dart_wrapper_);
+ dart_wrapper_ = nullptr;
+ this->ReleaseDartWrappableReference();
+ }
diff --git a/tools/patches/flutter-engine/ea969c358e24f71b865d5f720c0c1c8456a53bad.patch b/tools/patches/flutter-engine/ea969c358e24f71b865d5f720c0c1c8456a53bad.patch
deleted file mode 100644
index 6151279..0000000
--- a/tools/patches/flutter-engine/ea969c358e24f71b865d5f720c0c1c8456a53bad.patch
+++ /dev/null
@@ -1,1305 +0,0 @@
-diff --git a/lib/snapshot/libraries.json b/lib/snapshot/libraries.json
-index b6ffcef58..c4783158b 100644
---- a/lib/snapshot/libraries.json
-+++ b/lib/snapshot/libraries.json
-@@ -4,69 +4,69 @@
- "flutter": {
- "libraries": {
- "_builtin": {
-- "uri": "../../../third_party/dart/runtime/bin/builtin.dart"
-+ "uri": "../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
- },
- "core": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/core_patch.dart",
-- "../../../third_party/dart/runtime/lib/array.dart",
-- "../../../third_party/dart/runtime/lib/array_patch.dart",
-- "../../../third_party/dart/runtime/lib/bigint_patch.dart",
-- "../../../third_party/dart/runtime/lib/bool_patch.dart",
-- "../../../third_party/dart/runtime/lib/date_patch.dart",
-- "../../../third_party/dart/runtime/lib/double.dart",
-- "../../../third_party/dart/runtime/lib/double_patch.dart",
-- "../../../third_party/dart/runtime/lib/errors_patch.dart",
-- "../../../third_party/dart/runtime/lib/expando_patch.dart",
-- "../../../third_party/dart/runtime/lib/function.dart",
-- "../../../third_party/dart/runtime/lib/function_patch.dart",
-- "../../../third_party/dart/runtime/lib/growable_array.dart",
-- "../../../third_party/dart/runtime/lib/identical_patch.dart",
-- "../../../third_party/dart/runtime/lib/immutable_map.dart",
-- "../../../third_party/dart/runtime/lib/integers.dart",
-- "../../../third_party/dart/runtime/lib/integers_patch.dart",
-- "../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
-- "../../../third_party/dart/runtime/lib/lib_prefix.dart",
-- "../../../third_party/dart/runtime/lib/map_patch.dart",
-- "../../../third_party/dart/runtime/lib/null_patch.dart",
-- "../../../third_party/dart/runtime/lib/object_patch.dart",
-- "../../../third_party/dart/runtime/lib/regexp_patch.dart",
-- "../../../third_party/dart/runtime/lib/stacktrace.dart",
-- "../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
-- "../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
-- "../../../third_party/dart/runtime/lib/string_patch.dart",
-- "../../../third_party/dart/runtime/lib/type_patch.dart",
-- "../../../third_party/dart/runtime/lib/uri_patch.dart",
-- "../../../third_party/dart/runtime/lib/weak_property.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/core/core.dart"
- },
- "async": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/async_patch.dart",
-- "../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
-- "../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
-- "../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/async/async.dart"
- },
- "collection": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/collection_patch.dart",
-- "../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/collection/collection.dart"
- },
- "ffi": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
-- "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
-- "../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- },
- "typed_data": {
-- "patches": "../../../third_party/dart/runtime/lib/typed_data_patch.dart",
-+ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
- "uri": "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
- },
- "nativewrappers": {
-@@ -74,24 +74,24 @@
- },
- "mirrors": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/mirrors_patch.dart",
-- "../../../third_party/dart/runtime/lib/mirrors_impl.dart",
-- "../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- },
- "developer": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/developer.dart",
-- "../../../third_party/dart/runtime/lib/profiler.dart",
-- "../../../third_party/dart/runtime/lib/timeline.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/developer/developer.dart"
- },
- "isolate": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/isolate_patch.dart",
-- "../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- },
-@@ -100,48 +100,48 @@
- },
- "wasm": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- },
- "io": {
- "patches": [
-- "../../../third_party/dart/runtime/bin/common_patch.dart",
-- "../../../third_party/dart/runtime/bin/directory_patch.dart",
-- "../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
-- "../../../third_party/dart/runtime/bin/file_patch.dart",
-- "../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
-- "../../../third_party/dart/runtime/bin/filter_patch.dart",
-- "../../../third_party/dart/runtime/bin/io_service_patch.dart",
-- "../../../third_party/dart/runtime/bin/namespace_patch.dart",
-- "../../../third_party/dart/runtime/bin/platform_patch.dart",
-- "../../../third_party/dart/runtime/bin/process_patch.dart",
-- "../../../third_party/dart/runtime/bin/socket_patch.dart",
-- "../../../third_party/dart/runtime/bin/stdio_patch.dart",
-- "../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
-- "../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/io/io.dart"
- },
- "_internal": {
- "patches": [
-- "../../../third_party/dart/runtime/lib/internal_patch.dart",
-- "../../../third_party/dart/runtime/lib/class_id_fasta.dart",
-- "../../../third_party/dart/runtime/lib/print_patch.dart",
-- "../../../third_party/dart/runtime/lib/symbol_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
-+ "../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
- "../../../third_party/dart/sdk/lib/internal/patch.dart"
- ],
- "uri": "../../../third_party/dart/sdk/lib/internal/internal.dart"
- },
- "convert": {
-- "patches": "../../../third_party/dart/runtime/lib/convert_patch.dart",
-+ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
- "uri": "../../../third_party/dart/sdk/lib/convert/convert.dart"
- },
- "profiler": {
- "uri": "../../../third_party/dart/sdk/lib/profiler/profiler.dart"
- },
- "math": {
-- "patches": "../../../third_party/dart/runtime/lib/math_patch.dart",
-+ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
- "uri": "../../../third_party/dart/sdk/lib/math/math.dart"
- },
- "_http": {
-diff --git a/lib/snapshot/libraries.yaml b/lib/snapshot/libraries.yaml
-index 392e0500b..7269819f7 100644
---- a/lib/snapshot/libraries.yaml
-+++ b/lib/snapshot/libraries.yaml
-@@ -14,87 +14,87 @@
- flutter:
- libraries:
- _builtin:
-- uri: "../../../third_party/dart/runtime/bin/builtin.dart"
-+ uri: "../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
-
- _internal:
- uri: "../../../third_party/dart/sdk/lib/internal/internal.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/internal_patch.dart"
-- - "../../../third_party/dart/runtime/lib/class_id_fasta.dart"
-- - "../../../third_party/dart/runtime/lib/print_patch.dart"
-- - "../../../third_party/dart/runtime/lib/symbol_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
- - "../../../third_party/dart/sdk/lib/internal/patch.dart"
-
- async:
- uri: "../../../third_party/dart/sdk/lib/async/async.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/async_patch.dart"
-- - "../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
-- - "../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
-- - "../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
-
- collection:
- uri: "../../../third_party/dart/sdk/lib/collection/collection.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/collection_patch.dart"
-- - "../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
-
- convert:
- uri: "../../../third_party/dart/sdk/lib/convert/convert.dart"
-- patches: "../../../third_party/dart/runtime/lib/convert_patch.dart"
-+ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
-
- core:
- uri: "../../../third_party/dart/sdk/lib/core/core.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/core_patch.dart"
-- - "../../../third_party/dart/runtime/lib/array.dart"
-- - "../../../third_party/dart/runtime/lib/array_patch.dart"
-- - "../../../third_party/dart/runtime/lib/bigint_patch.dart"
-- - "../../../third_party/dart/runtime/lib/bool_patch.dart"
-- - "../../../third_party/dart/runtime/lib/date_patch.dart"
-- - "../../../third_party/dart/runtime/lib/double.dart"
-- - "../../../third_party/dart/runtime/lib/double_patch.dart"
-- - "../../../third_party/dart/runtime/lib/errors_patch.dart"
-- - "../../../third_party/dart/runtime/lib/expando_patch.dart"
-- - "../../../third_party/dart/runtime/lib/function.dart"
-- - "../../../third_party/dart/runtime/lib/function_patch.dart"
-- - "../../../third_party/dart/runtime/lib/growable_array.dart"
-- - "../../../third_party/dart/runtime/lib/identical_patch.dart"
-- - "../../../third_party/dart/runtime/lib/immutable_map.dart"
-- - "../../../third_party/dart/runtime/lib/integers.dart"
-- - "../../../third_party/dart/runtime/lib/integers_patch.dart"
-- - "../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
-- - "../../../third_party/dart/runtime/lib/lib_prefix.dart"
-- - "../../../third_party/dart/runtime/lib/map_patch.dart"
-- - "../../../third_party/dart/runtime/lib/null_patch.dart"
-- - "../../../third_party/dart/runtime/lib/object_patch.dart"
-- - "../../../third_party/dart/runtime/lib/regexp_patch.dart"
-- - "../../../third_party/dart/runtime/lib/stacktrace.dart"
-- - "../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
-- - "../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
-- - "../../../third_party/dart/runtime/lib/string_patch.dart"
-- - "../../../third_party/dart/runtime/lib/type_patch.dart"
-- - "../../../third_party/dart/runtime/lib/uri_patch.dart"
-- - "../../../third_party/dart/runtime/lib/weak_property.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
-
- developer:
- uri: "../../../third_party/dart/sdk/lib/developer/developer.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/developer.dart"
-- - "../../../third_party/dart/runtime/lib/profiler.dart"
-- - "../../../third_party/dart/runtime/lib/timeline.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
-
- ffi:
- uri: "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
-- - "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
-- - "../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
-
- wasm:
- uri: "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
-
- _http:
- uri: "../../../third_party/dart/sdk/lib/_http/http.dart"
-@@ -102,37 +102,37 @@ flutter:
- io:
- uri: "../../../third_party/dart/sdk/lib/io/io.dart"
- patches:
-- - "../../../third_party/dart/runtime/bin/common_patch.dart"
-- - "../../../third_party/dart/runtime/bin/directory_patch.dart"
-- - "../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
-- - "../../../third_party/dart/runtime/bin/file_patch.dart"
-- - "../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
-- - "../../../third_party/dart/runtime/bin/filter_patch.dart"
-- - "../../../third_party/dart/runtime/bin/io_service_patch.dart"
-- - "../../../third_party/dart/runtime/bin/namespace_patch.dart"
-- - "../../../third_party/dart/runtime/bin/platform_patch.dart"
-- - "../../../third_party/dart/runtime/bin/process_patch.dart"
-- - "../../../third_party/dart/runtime/bin/socket_patch.dart"
-- - "../../../third_party/dart/runtime/bin/stdio_patch.dart"
-- - "../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
-- - "../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
-
- isolate:
- uri: "../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/isolate_patch.dart"
-- - "../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
-
- math:
- uri: "../../../third_party/dart/sdk/lib/math/math.dart"
-- patches: "../../../third_party/dart/runtime/lib/math_patch.dart"
-+ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
-
- mirrors:
- uri: "../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- patches:
-- - "../../../third_party/dart/runtime/lib/mirrors_patch.dart"
-- - "../../../third_party/dart/runtime/lib/mirrors_impl.dart"
-- - "../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
-+ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
-
- nativewrappers:
- uri: "../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
-@@ -142,7 +142,7 @@ flutter:
-
- typed_data:
- uri: "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
-- patches: "../../../third_party/dart/runtime/lib/typed_data_patch.dart"
-+ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
-
- ui:
- uri: "../../lib/ui/ui.dart"
-diff --git a/shell/platform/fuchsia/dart_runner/kernel/libraries.json b/shell/platform/fuchsia/dart_runner/kernel/libraries.json
-index 0abe212e6..24c664852 100644
---- a/shell/platform/fuchsia/dart_runner/kernel/libraries.json
-+++ b/shell/platform/fuchsia/dart_runner/kernel/libraries.json
-@@ -1,43 +1,43 @@
- {
- "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
-- "comment:1": "Instead modify 'shell/platform/fuchsia/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
-+ "comment:1": "Instead modify 'flutter/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
- "dart_runner": {
- "libraries": {
- "_builtin": {
-- "uri": "../../../../../../third_party/dart/runtime/bin/builtin.dart"
-+ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
- },
- "core": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/core_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/array.dart",
-- "../../../../../../third_party/dart/runtime/lib/array_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/bool_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/date_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/double.dart",
-- "../../../../../../third_party/dart/runtime/lib/double_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/errors_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/expando_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/function.dart",
-- "../../../../../../third_party/dart/runtime/lib/function_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/growable_array.dart",
-- "../../../../../../third_party/dart/runtime/lib/identical_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/immutable_map.dart",
-- "../../../../../../third_party/dart/runtime/lib/integers.dart",
-- "../../../../../../third_party/dart/runtime/lib/integers_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart",
-- "../../../../../../third_party/dart/runtime/lib/map_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/null_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/object_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/stacktrace.dart",
-- "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/string_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/type_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/uri_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/core/core.dart"
- },
-@@ -46,30 +46,30 @@
- },
- "async": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/async_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/async/async.dart"
- },
- "collection": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/collection_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
- },
- "ffi": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- },
- "typed_data": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
- },
- "nativewrappers": {
-@@ -77,24 +77,24 @@
- },
- "mirrors": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
-- "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- },
- "developer": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/developer.dart",
-- "../../../../../../third_party/dart/runtime/lib/profiler.dart",
-- "../../../../../../third_party/dart/runtime/lib/timeline.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
- },
- "isolate": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- },
-@@ -103,48 +103,48 @@
- },
- "wasm": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- },
- "io": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/bin/common_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/directory_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/file_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/filter_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/platform_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/process_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/socket_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/io/io.dart"
- },
- "_internal": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/internal_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
-- "../../../../../../third_party/dart/runtime/lib/print_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
- "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
- },
- "convert": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/convert_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
- },
- "profiler": {
- "uri": "../../../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
- },
- "math": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/math_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/math/math.dart"
- },
- "_http": {
-diff --git a/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml b/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
-index cab901e60..5e1f638cd 100644
---- a/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
-+++ b/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
-@@ -14,87 +14,87 @@
- dart_runner:
- libraries:
- _builtin:
-- uri: "../../../../../../third_party/dart/runtime/bin/builtin.dart"
-+ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
-
- _internal:
- uri: "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/internal_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
-- - "../../../../../../third_party/dart/runtime/lib/print_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
- - "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
-
- async:
- uri: "../../../../../../third_party/dart/sdk/lib/async/async.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/async_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
-
- collection:
- uri: "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/collection_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
-
- convert:
- uri: "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/convert_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
-
- core:
- uri: "../../../../../../third_party/dart/sdk/lib/core/core.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/core_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/array.dart"
-- - "../../../../../../third_party/dart/runtime/lib/array_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/bool_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/date_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/double.dart"
-- - "../../../../../../third_party/dart/runtime/lib/double_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/errors_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/expando_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/function.dart"
-- - "../../../../../../third_party/dart/runtime/lib/function_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/growable_array.dart"
-- - "../../../../../../third_party/dart/runtime/lib/identical_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/immutable_map.dart"
-- - "../../../../../../third_party/dart/runtime/lib/integers.dart"
-- - "../../../../../../third_party/dart/runtime/lib/integers_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart"
-- - "../../../../../../third_party/dart/runtime/lib/map_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/null_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/object_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/stacktrace.dart"
-- - "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/string_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/type_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/uri_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
-
- developer:
- uri: "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/developer.dart"
-- - "../../../../../../third_party/dart/runtime/lib/profiler.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timeline.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
-
- ffi:
- uri: "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
-
- wasm:
- uri: "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
-
- _http:
- uri: "../../../../../../third_party/dart/sdk/lib/_http/http.dart"
-@@ -102,37 +102,37 @@ dart_runner:
- io:
- uri: "../../../../../../third_party/dart/sdk/lib/io/io.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/bin/common_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/directory_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/file_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/filter_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/platform_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/process_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/socket_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
-
- isolate:
- uri: "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
-
- math:
- uri: "../../../../../../third_party/dart/sdk/lib/math/math.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/math_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
-
- mirrors:
- uri: "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
-- - "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
-
- nativewrappers:
- uri: "../../../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
-@@ -142,7 +142,7 @@ dart_runner:
-
- typed_data:
- uri: "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
-
- fuchsia.builtin:
- uri: "../../../../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart"
-diff --git a/shell/platform/fuchsia/flutter/kernel/libraries.json b/shell/platform/fuchsia/flutter/kernel/libraries.json
-index 5a4602d8c..a8436200f 100644
---- a/shell/platform/fuchsia/flutter/kernel/libraries.json
-+++ b/shell/platform/fuchsia/flutter/kernel/libraries.json
-@@ -1,43 +1,43 @@
- {
- "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
-- "comment:1": "Instead modify 'shell/platform/fuchsia/flutter/kernel/libraries.yaml' and follow the instructions therein.",
-+ "comment:1": "Instead modify 'flutter/shell/platform/fuchsia/flutter/kernel/libraries.yaml' and follow the instructions therein.",
- "flutter_runner": {
- "libraries": {
- "_builtin": {
-- "uri": "../../../../../../third_party/dart/runtime/bin/builtin.dart"
-+ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
- },
- "core": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/core_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/array.dart",
-- "../../../../../../third_party/dart/runtime/lib/array_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/bool_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/date_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/double.dart",
-- "../../../../../../third_party/dart/runtime/lib/double_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/errors_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/expando_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/function.dart",
-- "../../../../../../third_party/dart/runtime/lib/function_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/growable_array.dart",
-- "../../../../../../third_party/dart/runtime/lib/identical_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/immutable_map.dart",
-- "../../../../../../third_party/dart/runtime/lib/integers.dart",
-- "../../../../../../third_party/dart/runtime/lib/integers_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart",
-- "../../../../../../third_party/dart/runtime/lib/map_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/null_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/object_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/stacktrace.dart",
-- "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/string_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/type_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/uri_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/core/core.dart"
- },
-@@ -46,30 +46,30 @@
- },
- "async": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/async_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/async/async.dart"
- },
- "collection": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/collection_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
- },
- "ffi": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- },
- "typed_data": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
- },
- "nativewrappers": {
-@@ -77,24 +77,24 @@
- },
- "mirrors": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
-- "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- },
- "developer": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/developer.dart",
-- "../../../../../../third_party/dart/runtime/lib/profiler.dart",
-- "../../../../../../third_party/dart/runtime/lib/timeline.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
- },
- "isolate": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- },
-@@ -103,48 +103,48 @@
- },
- "wasm": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- },
- "io": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/bin/common_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/directory_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/file_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/filter_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/platform_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/process_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/socket_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
-- "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/io/io.dart"
- },
- "_internal": {
- "patches": [
-- "../../../../../../third_party/dart/runtime/lib/internal_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
-- "../../../../../../third_party/dart/runtime/lib/print_patch.dart",
-- "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
-+ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
- "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
- ],
- "uri": "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
- },
- "convert": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/convert_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
- },
- "profiler": {
- "uri": "../../../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
- },
- "math": {
-- "patches": "../../../../../../third_party/dart/runtime/lib/math_patch.dart",
-+ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
- "uri": "../../../../../../third_party/dart/sdk/lib/math/math.dart"
- },
- "_http": {
-@@ -160,7 +160,7 @@
- "uri": "../../../../../../flutter/lib/ui/ui.dart"
- },
- "vmservice_io": {
-- "uri": "../../../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
-+ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/vmservice/vmservice_io.dart"
- }
- }
- }
-diff --git a/shell/platform/fuchsia/flutter/kernel/libraries.yaml b/shell/platform/fuchsia/flutter/kernel/libraries.yaml
-index f8385ca29..05b7f4f9f 100644
---- a/shell/platform/fuchsia/flutter/kernel/libraries.yaml
-+++ b/shell/platform/fuchsia/flutter/kernel/libraries.yaml
-@@ -14,87 +14,87 @@
- flutter_runner:
- libraries:
- _builtin:
-- uri: "../../../../../../third_party/dart/runtime/bin/builtin.dart"
-+ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
-
- _internal:
- uri: "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/internal_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
-- - "../../../../../../third_party/dart/runtime/lib/print_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
- - "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
-
- async:
- uri: "../../../../../../third_party/dart/sdk/lib/async/async.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/async_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
-
- collection:
- uri: "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/collection_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
-
- convert:
- uri: "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/convert_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
-
- core:
- uri: "../../../../../../third_party/dart/sdk/lib/core/core.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/core_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/array.dart"
-- - "../../../../../../third_party/dart/runtime/lib/array_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/bool_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/date_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/double.dart"
-- - "../../../../../../third_party/dart/runtime/lib/double_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/errors_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/expando_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/function.dart"
-- - "../../../../../../third_party/dart/runtime/lib/function_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/growable_array.dart"
-- - "../../../../../../third_party/dart/runtime/lib/identical_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/immutable_map.dart"
-- - "../../../../../../third_party/dart/runtime/lib/integers.dart"
-- - "../../../../../../third_party/dart/runtime/lib/integers_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart"
-- - "../../../../../../third_party/dart/runtime/lib/map_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/null_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/object_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/stacktrace.dart"
-- - "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/string_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/type_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/uri_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
-
- developer:
- uri: "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/developer.dart"
-- - "../../../../../../third_party/dart/runtime/lib/profiler.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timeline.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
-
- ffi:
- uri: "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
-
- wasm:
- uri: "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
-
- _http:
- uri: "../../../../../../third_party/dart/sdk/lib/_http/http.dart"
-@@ -102,37 +102,37 @@ flutter_runner:
- io:
- uri: "../../../../../../third_party/dart/sdk/lib/io/io.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/bin/common_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/directory_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/file_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/filter_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/platform_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/process_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/socket_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
-- - "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
-
- isolate:
- uri: "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
-
- math:
- uri: "../../../../../../third_party/dart/sdk/lib/math/math.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/math_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
-
- mirrors:
- uri: "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
- patches:
-- - "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
-- - "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
-- - "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
-+ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
-
- nativewrappers:
- uri: "../../../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
-@@ -142,7 +142,7 @@ flutter_runner:
-
- typed_data:
- uri: "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
-- patches: "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
-+ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
-
- fuchsia.builtin:
- uri: "../../../../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart"
-@@ -160,4 +160,4 @@ flutter_runner:
- uri: "../../../../../../third_party/dart/sdk/lib/vmservice/vmservice.dart"
-
- vmservice_io:
-- uri: "../../../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
-+ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/vmservice/vmservice_io.dart"
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index ad4aec0..7878730 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -299,8 +299,7 @@
_toUri(parsedArgs['dart-sdk-summary']),
_toUri(parsedArgs['libraries-file']),
_toUri(parsedArgs['packages-file']),
- summaryInputs,
- linkedInputs,
+ [...summaryInputs, ...linkedInputs],
target,
fileSystem,
parsedArgs['enable-experiment'] as List<String>,
diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn
index e41e7a4..495643d 100644
--- a/utils/dartdev/BUILD.gn
+++ b/utils/dartdev/BUILD.gn
@@ -11,8 +11,15 @@
],
"list lines")
+dartfix_files = exec_script("../../tools/list_dart_files.py",
+ [
+ "absolute",
+ rebase_path("../../pkg/dartfix"),
+ ],
+ "list lines")
+
application_snapshot("dartdev") {
main_dart = "../../pkg/dartdev/bin/dartdev.dart"
training_args = [ "--help" ]
- inputs = dartdev_files
+ inputs = dartdev_files + dartfix_files
}
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 221f9f1..ec13940 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -370,7 +370,7 @@
# TODO(38701): Cleanup after merging the forked SDK into mainline.
if (use_nnbd) {
- args += [ "--enable-experiment=non-nullable" ]
+ args += [ "--enable-experiment=non-nullable", "--force-nnbd-checks" ]
}
}