Version 2.9.0-11.0.dev
Merge commit '7b3ce0d54a32e159d99e9d8107473b01d805d1cd' into dev
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 7f8a7ba..87d1ada 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -219,8 +219,7 @@
{
"name": "ffi",
"rootUri": "../third_party/pkg/ffi",
- "packageUri": "lib/",
- "languageVersion": "2.6"
+ "packageUri": "lib/"
},
{
"name": "fixnum",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a233ee1..119220f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,11 @@
* Class `OSError` now implements `Exception`. This change means `OSError` will
now be caught in catch clauses catching `Exception`s.
* Added `InternetAddress.tryParse`.
+* [Abstract Unix Domain Socket][] is supported on Linux/Android now. Using an
+ `InternetAddress` with `address` starting with '@' and type being
+ `InternetAddressType.Unix` will create an abstract Unix Domain Socket.
+
+[Abstract Unix Domain Socket]: http://man7.org/linux/man-pages/man7/unix.7.html
### Tools
@@ -68,6 +73,19 @@
### Dart VM
+### Pub
+* Introduce `pub outdated --mode=null-safety` that will report which of your
+ dependencies you can upgrade to fully support null safety.
+* Fix `pub run` precompilation with relative `PUB_CACHE` paths (#2486)
+* Warn at publishing first time a package version opts in to null-safety.
+* Preserve Windows line endings in pubspec.lock if they are already there (#2489)
+* Better terminal color-detection. Use colors in terminals on Windows.
+* `pub outdated`: If the current version of a dependency is a prerelease
+ version, use prereleases for latest if no newer stable.
+* `pub outdated` now works without a lockfile. In that case the 'Current'
+ column will be empty.
+* `pub upgrade`: Show summary count of outdated packages after running.
+
## 2.8.2 - 2020-05-13
This is a patch release that fixes an AOT compilation bug in global
diff --git a/DEPS b/DEPS
index 9ba1668..9ce14c9 100644
--- a/DEPS
+++ b/DEPS
@@ -43,7 +43,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": "f65f3578f95415c9a2f3ad002aac7b507549e64a",
+ "co19_rev": "9dacb12cf963ce92fb056b7f2fb87096fd576e9a",
"co19_2_rev": "ef2cb6474595d3ed60870e1a26e8913a980d6d59",
# As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
@@ -90,8 +90,8 @@
# For more details, see https://github.com/dart-lang/sdk/issues/30164
"dart_style_tag": "1.3.6", # Please see the note above before updating.
- "dartdoc_tag" : "v0.31.0",
- "ffi_tag": "4cc14129e81f8804e73321f0ccf5484397a5ddce",
+ "dartdoc_tag" : "v0.32.0",
+ "ffi_tag": "454ab0f9ea6bd06942a983238d8a6818b1357edb",
"fixnum_tag": "eb3748663dc979271ff6a3d014fbe522543b1d91",
"glob_tag": "e9f4e6b7ae8abe5071461cf8f47191bb19cf7ef6",
"html_tag": "083a36cd801a4b787ba156b7c6e4c8b2e2daed4a",
@@ -105,7 +105,7 @@
"idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
"intl_tag": "0.16.1",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
- "json_rpc_2_tag": "eec10819a40e7bf2e401f2b97368776a90cc5550",
+ "json_rpc_2_tag": "d589e635d8ccb7cda6a804bd571f88abbabab146",
"linter_tag": "0.1.115",
"logging_tag": "9561ba016ae607747ae69b846c0e10958ca58ed4",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
@@ -121,7 +121,7 @@
"ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
"pool_tag": "86fbb2cde9bbc66c8d159909d2f65a5981ea5b50",
"protobuf_rev": "3746c8fd3f2b0147623a8e3db89c3ff4330de760",
- "pub_rev": "3606265962da4248d34d352aa3d170aae4496a90",
+ "pub_rev": "a4bc2dd08630f85a94f506eab037fcaaedb42222",
"pub_semver_tag": "v1.4.4",
"quiver-dart_tag": "2.0.0+1",
"resource_rev": "f8e37558a1c4f54550aa463b88a6a831e3e33cd6",
@@ -477,7 +477,7 @@
# TODO(37531): Remove these cipd packages and build with sdk instead when
# benchmark runner gets support for that.
- Var("dart_root") + "/benchmarks/FfiBoringssl/dart/native/out/": {
+ Var("dart_root") + "/benchmarks/FfiBoringssl/native/out/": {
"packages": [
{
"package": "dart/benchmarks/ffiboringssl",
diff --git a/benchmarks/FfiBoringssl/dart/digest.dart b/benchmarks/FfiBoringssl/dart/digest.dart
index ecc869b..655e12f 100644
--- a/benchmarks/FfiBoringssl/dart/digest.dart
+++ b/benchmarks/FfiBoringssl/dart/digest.dart
@@ -14,9 +14,9 @@
DynamicLibrary openSsl() {
// Force load crypto.
dlopenPlatformSpecific("crypto",
- path: Platform.script.resolve("native/out/").path);
+ path: Platform.script.resolve("../native/out/").path);
DynamicLibrary ssl = dlopenPlatformSpecific("ssl",
- path: Platform.script.resolve("native/out/").path);
+ path: Platform.script.resolve("../native/out/").path);
return ssl;
}
diff --git a/benchmarks/FfiBoringssl/dart/native/.gitignore b/benchmarks/FfiBoringssl/native/.gitignore
similarity index 100%
rename from benchmarks/FfiBoringssl/dart/native/.gitignore
rename to benchmarks/FfiBoringssl/native/.gitignore
diff --git a/benchmarks/FfiBoringssl/dart/native/Makefile b/benchmarks/FfiBoringssl/native/Makefile
similarity index 100%
rename from benchmarks/FfiBoringssl/dart/native/Makefile
rename to benchmarks/FfiBoringssl/native/Makefile
diff --git a/benchmarks/FfiBoringssl/dart/native/arm.cmake b/benchmarks/FfiBoringssl/native/arm.cmake
similarity index 100%
rename from benchmarks/FfiBoringssl/dart/native/arm.cmake
rename to benchmarks/FfiBoringssl/native/arm.cmake
diff --git a/benchmarks/FfiBoringssl/dart/native/arm64.cmake b/benchmarks/FfiBoringssl/native/arm64.cmake
similarity index 100%
rename from benchmarks/FfiBoringssl/dart/native/arm64.cmake
rename to benchmarks/FfiBoringssl/native/arm64.cmake
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/block_kind.dart b/pkg/_fe_analyzer_shared/lib/src/parser/block_kind.dart
index 60a6461..46c0f8d 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/block_kind.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/block_kind.dart
@@ -17,23 +17,26 @@
String toString() => 'BlockKind($name)';
- static const BlockKind catchClause = const BlockKind._('catch clause', true);
- static const BlockKind classDeclaration =
- const BlockKind._('class declaration', false);
- static const BlockKind enumDeclaration =
- const BlockKind._('enum declaration', false);
- static const BlockKind extensionDeclaration =
- const BlockKind._('extension declaration', false);
+ static const BlockKind catchClause =
+ const BlockKind._('catch clause', /* useNameForMissingBlock = */ true);
+ static const BlockKind classDeclaration = const BlockKind._(
+ 'class declaration', /* useNameForMissingBlock = */ false);
+ static const BlockKind enumDeclaration = const BlockKind._(
+ 'enum declaration', /* useNameForMissingBlock = */ false);
+ static const BlockKind extensionDeclaration = const BlockKind._(
+ 'extension declaration', /* useNameForMissingBlock = */ false);
static const BlockKind finallyClause =
- const BlockKind._('finally clause', true);
+ const BlockKind._('finally clause', /* useNameForMissingBlock = */ true);
static const BlockKind functionBody =
- const BlockKind._('function body', false);
- static const BlockKind invalid = const BlockKind._('invalid', false);
- static const BlockKind mixinDeclaration =
- const BlockKind._('mixin declaration', false);
- static const BlockKind statement = const BlockKind._('statement', false);
- static const BlockKind switchStatement =
- const BlockKind._('switch statement', false);
+ const BlockKind._('function body', /* useNameForMissingBlock = */ false);
+ static const BlockKind invalid =
+ const BlockKind._('invalid', /* useNameForMissingBlock = */ false);
+ static const BlockKind mixinDeclaration = const BlockKind._(
+ 'mixin declaration', /* useNameForMissingBlock = */ false);
+ static const BlockKind statement =
+ const BlockKind._('statement', /* useNameForMissingBlock = */ false);
+ static const BlockKind switchStatement = const BlockKind._(
+ 'switch statement', /* useNameForMissingBlock = */ false);
static const BlockKind tryStatement =
- const BlockKind._('try statement', true);
+ const BlockKind._('try statement', /* useNameForMissingBlock = */ true);
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/literal_entry_info.dart b/pkg/_fe_analyzer_shared/lib/src/parser/literal_entry_info.dart
index 0e3bb11..35221fd 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/literal_entry_info.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/literal_entry_info.dart
@@ -10,7 +10,8 @@
/// [simpleEntry] is the first step for parsing a literal entry
/// without any control flow or spread collection operator.
-const LiteralEntryInfo simpleEntry = const LiteralEntryInfo(true, 0);
+const LiteralEntryInfo simpleEntry =
+ const LiteralEntryInfo(/* hasEntry = */ true, /* ifConditionDelta = */ 0);
/// [LiteralEntryInfo] represents steps for processing an entry
/// in a literal list, map, or set. These steps will handle parsing
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 2f50fa0..7b8fe3a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -360,7 +360,7 @@
// then report an error and skip the current token.
token = token.next;
listener.beginMetadataStar(token);
- listener.endMetadataStar(0);
+ listener.endMetadataStar(/* count = */ 0);
reportRecoverableErrorWithToken(
token, codes.templateExpectedDeclaration);
listener.handleInvalidTopLevelDeclaration(token);
@@ -444,8 +444,9 @@
/// token and returns the token after the last consumed token rather than the
/// last consumed token.
Token parseTopLevelDeclaration(Token token) {
- token =
- parseTopLevelDeclarationImpl(syntheticPreviousToken(token), null).next;
+ token = parseTopLevelDeclarationImpl(
+ syntheticPreviousToken(token), /* directiveState = */ null)
+ .next;
listener.endTopLevelDeclaration(token);
return token;
}
@@ -660,9 +661,11 @@
} else if (optional('as', next)) {
Token asKeyword = next;
token = ensureIdentifier(next, IdentifierContext.importPrefixDeclaration);
- listener.handleImportPrefix(null, asKeyword);
+ listener.handleImportPrefix(/* deferredKeyword = */ null, asKeyword);
} else {
- listener.handleImportPrefix(null, null);
+ listener.handleImportPrefix(
+ /* deferredKeyword = */ null,
+ /* asKeyword = */ null);
}
return token;
}
@@ -685,7 +688,7 @@
return token;
} else {
// Recovery
- listener.endImport(importKeyword, null);
+ listener.endImport(importKeyword, /* semicolon = */ null);
return parseImportRecovery(uri);
}
}
@@ -740,7 +743,7 @@
if (optional('deferred', token.next) &&
!optional('as', token.next.next)) {
- listener.handleImportPrefix(token.next, null);
+ listener.handleImportPrefix(token.next, /* asKeyword = */ null);
token = token.next;
} else {
token = parseImportPrefixOpt(token);
@@ -819,7 +822,7 @@
if (!optional('(', leftParen)) {
reportRecoverableError(
leftParen, codes.templateExpectedButGot.withArguments('('));
- leftParen = rewriter.insertParens(token, true);
+ leftParen = rewriter.insertParens(token, /* includeIdentifier = */ true);
}
token = parseDottedName(leftParen);
Token next = token.next;
@@ -957,10 +960,12 @@
/// ```
Token parseTypeList(Token token) {
listener.beginTypeList(token.next);
- token = computeType(token, true).ensureTypeOrVoid(token, this);
+ token =
+ computeType(token, /* required = */ true).ensureTypeOrVoid(token, this);
int count = 1;
while (optional(',', token.next)) {
- token = computeType(token.next, true).ensureTypeOrVoid(token.next, this);
+ token = computeType(token.next, /* required = */ true)
+ .ensureTypeOrVoid(token.next, this);
count++;
}
listener.endTypeList(count);
@@ -1094,10 +1099,11 @@
Token parseTypedef(Token typedefKeyword) {
assert(optional('typedef', typedefKeyword));
listener.beginFunctionTypeAlias(typedefKeyword);
- TypeInfo typeInfo = computeType(typedefKeyword, false);
+ TypeInfo typeInfo = computeType(typedefKeyword, /* required = */ false);
Token token = typeInfo.skipType(typedefKeyword).next;
Token equals;
- TypeParamOrArgInfo typeParam = computeTypeParamOrArg(token, true);
+ TypeParamOrArgInfo typeParam =
+ computeTypeParamOrArg(token, /* inDeclaration = */ true);
if (typeInfo == noType &&
(token.kind == IDENTIFIER_TOKEN || token.type.isPseudo) &&
optional('=', typeParam.skip(token).next)) {
@@ -1112,7 +1118,8 @@
}
if (optional('=', token)) {
equals = token;
- token = computeType(equals, true).ensureTypeOrVoid(equals, this);
+ token = computeType(equals, /* required = */ true)
+ .ensureTypeOrVoid(equals, this);
} else {
// A rewrite caused the = to disappear
token = parseFormalParametersRequiredOpt(
@@ -1183,7 +1190,7 @@
}
}
reportRecoverableError(name, missingParameterMessage(kind));
- token = rewriter.insertParens(token, false);
+ token = rewriter.insertParens(token, /* includeIdentifier = */ false);
token = parseFormalParametersRest(token, kind);
}
return token;
@@ -1209,7 +1216,7 @@
listener.beginOptionalFormalParameters(token);
Token closeBrace = token.endGroup;
assert(optional(')', closeBrace));
- listener.endFormalParameters(0, token, closeBrace, kind);
+ listener.endFormalParameters(/* count = */ 0, token, closeBrace, kind);
return closeBrace;
}
@@ -1221,7 +1228,7 @@
Token next = token.next;
if (!optional('(', next)) {
reportRecoverableError(next, missingParameterMessage(kind));
- next = rewriter.insertParens(token, false);
+ next = rewriter.insertParens(token, /* includeIdentifier = */ false);
}
return parseFormalParametersRest(next, kind);
}
@@ -1408,7 +1415,7 @@
(optional('.', next) ||
(next.isIdentifier && optional('.', next.next)))) {
// Recovery: Malformed type reference.
- typeInfo = computeType(beforeType, true);
+ typeInfo = computeType(beforeType, /* required = */ true);
token = typeInfo.skipType(beforeType);
next = token.next;
}
@@ -1591,8 +1598,8 @@
rewriteAndRecover(
token,
codes.messageEmptyOptionalParameterList,
- new SyntheticStringToken(
- TokenType.IDENTIFIER, '', token.next.charOffset, 0));
+ new SyntheticStringToken(TokenType.IDENTIFIER, '',
+ token.next.charOffset, /* _length = */ 0));
token = parseFormalParameter(
token, FormalParameterKind.optionalPositional, kind);
++parameterCount;
@@ -1642,8 +1649,8 @@
rewriteAndRecover(
token,
codes.messageEmptyNamedParameterList,
- new SyntheticStringToken(
- TokenType.IDENTIFIER, '', token.next.charOffset, 0));
+ new SyntheticStringToken(TokenType.IDENTIFIER, '',
+ token.next.charOffset, /* _length = */ 0));
token =
parseFormalParameter(token, FormalParameterKind.optionalNamed, kind);
++parameterCount;
@@ -1698,7 +1705,9 @@
Token skipBlock(Token token) {
// The scanner ensures that `{` always has a closing `}`.
- return ensureBlock(token, null, null).endGroup;
+ return ensureBlock(
+ token, /* template = */ null, /* missingBlockName = */ null)
+ .endGroup;
}
/// ```
@@ -1758,7 +1767,8 @@
}
} else {
// TODO(danrubel): merge this error message with missing class/mixin body
- leftBrace = ensureBlock(token, codes.templateExpectedEnumBody, null);
+ leftBrace = ensureBlock(
+ token, codes.templateExpectedEnumBody, /* missingBlockName = */ null);
token = leftBrace.endGroup;
}
assert(optional('}', token));
@@ -1773,8 +1783,9 @@
listener.beginClassOrNamedMixinApplicationPrelude(begin);
Token name = ensureIdentifier(
classKeyword, IdentifierContext.classOrMixinOrExtensionDeclaration);
- Token token =
- computeTypeParamOrArg(name, true, true).parseVariables(name, this);
+ Token token = computeTypeParamOrArg(
+ name, /* inDeclaration = */ true, /* allowsVariance = */ true)
+ .parseVariables(name, this);
if (optional('=', token.next)) {
listener.beginNamedMixinApplication(begin, abstractToken, name);
return parseNamedMixinApplication(token, begin, classKeyword);
@@ -1788,7 +1799,8 @@
Token token, Token begin, Token classKeyword) {
Token equals = token = token.next;
assert(optional('=', equals));
- token = computeType(token, true).ensureTypeNotVoid(token, this);
+ token = computeType(token, /* required = */ true)
+ .ensureTypeNotVoid(token, this);
token = parseMixinApplicationRest(token);
Token implementsKeyword = null;
if (optional('implements', token.next)) {
@@ -1819,7 +1831,7 @@
if (!optional('{', token.next)) {
// Recovery
token = parseClassHeaderRecovery(start, begin, classKeyword);
- ensureBlock(token, null, 'class declaration');
+ ensureBlock(token, /* template = */ null, 'class declaration');
}
token = parseClassOrMixinOrExtensionBody(
token, DeclarationKind.Class, className);
@@ -1876,7 +1888,7 @@
reportRecoverableError(
token.next, codes.templateExpectedInstead.withArguments('extends'));
Token incorrectExtendsKeyword = token.next;
- token = computeType(incorrectExtendsKeyword, true)
+ token = computeType(incorrectExtendsKeyword, /* required = */ true)
.ensureTypeNotVoid(incorrectExtendsKeyword, this);
listener.handleClassExtends(incorrectExtendsKeyword);
} else {
@@ -1939,11 +1951,12 @@
Token next = token.next;
if (optional('extends', next)) {
Token extendsKeyword = next;
- token = computeType(next, true).ensureTypeNotVoid(next, this);
+ token = computeType(next, /* required = */ true)
+ .ensureTypeNotVoid(next, this);
listener.handleClassExtends(extendsKeyword);
} else {
listener.handleNoType(token);
- listener.handleClassExtends(null);
+ listener.handleClassExtends(/* extendsKeyword = */ null);
}
return token;
}
@@ -1959,8 +1972,8 @@
if (optional('implements', token.next)) {
implementsKeyword = token.next;
do {
- token =
- computeType(token.next, true).ensureTypeNotVoid(token.next, this);
+ token = computeType(token.next, /* required = */ true)
+ .ensureTypeNotVoid(token.next, this);
++interfacesCount;
} while (optional(',', token.next));
}
@@ -1981,14 +1994,15 @@
listener.beginClassOrNamedMixinApplicationPrelude(mixinKeyword);
Token name = ensureIdentifier(
mixinKeyword, IdentifierContext.classOrMixinOrExtensionDeclaration);
- Token headerStart =
- computeTypeParamOrArg(name, true, true).parseVariables(name, this);
+ Token headerStart = computeTypeParamOrArg(
+ name, /* inDeclaration = */ true, /* allowsVariance = */ true)
+ .parseVariables(name, this);
listener.beginMixinDeclaration(mixinKeyword, name);
Token token = parseMixinHeaderOpt(headerStart, mixinKeyword);
if (!optional('{', token.next)) {
// Recovery
token = parseMixinHeaderRecovery(token, mixinKeyword, headerStart);
- ensureBlock(token, null, 'mixin declaration');
+ ensureBlock(token, /* template = */ null, 'mixin declaration');
}
token = parseClassOrMixinOrExtensionBody(
token, DeclarationKind.Mixin, name.lexeme);
@@ -2082,7 +2096,7 @@
/// ```
Token parseMixinOnOpt(Token token) {
if (!optional('on', token.next)) {
- listener.handleMixinOn(null, 0);
+ listener.handleMixinOn(/* onKeyword = */ null, /* typeCount = */ 0);
return token;
}
return parseMixinOn(token);
@@ -2096,7 +2110,8 @@
onKeyword.lexeme == 'extend');
int typeCount = 0;
do {
- token = computeType(token.next, true).ensureTypeNotVoid(token.next, this);
+ token = computeType(token.next, /* required = */ true)
+ .ensureTypeNotVoid(token.next, this);
++typeCount;
} while (optional(',', token.next));
listener.handleMixinOn(onKeyword, typeCount);
@@ -2123,7 +2138,8 @@
} else {
name = null;
}
- token = computeTypeParamOrArg(token, true).parseVariables(token, this);
+ token = computeTypeParamOrArg(token, /* inDeclaration = */ true)
+ .parseVariables(token, this);
listener.beginExtensionDeclaration(extensionKeyword, name);
Token onKeyword = token.next;
if (!optional('on', onKeyword)) {
@@ -2139,7 +2155,7 @@
onKeyword = rewriter.insertSyntheticKeyword(token, Keyword.ON);
}
}
- TypeInfo typeInfo = computeType(onKeyword, true);
+ TypeInfo typeInfo = computeType(onKeyword, /* required = */ true);
token = typeInfo.ensureTypeOrVoid(onKeyword, this);
if (!optional('{', token.next)) {
// Recovery
@@ -2163,7 +2179,7 @@
break;
}
}
- ensureBlock(token, null, 'extension declaration');
+ ensureBlock(token, /* template = */ null, 'extension declaration');
}
token = parseClassOrMixinOrExtensionBody(
token, DeclarationKind.Extension, name?.lexeme);
@@ -2239,7 +2255,8 @@
}
Token parseTypeVariablesOpt(Token token) {
- return computeTypeParamOrArg(token, true).parseVariables(token, this);
+ return computeTypeParamOrArg(token, /* inDeclaration = */ true)
+ .parseVariables(token, this);
}
/// Parse a top level field or function.
@@ -2313,7 +2330,8 @@
}
Token beforeType = token;
- TypeInfo typeInfo = computeType(token, false, true);
+ TypeInfo typeInfo =
+ computeType(token, /* required = */ false, /* inDeclaration = */ true);
token = typeInfo.skipType(token);
next = token.next;
@@ -2431,15 +2449,15 @@
return parseFields(
beforeStart,
externalToken,
- null,
- null,
+ /* staticToken = */ null,
+ /* covariantToken = */ null,
lateToken,
varFinalOrConst,
beforeType,
typeInfo,
token.next,
DeclarationKind.TopLevel,
- null,
+ /* enclosingDeclarationName = */ null,
nameIsRecovered);
}
@@ -2590,7 +2608,8 @@
reportRecoverableError(
externalToken, codes.messageExternalMethodWithBody);
}
- token = parseFunctionBody(token, false, isExternal);
+ token = parseFunctionBody(
+ token, /* ofFunctionExpression = */ false, isExternal);
asyncState = savedAsyncModifier;
listener.endTopLevelMethod(beforeStart.next, getOrSet, token);
return token;
@@ -2605,7 +2624,8 @@
if (!optional('<', name.next)) {
return noTypeParamOrArg.parseVariables(name, this);
}
- TypeParamOrArgInfo typeVar = computeTypeParamOrArg(name, true);
+ TypeParamOrArgInfo typeVar =
+ computeTypeParamOrArg(name, /* inDeclaration = */ true);
Token token = typeVar.parseVariables(name, this);
if (optional('=', token.next)) {
// Recovery
@@ -2872,7 +2892,7 @@
} else if (!optional('(', next)) {
reportRecoverableError(
next, codes.templateExpectedAfterButGot.withArguments('('));
- rewriter.insertParens(token, false);
+ rewriter.insertParens(token, /* includeIdentifier = */ false);
}
}
return parseInitializerExpressionRest(start);
@@ -2965,8 +2985,8 @@
Token next = token.next;
if (!identical(next.kind, STRING_TOKEN)) {
codes.Message message = codes.templateExpectedString.withArguments(next);
- Token newToken =
- new SyntheticStringToken(TokenType.STRING, '""', next.charOffset, 0);
+ Token newToken = new SyntheticStringToken(
+ TokenType.STRING, '""', next.charOffset, /* _length = */ 0);
rewriteAndRecover(token, message, newToken);
}
return parseLiteralString(token);
@@ -3048,7 +3068,8 @@
Token skipClassOrMixinOrExtensionBody(Token token) {
// The scanner ensures that `{` always has a closing `}`.
- return ensureBlock(token, null, null);
+ return ensureBlock(
+ token, /* template = */ null, /* missingBlockName = */ null);
}
/// ```
@@ -3545,7 +3566,7 @@
reportRecoverableError(bodyStart, codes.messageRedirectionInNonFactory);
token = parseRedirectingFactoryBody(token);
} else {
- token = parseFunctionBody(token, false,
+ token = parseFunctionBody(token, /* ofFunctionExpression = */ false,
(staticToken == null || externalToken != null) && inPlainSync);
}
asyncState = savedAsyncModifier;
@@ -3698,14 +3719,20 @@
if (!optional(';', next)) {
reportRecoverableError(next, codes.messageExternalFactoryWithBody);
}
- token = parseFunctionBody(token, false, true);
+ token = parseFunctionBody(
+ token,
+ /* ofFunctionExpression = */ false,
+ /* allowAbstract = */ true);
} else {
if (varFinalOrConst != null && !optional('native', next)) {
if (optional('const', varFinalOrConst)) {
reportRecoverableError(varFinalOrConst, codes.messageConstFactory);
}
}
- token = parseFunctionBody(token, false, false);
+ token = parseFunctionBody(
+ token,
+ /* ofFunctionExpression = */ false,
+ /* allowAbstract = */ false);
}
switch (kind) {
case DeclarationKind.Class:
@@ -3770,7 +3797,8 @@
Token beginToken = token.next;
listener.beginFunctionExpression(beginToken);
token = parseFormalParametersRequiredOpt(token, MemberKind.Local);
- token = parseAsyncOptBody(token, true, false);
+ token = parseAsyncOptBody(
+ token, /* ofFunctionExpression = */ true, /* allowAbstract = */ false);
listener.endFunctionExpression(beginToken, token.next);
return token;
}
@@ -3785,7 +3813,8 @@
Token formals = typeParam.parseVariables(name, this);
listener.beginNamedFunctionExpression(start.next);
typeInfo.parseType(start, this);
- return parseNamedFunctionRest(beforeName, start.next, formals, true);
+ return parseNamedFunctionRest(
+ beforeName, start.next, formals, /* isFunctionExpression = */ true);
}
/// Parses the rest of a named function declaration starting from its [name]
@@ -3818,7 +3847,8 @@
listener.endFunctionName(begin, token);
token = parseFormalParametersRequiredOpt(formals, MemberKind.Local);
token = parseInitializersOpt(token);
- token = parseAsyncOptBody(token, isFunctionExpression, false);
+ token = parseAsyncOptBody(
+ token, isFunctionExpression, /* allowAbstract = */ false);
if (isFunctionExpression) {
listener.endNamedFunctionExpression(token);
} else {
@@ -3908,7 +3938,7 @@
if (optional(';', token.next)) {
token = token.next;
}
- listener.handleFunctionBodySkipped(token, true);
+ listener.handleFunctionBodySkipped(token, /* isExpressionBody = */ true);
} else if (identical(value, '=')) {
token = next;
reportRecoverableError(token, codes.messageExpectedBody);
@@ -3919,10 +3949,10 @@
if (optional(';', token.next)) {
token = token.next;
}
- listener.handleFunctionBodySkipped(token, true);
+ listener.handleFunctionBodySkipped(token, /* isExpressionBody = */ true);
} else {
token = skipBlock(token);
- listener.handleFunctionBodySkipped(token, false);
+ listener.handleFunctionBodySkipped(token, /* isExpressionBody = */ false);
}
return token;
}
@@ -3967,7 +3997,7 @@
token = ensureSemicolon(token);
listener.handleExpressionFunctionBody(begin, token);
} else {
- listener.handleExpressionFunctionBody(begin, null);
+ listener.handleExpressionFunctionBody(begin, /* endToken = */ null);
}
return token;
}
@@ -3995,7 +4025,10 @@
begin = next = token.next;
// Fall through to parse the block.
} else {
- token = ensureBlock(token, codes.templateExpectedFunctionBody, null);
+ token = ensureBlock(
+ token,
+ codes.templateExpectedFunctionBody,
+ /* missingBlockName = */ null);
listener.handleInvalidFunctionBody(token);
return token.endGroup;
}
@@ -4032,7 +4065,7 @@
token = ensureSemicolon(token);
listener.handleExpressionFunctionBody(begin, token);
} else {
- listener.handleExpressionFunctionBody(begin, null);
+ listener.handleExpressionFunctionBody(begin, /* endToken = */ null);
}
if (inGenerator) {
listener.handleInvalidStatement(
@@ -4113,7 +4146,12 @@
return parseLabeledStatement(token);
}
return parseExpressionStatementOrDeclarationAfterModifiers(
- token, token, null, null, null, false);
+ token,
+ token,
+ /* lateToken = */ null,
+ /* varFinalOrConst = */ null,
+ /* typeInfo = */ null,
+ /* onlyParseVariableDeclarationStart = */ false);
}
final String value = token.next.stringValue;
if (identical(value, '{')) {
@@ -4125,7 +4163,12 @@
Token varOrFinal = token.next;
if (!isModifier(varOrFinal.next)) {
return parseExpressionStatementOrDeclarationAfterModifiers(
- varOrFinal, token, null, varOrFinal, null, false);
+ varOrFinal,
+ token,
+ /* lateToken = */ null,
+ varOrFinal,
+ /* typeInfo = */ null,
+ /* onlyParseVariableDeclarationStart = */ false);
}
return parseExpressionStatementOrDeclaration(token);
} else if (identical(value, 'if')) {
@@ -4133,7 +4176,7 @@
} else if (identical(value, 'await') && optional('for', token.next.next)) {
return parseForStatement(token.next, token.next);
} else if (identical(value, 'for')) {
- return parseForStatement(token, null);
+ return parseForStatement(token, /* awaitToken = */ null);
} else if (identical(value, 'rethrow')) {
return parseRethrowStatement(token);
} else if (identical(value, 'while')) {
@@ -4245,12 +4288,12 @@
listener.beginReturnStatement(begin);
Token next = token.next;
if (optional(';', next)) {
- listener.endReturnStatement(false, begin, next);
+ listener.endReturnStatement(/* hasExpression = */ false, begin, next);
return next;
}
token = parseExpression(token);
token = ensureSemicolon(token);
- listener.endReturnStatement(true, begin, token);
+ listener.endReturnStatement(/* hasExpression = */ true, begin, token);
if (inGenerator) {
listener.handleInvalidStatement(
begin, codes.messageGeneratorReturnsValue);
@@ -4340,8 +4383,9 @@
}
} else {
token = optional('throw', token.next)
- ? parseThrowExpression(token, true)
- : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true);
+ ? parseThrowExpression(token, /* allowCascades = */ true)
+ : parsePrecedenceExpression(
+ token, ASSIGNMENT_PRECEDENCE, /* allowCascades = */ true);
}
expressionDepth--;
return token;
@@ -4349,8 +4393,9 @@
Token parseExpressionWithoutCascade(Token token) {
return optional('throw', token.next)
- ? parseThrowExpression(token, false)
- : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, false);
+ ? parseThrowExpression(token, /* allowCascades = */ false)
+ : parsePrecedenceExpression(
+ token, ASSIGNMENT_PRECEDENCE, /* allowCascades = */ false);
}
bool canParseAsConditional(Token question) {
@@ -4434,7 +4479,7 @@
// level.
Token next = token.next;
token = optional('throw', next.next)
- ? parseThrowExpression(next, false)
+ ? parseThrowExpression(next, /* allowCascades = */ false)
: parsePrecedenceExpression(next, level, allowCascades);
listener.handleAssignmentExpression(operator);
} else if (identical(tokenLevel, POSTFIX_PRECEDENCE)) {
@@ -4474,11 +4519,13 @@
} else if (identical(type, TokenType.OPEN_PAREN) ||
identical(type, TokenType.OPEN_SQUARE_BRACKET) ||
identical(type, TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET)) {
- token = parseArgumentOrIndexStar(token, typeArg, false);
+ token = parseArgumentOrIndexStar(
+ token, typeArg, /* checkedNullAware = */ false);
} else if (identical(type, TokenType.QUESTION)) {
// We have determined selector precedence so this is a null-aware
// bracket operator.
- token = parseArgumentOrIndexStar(token, typeArg, true);
+ token = parseArgumentOrIndexStar(
+ token, typeArg, /* checkedNullAware = */ true);
} else if (identical(type, TokenType.INDEX)) {
BeginToken replacement = link(
new BeginToken(TokenType.OPEN_SQUARE_BRACKET, next.charOffset,
@@ -4486,7 +4533,8 @@
new Token(TokenType.CLOSE_SQUARE_BRACKET, next.charOffset + 1));
rewriter.replaceTokenFollowing(token, replacement);
replacement.endToken = replacement.next;
- token = parseArgumentOrIndexStar(token, noTypeParamOrArg, false);
+ token = parseArgumentOrIndexStar(
+ token, noTypeParamOrArg, /* checkedNullAware = */ false);
} else if (identical(type, TokenType.BANG)) {
listener.handleNonNullAssertExpression(token.next);
token = next;
@@ -4561,7 +4609,8 @@
assert(optional('..', cascadeOperator) || optional('?..', cascadeOperator));
listener.beginCascade(cascadeOperator);
if (optional('[', token.next)) {
- token = parseArgumentOrIndexStar(token, noTypeParamOrArg, false);
+ token = parseArgumentOrIndexStar(
+ token, noTypeParamOrArg, /* checkedNullAware = */ false);
} else {
token = parseSend(token, IdentifierContext.expressionContinuation);
listener.endBinaryExpression(cascadeOperator);
@@ -4587,7 +4636,8 @@
next = token.next;
assert(optional('(', next));
}
- token = parseArgumentOrIndexStar(token, typeArg, false);
+ token = parseArgumentOrIndexStar(
+ token, typeArg, /* checkedNullAware = */ false);
next = token.next;
} while (!identical(mark, token));
@@ -4796,12 +4846,12 @@
} else if (kind == OPEN_SQUARE_BRACKET_TOKEN ||
optional('[]', token.next)) {
listener.handleNoTypeArguments(token.next);
- return parseLiteralListSuffix(token, null);
+ return parseLiteralListSuffix(token, /* constKeyword = */ null);
} else if (kind == OPEN_CURLY_BRACKET_TOKEN) {
listener.handleNoTypeArguments(token.next);
- return parseLiteralSetOrMapSuffix(token, null);
+ return parseLiteralSetOrMapSuffix(token, /* constKeyword = */ null);
} else if (kind == LT_TOKEN) {
- return parseLiteralListSetMapOrFunction(token, null);
+ return parseLiteralListSetMapOrFunction(token, /* constKeyword = */ null);
} else {
// Fall through to the recovery code.
}
@@ -4852,7 +4902,7 @@
// Recover
reportRecoverableError(
openParen, codes.templateExpectedToken.withArguments('('));
- openParen = rewriter.insertParens(token, false);
+ openParen = rewriter.insertParens(token, /* includeIdentifier = */ false);
}
token = parseExpressionInParenthesisRest(openParen);
listener.handleParenthesizedCondition(openParen);
@@ -4928,7 +4978,11 @@
int count = 0;
if (optional('[]', token)) {
token = rewriteSquareBrackets(beforeToken).next;
- listener.handleLiteralList(0, token, constKeyword, token.next);
+ listener.handleLiteralList(
+ /* count = */ 0,
+ token,
+ constKeyword,
+ token.next);
return token.next;
}
bool old = mayParseFunctionExpressions;
@@ -4994,7 +5048,8 @@
assert(optional('{', leftBrace));
Token next = token.next;
if (optional('}', next)) {
- listener.handleLiteralSetOrMap(0, leftBrace, constKeyword, next, false);
+ listener.handleLiteralSetOrMap(/* count = */ 0, leftBrace, constKeyword,
+ next, /* hasSetEntry = */ false);
return next;
}
@@ -5106,7 +5161,8 @@
Token parseLiteralListSetMapOrFunction(
final Token start, Token constKeyword) {
assert(optional('<', start.next));
- TypeParamOrArgInfo typeParamOrArg = computeTypeParamOrArg(start, true);
+ TypeParamOrArgInfo typeParamOrArg =
+ computeTypeParamOrArg(start, /* inDeclaration = */ true);
Token token = typeParamOrArg.skip(start);
if (optional('(', token.next)) {
if (constKeyword != null) {
@@ -5169,7 +5225,7 @@
if (!mayParseFunctionExpressions) {
return parseSend(token, context);
}
- TypeInfo typeInfo = computeType(token, false);
+ TypeInfo typeInfo = computeType(token, /* required = */ false);
Token beforeName = typeInfo.skipType(token);
Token name = beforeName.next;
if (name.isIdentifier) {
@@ -5190,7 +5246,7 @@
if (!optional('(', next)) {
reportRecoverableError(
token, codes.templateExpectedAfterButGot.withArguments('('));
- next = rewriter.insertParens(token, false);
+ next = rewriter.insertParens(token, /* includeIdentifier = */ false);
}
return parseArgumentsRest(next);
}
@@ -5211,7 +5267,7 @@
next = token.next;
}
if (!optional('(', next)) {
- next = rewriter.insertParens(token, false);
+ next = rewriter.insertParens(token, /* includeIdentifier = */ false);
}
}
return parseArgumentsRest(next);
@@ -5351,11 +5407,11 @@
Token next = token.next;
if (next.isUserDefinableOperator) {
listener.handleOperator(next);
- listener.endLiteralSymbol(hashToken, 1);
+ listener.endLiteralSymbol(hashToken, /* identifierCount = */ 1);
return next;
} else if (optional('void', next)) {
listener.handleSymbolVoid(next);
- listener.endLiteralSymbol(hashToken, 1);
+ listener.endLiteralSymbol(hashToken, /* identifierCount = */ 1);
return next;
} else {
int count = 1;
@@ -5391,7 +5447,7 @@
} else if (identical(kind, STRING_INTERPOLATION_IDENTIFIER_TOKEN)) {
// Parsing $identifier.
token = parseIdentifierExpression(next);
- listener.handleInterpolationExpression(next, null);
+ listener.handleInterpolationExpression(next, /* rightBracket = */ null);
} else {
break;
}
@@ -5574,7 +5630,7 @@
}
TypeInfo computeTypeAfterIsOrAs(Token token) {
- TypeInfo typeInfo = computeType(token, true);
+ TypeInfo typeInfo = computeType(token, /* required = */ true);
if (typeInfo.isNullable) {
Token next = typeInfo.skipType(token).next;
if (!isOneOfOrEof(
@@ -5662,7 +5718,7 @@
Token constToken = start.next;
assert(optional('const', constToken));
if (!isModifier(constToken.next)) {
- TypeInfo typeInfo = computeType(constToken, false);
+ TypeInfo typeInfo = computeType(constToken, /* required = */ false);
if (typeInfo == noType) {
Token next = constToken.next;
if (!next.isIdentifier) {
@@ -5679,7 +5735,12 @@
}
}
return parseExpressionStatementOrDeclarationAfterModifiers(
- constToken, start, null, constToken, typeInfo, false);
+ constToken,
+ start,
+ /* lateToken = */ null,
+ constToken,
+ typeInfo,
+ /* onlyParseVariableDeclarationStart = */ false);
}
return parseExpressionStatementOrDeclaration(start);
}
@@ -5740,8 +5801,13 @@
}
}
- return parseExpressionStatementOrDeclarationAfterModifiers(token, start,
- lateToken, varFinalOrConst, null, onlyParseVariableDeclarationStart);
+ return parseExpressionStatementOrDeclarationAfterModifiers(
+ token,
+ start,
+ lateToken,
+ varFinalOrConst,
+ /* typeInfo = */ null,
+ onlyParseVariableDeclarationStart);
}
/// See [parseExpressionStatementOrDeclaration]
@@ -5752,7 +5818,7 @@
Token varFinalOrConst,
TypeInfo typeInfo,
bool onlyParseVariableDeclarationStart) {
- typeInfo ??= computeType(beforeType, false);
+ typeInfo ??= computeType(beforeType, /* required = */ false);
Token token = typeInfo.skipType(beforeType);
Token next = token.next;
@@ -5774,13 +5840,17 @@
}
if (!optional('@', start.next)) {
listener.beginMetadataStar(start.next);
- listener.endMetadataStar(0);
+ listener.endMetadataStar(/* count = */ 0);
}
Token beforeFormals =
computeTypeParamOrArg(next).parseVariables(next, this);
listener.beginLocalFunctionDeclaration(start.next);
token = typeInfo.parseType(beforeType, this);
- return parseNamedFunctionRest(token, start.next, beforeFormals, false);
+ return parseNamedFunctionRest(
+ token,
+ start.next,
+ beforeFormals,
+ /* isFunctionExpression = */ false);
}
}
@@ -5876,13 +5946,14 @@
if (!optional('@', start.next)) {
listener.beginMetadataStar(start.next);
- listener.endMetadataStar(0);
+ listener.endMetadataStar(/* count = */ 0);
}
token = typeInfo.parseType(beforeType, this);
next = token.next;
listener.beginVariablesDeclaration(next, lateToken, varFinalOrConst);
if (!onlyParseVariableDeclarationStart) {
- token = parseVariablesDeclarationRest(token, true);
+ token =
+ parseVariablesDeclarationRest(token, /* endWithSemicolon = */ true);
}
return token;
}
@@ -5899,7 +5970,7 @@
listener.endVariablesDeclaration(count, semicolon);
return semicolon;
} else {
- listener.endVariablesDeclaration(count, null);
+ listener.endVariablesDeclaration(count, /* endToken = */ null);
return token;
}
}
@@ -6009,14 +6080,16 @@
// parses the metadata, modifiers, and type of a local variable
// declaration if it exists. This enables capturing [beforeIdentifier]
// for later error reporting.
- return parseExpressionStatementOrDeclaration(leftParenthesis, true);
+ return parseExpressionStatementOrDeclaration(
+ leftParenthesis, /* onlyParseVariableDeclarationStart = */ true);
}
/// Parse the remainder of the local variable declaration
/// or an expression if no local variable declaration was found.
Token parseForLoopPartsMid(Token token, Token awaitToken, Token forToken) {
if (token != forToken.next) {
- token = parseVariablesDeclarationRest(token, false);
+ token =
+ parseVariablesDeclarationRest(token, /* endWithSemicolon = */ false);
listener.handleForInitializerLocalVariableDeclaration(
token, optional('in', token.next));
} else if (optional(';', token.next)) {
@@ -6216,7 +6289,8 @@
/// ;
/// ```
Token parseBlock(Token token, BlockKind blockKind) {
- Token begin = token = ensureBlock(token, null, blockKind.missingBlockName);
+ Token begin = token =
+ ensureBlock(token, /* template = */ null, blockKind.missingBlockName);
listener.beginBlock(begin, blockKind);
int statementCount = 0;
Token startToken = token.next;
@@ -6345,8 +6419,8 @@
throwToken.next, codes.messageMissingExpressionInThrow);
rewriter.insertToken(
throwToken,
- new SyntheticStringToken(
- TokenType.STRING, '""', throwToken.next.charOffset, 0));
+ new SyntheticStringToken(TokenType.STRING, '""',
+ throwToken.next.charOffset, /* _length = */ 0));
}
token = allowCascades
? parseExpression(throwToken)
@@ -6402,7 +6476,8 @@
if (identical(value, 'on')) {
// 'on' type catchPart?
onKeyword = token;
- lastConsumed = computeType(token, true).ensureTypeNotVoid(token, this);
+ lastConsumed = computeType(token, /* required = */ true)
+ .ensureTypeNotVoid(token, this);
token = lastConsumed.next;
value = token.stringValue;
}
@@ -6414,7 +6489,8 @@
Token openParens = catchKeyword.next;
if (!optional("(", openParens)) {
reportRecoverableError(openParens, codes.messageCatchSyntax);
- openParens = rewriter.insertParens(catchKeyword, true);
+ openParens = rewriter.insertParens(
+ catchKeyword, /* includeIdentifier = */ true);
}
Token exceptionName = openParens.next;
@@ -6534,7 +6610,8 @@
/// ;
/// ```
Token parseSwitchBlock(Token token) {
- Token beginSwitch = token = ensureBlock(token, null, 'switch statement');
+ Token beginSwitch =
+ token = ensureBlock(token, /* template = */ null, 'switch statement');
listener.beginSwitchBlock(beginSwitch);
int caseCount = 0;
Token defaultKeyword = null;
@@ -6685,7 +6762,8 @@
// Recovery
reportRecoverableError(
leftParenthesis, codes.templateExpectedButGot.withArguments('('));
- leftParenthesis = rewriter.insertParens(token, true);
+ leftParenthesis =
+ rewriter.insertParens(token, /* includeIdentifier = */ true);
}
token = leftParenthesis;
Token commaToken = null;
@@ -6807,7 +6885,8 @@
Token beforeType,
DeclarationKind kind,
String enclosingDeclarationName) {
- TypeInfo typeInfo = computeType(beforeStart, false, true);
+ TypeInfo typeInfo = computeType(
+ beforeStart, /* required = */ false, /* inDeclaration = */ true);
Token beforeName = typeInfo.skipType(beforeType);
Token next = beforeName.next;
@@ -6825,7 +6904,8 @@
rewriter.insertSyntheticKeyword(beforeName, Keyword.OPERATOR);
// Having inserted the keyword the type now possibly compute differently.
- typeInfo = computeType(beforeStart, true, true);
+ typeInfo = computeType(
+ beforeStart, /* required = */ true, /* inDeclaration = */ true);
beforeName = typeInfo.skipType(beforeType);
next = beforeName.next;
@@ -6851,11 +6931,11 @@
varFinalOrConst,
beforeType,
typeInfo,
- null,
+ /* getOrSet = */ null,
beforeName.next,
kind,
enclosingDeclarationName,
- false);
+ /* nameIsRecovered = */ false);
listener.endMember();
return token;
}
@@ -6915,7 +6995,7 @@
token.next,
kind,
enclosingDeclarationName,
- false);
+ /* nameIsRecovered = */ false);
} else if (token == beforeStart) {
// TODO(danrubel): Provide a more specific error message for extra ';'.
reportRecoverableErrorWithToken(next, codes.templateExpectedClassMember);
@@ -6937,7 +7017,7 @@
token.next,
kind,
enclosingDeclarationName,
- false);
+ /* nameIsRecovered = */ false);
}
listener.endMember();
@@ -7074,7 +7154,7 @@
if (token.previous != null) {
return token.previous;
}
- Token before = new Token.eof(-1);
+ Token before = new Token.eof(/* offset = */ -1);
before.next = token;
return before;
}
@@ -7119,7 +7199,7 @@
int length = comment.length;
int start = 3;
bool inCodeBlock = false;
- int codeBlock = comment.indexOf('```', 3);
+ int codeBlock = comment.indexOf('```', /* start = */ 3);
if (codeBlock == -1) {
codeBlock = length;
}
@@ -7156,11 +7236,12 @@
while (token != null && !token.isEof) {
String comment = token.lexeme;
if (comment.startsWith('///')) {
- if (comment.indexOf('```', 3) != -1) {
+ if (comment.indexOf('```', /* start = */ 3) != -1) {
inCodeBlock = !inCodeBlock;
}
if (!inCodeBlock && !comment.startsWith('/// ')) {
- count += parseCommentReferencesInText(token, 3, comment.length);
+ count += parseCommentReferencesInText(
+ token, /* start = */ 3, comment.length);
}
}
token = token.next;
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_main.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_main.dart
index eadd81c..a560e01 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_main.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_main.dart
@@ -33,7 +33,7 @@
mainEntryPoint(List<String> arguments) async {
for (String argument in arguments) {
if (argument.startsWith("@")) {
- Uri uri = Uri.base.resolve(argument.substring(1));
+ Uri uri = Uri.base.resolve(argument.substring(/* startIndex = */ 1));
await for (String file in new File.fromUri(uri)
.openRead()
.cast<List<int>>()
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart b/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
index f5aca05..d4928a5 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/quote.dart
@@ -92,7 +92,7 @@
case Quote.MultiLineSingle:
case Quote.MultiLineDouble:
- return lengthOfOptionalWhitespacePrefix(first, 3);
+ return lengthOfOptionalWhitespacePrefix(first, /* start = */ 3);
case Quote.RawSingle:
case Quote.RawDouble:
@@ -100,7 +100,7 @@
case Quote.RawMultiLineSingle:
case Quote.RawMultiLineDouble:
- return lengthOfOptionalWhitespacePrefix(first, 4);
+ return lengthOfOptionalWhitespacePrefix(first, /* start = */ 4);
}
return throw new UnsupportedError("'$quote' in firstQuoteLength");
}
@@ -131,7 +131,8 @@
String unescapeLastStringPart(String last, Quote quote, Object location,
bool isLastQuoteSynthetic, UnescapeErrorListener listener) {
int end = last.length - (isLastQuoteSynthetic ? 0 : lastQuoteLength(quote));
- return unescape(last.substring(0, end), quote, location, listener);
+ return unescape(
+ last.substring(/* startIndex = */ 0, end), quote, location, listener);
}
String unescapeString(
@@ -154,13 +155,15 @@
case Quote.Double:
return !string.contains("\\")
? string
- : unescapeCodeUnits(string.codeUnits, false, location, listener);
+ : unescapeCodeUnits(
+ string.codeUnits, /* isRaw = */ false, location, listener);
case Quote.MultiLineSingle:
case Quote.MultiLineDouble:
return !string.contains("\\") && !string.contains("\r")
? string
- : unescapeCodeUnits(string.codeUnits, false, location, listener);
+ : unescapeCodeUnits(
+ string.codeUnits, /* isRaw = */ false, location, listener);
case Quote.RawSingle:
case Quote.RawDouble:
@@ -170,7 +173,8 @@
case Quote.RawMultiLineDouble:
return !string.contains("\r")
? string
- : unescapeCodeUnits(string.codeUnits, true, location, listener);
+ : unescapeCodeUnits(
+ string.codeUnits, /* isRaw = */ true, location, listener);
}
return throw new UnsupportedError("'$quote' in unescape");
}
@@ -193,7 +197,7 @@
} else if (!isRaw && code == $BACKSLASH) {
if (codeUnits.length == ++i) {
listener.handleUnescapeError(
- codes.messageInvalidUnicodeEscape, location, i, 1);
+ codes.messageInvalidUnicodeEscape, location, i, /* length = */ 1);
return new String.fromCharCodes(codeUnits);
}
code = codeUnits[i];
@@ -296,5 +300,5 @@
}
result[resultOffset++] = code;
}
- return new String.fromCharCodes(result, 0, resultOffset);
+ return new String.fromCharCodes(result, /* start = */ 0, resultOffset);
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
index d59eae1..b5b58a5 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
@@ -91,8 +91,8 @@
if (token != null) {
// If offset is available report and internal problem to show the
// parsed code in the output.
- throw internalProblem(
- new Message(null, message: message), token.charOffset, uri);
+ throw internalProblem(new Message(/* code = */ null, message: message),
+ token.charOffset, uri);
} else {
throw message;
}
@@ -191,8 +191,8 @@
if (token != null) {
// If offset is available report and internal problem to show the
// parsed code in the output.
- throw internalProblem(
- new Message(null, message: message), token.charOffset, uri);
+ throw internalProblem(new Message(/* code = */ null, message: message),
+ token.charOffset, uri);
} else {
throw message;
}
@@ -213,7 +213,7 @@
if (node == null) {
internalProblem(
templateInternalProblemUnhandled.withArguments("null", "push"),
- -1,
+ /* charOffset = */ -1,
uri);
}
stack.push(node);
@@ -243,7 +243,7 @@
String s = " $o";
int index = s.indexOf("\n");
if (index != -1) {
- s = s.substring(0, index) + "...";
+ s = s.substring(/* startIndex = */ 0, index) + "...";
}
print(s);
}
@@ -255,7 +255,7 @@
printEvent(name);
internalProblem(
templateInternalProblemUnhandled.withArguments(name, "$runtimeType"),
- -1,
+ /* charOffset = */ -1,
uri);
}
@@ -518,7 +518,7 @@
}
class StackImpl implements Stack {
- List<Object> array = new List<Object>(8);
+ List<Object> array = new List<Object>(/* length = */ 8);
int arrayLength = 0;
bool get isNotEmpty => arrayLength > 0;
@@ -582,14 +582,14 @@
List<Object> get values {
final int length = arrayLength;
final List<Object> list = new List<Object>(length);
- list.setRange(0, length, array);
+ list.setRange(/* start = */ 0, length, array);
return list;
}
void _grow() {
final int length = array.length;
final List<Object> newArray = new List<Object>(length * 2);
- newArray.setRange(0, length, array, 0);
+ newArray.setRange(/* start = */ 0, length, array, /* skipCount = */ 0);
array = newArray;
}
}
@@ -624,7 +624,7 @@
Object pop(NullValue nullValue) {
Object result = realStack.pop(nullValue);
latestStacktraces.clear();
- latestStacktraces.add(stackTraceStack.pop(null));
+ latestStacktraces.add(stackTraceStack.pop(/* nullValue = */ null));
return result;
}
@@ -632,7 +632,7 @@
List<Object> popList(int count, List<Object> list, NullValue nullValue) {
List<Object> result = realStack.popList(count, list, nullValue);
latestStacktraces.length = count;
- stackTraceStack.popList(count, latestStacktraces, null);
+ stackTraceStack.popList(count, latestStacktraces, /* nullValue = */ null);
return result;
}
@@ -671,7 +671,9 @@
List<T> pop(Stack stack, int count, [NullValue nullValue]) {
return stack.popList(
- count, new List<T>.filled(count, null, growable: true), nullValue);
+ count,
+ new List<T>.filled(count, /* fill = */ null, growable: true),
+ nullValue);
}
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart b/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
index ac26b16..cc5cbce 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/token_stream_rewriter.dart
@@ -28,7 +28,9 @@
next = new SyntheticBeginToken(TokenType.OPEN_PAREN, offset);
if (includeIdentifier) {
next = _setNext(
- next, new SyntheticStringToken(TokenType.IDENTIFIER, '', offset, 0));
+ next,
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER, '', offset, /* _length = */ 0));
}
next = _setNext(next, new SyntheticToken(TokenType.CLOSE_PAREN, offset));
_setEndGroup(leftParen, next);
@@ -175,8 +177,8 @@
BeginToken leftParen =
next = new SyntheticBeginToken(TokenType.OPEN_PAREN, offset);
if (includeIdentifier) {
- Token identifier =
- new SyntheticStringToken(TokenType.IDENTIFIER, '', offset, 0);
+ Token identifier = new SyntheticStringToken(
+ TokenType.IDENTIFIER, '', offset, /* _length = */ 0);
next.next = identifier;
next = identifier;
}
@@ -253,8 +255,8 @@
Token insertSyntheticIdentifier(Token token, [String value]) {
return insertToken(
token,
- new SyntheticStringToken(
- TokenType.IDENTIFIER, value ?? '', token.next.charOffset, 0));
+ new SyntheticStringToken(TokenType.IDENTIFIER, value ?? '',
+ token.next.charOffset, /* _length = */ 0));
}
/// Insert a new synthetic [keyword] after [token] and return the new token.
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 84964e7..ec8e355 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
@@ -171,7 +171,7 @@
listener.handleQualified(period);
listener.handleNoTypeArguments(token.next);
- listener.handleType(start, null);
+ listener.handleType(start, /* questionMark = */ null);
return token;
}
@@ -244,7 +244,7 @@
}
Token parseTypeRest(Token start, Token token, Parser parser) {
- parser.listener.handleType(start, null);
+ parser.listener.handleType(start, /* questionMark = */ null);
return token;
}
@@ -315,7 +315,7 @@
}
Token parseTypeRest(Token token, Parser parser) {
- parser.listener.handleType(token, null);
+ parser.listener.handleType(token, /* questionMark = */ null);
return token;
}
@@ -487,7 +487,8 @@
final List<Token> typeVariableEndGroups = <Token>[];
for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
typeVariableEndGroups.add(
- computeTypeParamOrArg(t.head, true).parseVariables(t.head, parser));
+ computeTypeParamOrArg(t.head, /* inDeclaration = */ true)
+ .parseVariables(t.head, parser));
parser.listener.beginFunctionType(start);
}
@@ -692,7 +693,8 @@
while (optional('Function', token)) {
Token typeVariableStart = token;
// TODO(danrubel): Consider caching TypeParamOrArgInfo
- token = computeTypeParamOrArg(token, true).skip(token);
+ token =
+ computeTypeParamOrArg(token, /* inDeclaration = */ true).skip(token);
token = token.next;
if (!optional('(', token)) {
break; // Not a function type.
@@ -770,7 +772,7 @@
Listener listener = parser.listener;
listener.beginTypeArguments(beginGroup);
simpleType.parseType(beginGroup, parser);
- parser.listener.endTypeArguments(1, beginGroup, endGroup);
+ parser.listener.endTypeArguments(/* count = */ 1, beginGroup, endGroup);
return endGroup;
}
@@ -783,12 +785,16 @@
Listener listener = parser.listener;
listener.beginTypeVariables(beginGroup);
listener.beginMetadataStar(token);
- listener.endMetadataStar(0);
+ listener.endMetadataStar(/* count = */ 0);
listener.handleIdentifier(token, IdentifierContext.typeVariableDeclaration);
listener.beginTypeVariable(token);
- listener.handleTypeVariablesDefined(token, 1);
+ listener.handleTypeVariablesDefined(token, /* count = */ 1);
listener.handleNoType(token);
- listener.endTypeVariable(endGroup, 0, null, null);
+ listener.endTypeVariable(
+ endGroup,
+ /* index = */ 0,
+ /* extendsOrSuper = */ null,
+ /* variance = */ null);
listener.endTypeVariables(beginGroup, endGroup);
return endGroup;
}
@@ -898,11 +904,12 @@
Token next = start;
typeArgumentCount = 0;
while (true) {
- TypeInfo typeInfo = computeType(next, true, inDeclaration);
+ TypeInfo typeInfo =
+ computeType(next, /* required = */ true, inDeclaration);
if (typeInfo == noType) {
while (typeInfo == noType && optional('@', next.next)) {
next = skipMetadata(next);
- typeInfo = computeType(next, true, inDeclaration);
+ typeInfo = computeType(next, /* required = */ true, inDeclaration);
}
if (typeInfo == noType) {
if (next == start && !inDeclaration && !isCloser(next.next)) {
@@ -921,7 +928,8 @@
token = typeInfo.skipType(next);
next = token.next;
if (optional('extends', next)) {
- token = computeType(next, true, inDeclaration).skipType(next);
+ token = computeType(next, /* required = */ true, inDeclaration)
+ .skipType(next);
next = token.next;
}
if (!optional(',', next)) {
@@ -967,14 +975,15 @@
parser.listener.beginTypeArguments(start);
int count = 0;
while (true) {
- TypeInfo typeInfo = computeType(next, true, inDeclaration);
+ TypeInfo typeInfo =
+ computeType(next, /* required = */ true, inDeclaration);
if (typeInfo == noType) {
// Recovery
while (typeInfo == noType && optional('@', next.next)) {
parser.reportRecoverableErrorWithToken(
next.next, codes.templateUnexpectedToken);
next = skipMetadata(next);
- typeInfo = computeType(next, true, inDeclaration);
+ typeInfo = computeType(next, /* required = */ true, inDeclaration);
}
// Fall through to process type (if any) and consume `,`
}
@@ -988,7 +997,7 @@
// Recovery
if (!looksLikeTypeParamOrArg(inDeclaration, next)) {
- token = parseUnexpectedEnd(token, true, parser);
+ token = parseUnexpectedEnd(token, /* isArguments = */ true, parser);
break;
}
// Missing comma. Report error, insert comma, and continue looping.
@@ -1036,7 +1045,7 @@
token = variance;
} else {
- variances = variances.prepend(null);
+ variances = variances.prepend(/* element = */ null);
}
next = parser.ensureIdentifier(
@@ -1047,12 +1056,13 @@
next = token.next;
if (optional('extends', next)) {
- TypeInfo typeInfo = computeType(next, true, inDeclaration);
+ TypeInfo typeInfo =
+ computeType(next, /* required = */ true, inDeclaration);
token = typeInfo.skipType(next);
next = token.next;
superTypeInfos = superTypeInfos.prepend(typeInfo);
} else {
- superTypeInfos = superTypeInfos.prepend(null);
+ superTypeInfos = superTypeInfos.prepend(/* element = */ null);
}
++count;
@@ -1104,7 +1114,7 @@
}
if (!parseCloser(token)) {
- token = parseUnexpectedEnd(token, false, parser);
+ token = parseUnexpectedEnd(token, /* isArguments = */ false, parser);
}
Token endGroup = token.next;
listener.endTypeVariables(start, endGroup);
@@ -1143,7 +1153,7 @@
optional('dynamic', next) ||
optional('void', next) ||
optional('Function', next)) {
- TypeInfo invalidType = computeType(token, true);
+ TypeInfo invalidType = computeType(token, /* required = */ true);
if (invalidType != noType) {
if (!errorReported) {
parser.reportRecoverableError(
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
index bd67253..a18c954 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
@@ -89,7 +89,7 @@
* is not exposed to clients of the scanner, which are expected to invoke
* [firstToken] to access the token stream.
*/
- final Token tokens = new Token.eof(-1);
+ final Token tokens = new Token.eof(/* offset = */ -1);
/**
* A pointer to the last scanned token.
@@ -802,7 +802,7 @@
if (identical($r, next)) {
return tokenizeRawStringKeywordOrIdentifier(next);
}
- return tokenizeKeywordOrIdentifier(next, true);
+ return tokenizeKeywordOrIdentifier(next, /* allowDollar = */ true);
}
if (identical(next, $CLOSE_PAREN)) {
@@ -849,11 +849,11 @@
}
if (identical(next, $DQ) || identical(next, $SQ)) {
- return tokenizeString(next, scanOffset, false);
+ return tokenizeString(next, scanOffset, /* raw = */ false);
}
if (identical(next, $_)) {
- return tokenizeKeywordOrIdentifier(next, true);
+ return tokenizeKeywordOrIdentifier(next, /* allowDollar = */ true);
}
if (identical(next, $COLON)) {
@@ -911,7 +911,7 @@
}
if (identical(next, $$)) {
- return tokenizeKeywordOrIdentifier(next, true);
+ return tokenizeKeywordOrIdentifier(next, /* allowDollar = */ true);
}
if (identical(next, $MINUS)) {
@@ -1217,7 +1217,7 @@
return tokenizeFractionPart(advance(), start);
}
}
- appendSubstringToken(TokenType.INT, start, true);
+ appendSubstringToken(TokenType.INT, start, /* asciiOnly = */ true);
return next;
}
}
@@ -1247,10 +1247,11 @@
messageExpectedHexDigit, start, stringOffset));
// Recovery
appendSyntheticSubstringToken(
- TokenType.HEXADECIMAL, start, true, "0");
+ TokenType.HEXADECIMAL, start, /* asciiOnly = */ true, "0");
return next;
}
- appendSubstringToken(TokenType.HEXADECIMAL, start, true);
+ appendSubstringToken(
+ TokenType.HEXADECIMAL, start, /* asciiOnly = */ true);
return next;
}
}
@@ -1301,7 +1302,8 @@
hasExponentDigits = true;
} else {
if (!hasExponentDigits) {
- appendSyntheticSubstringToken(TokenType.DOUBLE, start, true, '0');
+ appendSyntheticSubstringToken(
+ TokenType.DOUBLE, start, /* asciiOnly = */ true, '0');
prependErrorToken(new UnterminatedToken(
messageMissingExponent, tokenStart, stringOffset));
return next;
@@ -1321,7 +1323,8 @@
}
if (!hasDigit) {
// Reduce offset, we already advanced to the token past the period.
- appendSubstringToken(TokenType.INT, start, true, -1);
+ appendSubstringToken(
+ TokenType.INT, start, /* asciiOnly = */ true, /* extraOffset = */ -1);
// TODO(ahe): Wrong offset for the period. Cannot call beginToken because
// the scanner already advanced past the period.
@@ -1332,7 +1335,7 @@
appendPrecedenceToken(TokenType.PERIOD);
return next;
}
- appendSubstringToken(TokenType.DOUBLE, start, true);
+ appendSubstringToken(TokenType.DOUBLE, start, /* asciiOnly = */ true);
return next;
}
@@ -1367,23 +1370,23 @@
next = advance();
}
if (!identical($AT, next)) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
next = advance();
if (!identical($d, next)) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
next = advance();
if (!identical($a, next)) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
next = advance();
if (!identical($r, next)) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
next = advance();
if (!identical($t, next)) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
next = advance();
@@ -1392,7 +1395,7 @@
next = advance();
}
if (!identical($EQ, next)) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
next = advance();
@@ -1407,12 +1410,12 @@
next = advance();
}
if (scanOffset == majorStart) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
// minor
if (!identical($PERIOD, next)) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
next = advance();
int minor = 0;
@@ -1422,7 +1425,7 @@
next = advance();
}
if (scanOffset == minorStart) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
// trailing spaces
@@ -1430,7 +1433,7 @@
next = advance();
}
if (next != $LF && next != $CR && next != $EOF) {
- return tokenizeSingleLineCommentRest(next, start, false);
+ return tokenizeSingleLineCommentRest(next, start, /* dartdoc = */ false);
}
LanguageVersionToken languageVersion =
@@ -1486,7 +1489,7 @@
if (!asciiOnlyLines) handleUnicode(unicodeStart);
prependErrorToken(new UnterminatedToken(
messageUnterminatedComment, tokenStart, stringOffset));
- advanceAfterError(true);
+ advanceAfterError(/* shouldAdvance = */ true);
break;
} else if (identical($STAR, next)) {
next = advance();
@@ -1579,9 +1582,9 @@
if (identical(nextnext, $DQ) || identical(nextnext, $SQ)) {
int start = scanOffset;
next = advance();
- return tokenizeString(next, start, true);
+ return tokenizeString(next, start, /* raw = */ true);
}
- return tokenizeKeywordOrIdentifier(next, true);
+ return tokenizeKeywordOrIdentifier(next, /* allowDollar = */ true);
}
int tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
@@ -1635,7 +1638,8 @@
if (start == scanOffset) {
return unexpected(next);
} else {
- appendSubstringToken(TokenType.IDENTIFIER, start, true);
+ appendSubstringToken(
+ TokenType.IDENTIFIER, start, /* asciiOnly = */ true);
}
break;
}
@@ -1658,7 +1662,7 @@
return tokenizeMultiLineString(quoteChar, start, raw);
} else {
// Empty string.
- appendSubstringToken(TokenType.STRING, start, true);
+ appendSubstringToken(TokenType.STRING, start, /* asciiOnly = */ true);
return next;
}
}
@@ -1748,10 +1752,11 @@
$A <= next && next <= $Z ||
identical(next, $_)) {
beginToken(); // The identifier starts here.
- next = tokenizeKeywordOrIdentifier(next, false);
+ next = tokenizeKeywordOrIdentifier(next, /* allowDollar = */ false);
} else {
beginToken(); // The synthetic identifier starts here.
- appendSyntheticSubstringToken(TokenType.IDENTIFIER, scanOffset, true, '');
+ appendSyntheticSubstringToken(
+ TokenType.IDENTIFIER, scanOffset, /* asciiOnly = */ true, '');
prependErrorToken(new UnterminatedToken(
messageUnexpectedDollarInString, tokenStart, stringOffset));
}
@@ -1892,8 +1897,8 @@
}
codeUnits.add(errorToken.character);
prependErrorToken(errorToken);
- int next = advanceAfterError(true);
- while (_isIdentifierChar(next, true)) {
+ int next = advanceAfterError(/* shouldAdvance = */ true);
+ while (_isIdentifierChar(next, /* allowDollar = */ true)) {
codeUnits.add(next);
next = advance();
}
@@ -1902,7 +1907,7 @@
return next;
} else {
prependErrorToken(errorToken);
- return advanceAfterError(true);
+ return advanceAfterError(/* shouldAdvance = */ true);
}
}
@@ -1962,7 +1967,7 @@
}
// The first line starts at character offset 0.
- add(0);
+ add(/* value = */ 0);
}
// Implement abstract members used by [ListMixin]
@@ -1991,7 +1996,7 @@
// Specialize methods from [ListMixin].
void add(int value) {
if (arrayLength >= array.length) {
- grow(0);
+ grow(/* newLengthMinimum = */ 0);
}
if (value > 65535 && array is! Uint32List) {
switchToUint32(array.length);
@@ -2007,7 +2012,7 @@
if (array is Uint16List) {
final Uint16List newArray = new Uint16List(newLength);
- newArray.setRange(0, arrayLength, array);
+ newArray.setRange(/* start = */ 0, arrayLength, array);
array = newArray;
} else {
switchToUint32(newLength);
@@ -2016,7 +2021,7 @@
void switchToUint32(int newLength) {
final Uint32List newArray = new Uint32List(newLength);
- newArray.setRange(0, arrayLength, array);
+ newArray.setRange(/* start = */ 0, arrayLength, array);
array = newArray;
}
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/io.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/io.dart
index 93b0141..04f95e9 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/io.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/io.dart
@@ -17,7 +17,7 @@
int length = file.lengthSync();
// +1 to have a 0 terminated list, see [Scanner].
list = new Uint8List(length + 1);
- file.readIntoSync(list, 0, length);
+ file.readIntoSync(list, /* start = */ 0, length);
} finally {
file.closeSync();
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
index 0899d1f..b4620e3 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/keyword_state.dart
@@ -25,7 +25,11 @@
strings[i] = analyzer.Keyword.values[i].lexeme;
}
strings.sort((a, b) => a.compareTo(b));
- _KEYWORD_STATE = computeKeywordStateTable(0, strings, 0, strings.length);
+ _KEYWORD_STATE = computeKeywordStateTable(
+ /* start = */ 0,
+ strings,
+ /* offset = */ 0,
+ strings.length);
}
return _KEYWORD_STATE;
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart
index 12cdd53..a42b728 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart
@@ -35,8 +35,8 @@
*/
StringToken.fromString(TokenType type, String value, int charOffset,
{bool canonicalize: false, analyzer.CommentToken precedingComments})
- : valueOrLazySubstring =
- canonicalizedString(value, 0, value.length, canonicalize),
+ : valueOrLazySubstring = canonicalizedString(
+ value, /* start = */ 0, value.length, canonicalize),
super(type, charOffset, precedingComments);
/**
@@ -108,7 +108,7 @@
static String canonicalizedString(
String s, int start, int end, bool canonicalize) {
if (!canonicalize) return s;
- return canonicalizer.canonicalize(s, start, end, false);
+ return canonicalizer.canonicalize(s, start, end, /* asciiOnly = */ false);
}
static String decodeUtf8(List<int> data, int start, int end, bool asciiOnly) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/utf8_bytes_scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/utf8_bytes_scanner.dart
index 97191c6..f55b9ee 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/utf8_bytes_scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/utf8_bytes_scanner.dart
@@ -91,7 +91,7 @@
numberOfBytesHint: bytes.length) {
assert(bytes.last == 0);
// Skip a leading BOM.
- if (containsBomAt(0)) {
+ if (containsBomAt(/* offset = */ 0)) {
byteOffset += 3;
utf8Slack += 3;
}
@@ -165,7 +165,7 @@
utf8Slack += (numBytes - 1);
scanSlack = numBytes - 1;
scanSlackOffset = byteOffset;
- return codePoint.codeUnitAt(0);
+ return codePoint.codeUnitAt(/* index = */ 0);
} else if (codePoint.length == 2) {
utf8Slack += (numBytes - 2);
scanSlack = numBytes - 1;
diff --git a/pkg/_fe_analyzer_shared/lib/src/sdk/allowed_experiments.dart b/pkg/_fe_analyzer_shared/lib/src/sdk/allowed_experiments.dart
new file mode 100644
index 0000000..a7faa11
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/lib/src/sdk/allowed_experiments.dart
@@ -0,0 +1,220 @@
+// 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:convert';
+
+import 'package:meta/meta.dart';
+
+/// Parse the given [jsonText] into the [AllowedExperiments].
+///
+/// Throw [FormatException] is any format issues are found.
+AllowedExperiments parseAllowedExperiments(String jsonText) {
+ return new _AllowedExperimentsParser(jsonText).parse();
+}
+
+/// The set of experiments enabled for SDK and packages.
+class AllowedExperiments {
+ /// The set of experiments that are enabled for all SDK libraries other than
+ /// for those which are specified in [sdkLibraryExperiments].
+ final List<String> sdkDefaultExperiments;
+
+ /// Mapping from individual SDK libraries, e.g. 'core', to the set of
+ /// experiments that are enabled for this library.
+ final Map<String, List<String>> sdkLibraryExperiments;
+
+ /// Mapping from package names, e.g. 'path', to the set of experiments that
+ /// are enabled for all files of this package.
+ final Map<String, List<String>> packageExperiments;
+
+ AllowedExperiments({
+ @required this.sdkDefaultExperiments,
+ @required this.sdkLibraryExperiments,
+ @required this.packageExperiments,
+ });
+
+ /// Return the set of enabled experiments for the package with the [name],
+ /// e.g. "path", possibly `null`.
+ List<String> forPackage(String name) {
+ return packageExperiments[name];
+ }
+
+ /// Return the set of enabled experiments for the library with the [name],
+ /// e.g. "core".
+ List<String> forSdkLibrary(String name) {
+ return sdkLibraryExperiments[name] ?? sdkDefaultExperiments;
+ }
+}
+
+class _AllowedExperimentsParser {
+ final String _jsonText;
+ final List<String> _parsePath = [];
+ final Map<String, List<String>> _experimentSets = {};
+
+ _AllowedExperimentsParser(this._jsonText);
+
+ AllowedExperiments parse() {
+ Object rootObject = json.decode(_jsonText);
+ Map<String, Object> map = _mustBeMap(rootObject);
+
+ _ensureVersion(map);
+
+ _withParsePath('experimentSets', () {
+ Map<String, Object> experimentSetMap =
+ _requiredMap(map, 'experimentSets');
+ for (MapEntry<String, Object> entry in experimentSetMap.entries) {
+ String setName = entry.key;
+ _withParsePath(setName, () {
+ _experimentSets[setName] = _mustBeListOfStrings(entry.value);
+ });
+ }
+ });
+
+ List<String> sdkDefaultExperimentSet = <String>[];
+ Map<String, List<String>> sdkLibraryExperiments = <String, List<String>>{};
+ _withParsePath('sdk', () {
+ Map<String, Object> sdkMap = _requiredMap(map, 'sdk');
+
+ _withParsePath('default', () {
+ sdkDefaultExperimentSet = _experimentList(
+ _requiredMap(sdkMap, 'default'),
+ );
+ });
+
+ _withParsePath('libraries', () {
+ Map<String, Object> sdkLibraryExperimentsMap =
+ _optionalMap(sdkMap, 'libraries');
+ if (sdkLibraryExperimentsMap != null) {
+ for (MapEntry<String, Object> entry
+ in sdkLibraryExperimentsMap.entries) {
+ String libraryName = entry.key;
+ _withParsePath(libraryName, () {
+ Map<String, Object> libraryMap = _mustBeMap(entry.value);
+ List<String> experimentList = _experimentList(libraryMap);
+ sdkLibraryExperiments[libraryName] = experimentList;
+ });
+ }
+ }
+ });
+ });
+
+ Map<String, List<String>> packageExperiments = <String, List<String>>{};
+ _withParsePath('packages', () {
+ Map<String, Object> packageExperimentsMap = _optionalMap(map, 'packages');
+ if (packageExperimentsMap != null) {
+ for (MapEntry<String, Object> entry in packageExperimentsMap.entries) {
+ String packageName = entry.key;
+ _withParsePath(packageName, () {
+ Map<String, Object> libraryMap = _mustBeMap(entry.value);
+ List<String> experimentList = _experimentList(libraryMap);
+ packageExperiments[packageName] = experimentList;
+ });
+ }
+ }
+ });
+
+ return new AllowedExperiments(
+ sdkDefaultExperiments: sdkDefaultExperimentSet,
+ sdkLibraryExperiments: sdkLibraryExperiments,
+ packageExperiments: packageExperiments,
+ );
+ }
+
+ void _ensureVersion(Map<String, Object> map) {
+ Object versionObject = map['version'];
+ if (versionObject is! int || versionObject != 1) {
+ throw new FormatException(
+ "Expected field 'version' with value '1'; "
+ "actually ${versionObject.runtimeType}: $versionObject",
+ _jsonText,
+ );
+ }
+ }
+
+ List<String> _experimentList(Map<String, Object> map) {
+ String experimentSetName = _requiredString(map, 'experimentSet');
+ List<String> result = _experimentSets[experimentSetName];
+ if (result != null) {
+ return result;
+ }
+
+ throw new FormatException(
+ "No experiment set '$experimentSetName in $_experimentSets",
+ _jsonText,
+ );
+ }
+
+ List<String> _mustBeListOfStrings(Object object) {
+ if (object is List<Object> && object.every((e) => e is String)) {
+ return List.castFrom(object);
+ }
+
+ String path = _parsePath.join(' / ');
+ throw new FormatException(
+ "Expected list of strings at $path, "
+ "actually ${object.runtimeType}: $object",
+ _jsonText,
+ );
+ }
+
+ Map<String, Object> _mustBeMap(Object object) {
+ if (object is Map<String, Object>) {
+ return object;
+ }
+
+ String path = _parsePath.isNotEmpty ? _parsePath.join(' / ') : 'root';
+ throw new FormatException(
+ "Expected map at $path, "
+ "actually ${object.runtimeType}: $object",
+ _jsonText,
+ );
+ }
+
+ Map<String, Object> _optionalMap(Map<String, Object> map, String name) {
+ Object result = map[name];
+ if (result == null || result is Map<String, Object>) {
+ return result;
+ }
+
+ String path = _parsePath.join(' / ');
+ throw new FormatException(
+ "Expected map at $path, actually ${result.runtimeType}: $result",
+ _jsonText,
+ );
+ }
+
+ Map<String, Object> _requiredMap(Map<String, Object> map, String name) {
+ Object result = map[name];
+ if (result is Map<String, Object>) {
+ return result;
+ }
+
+ String path = _parsePath.join(' / ');
+ throw new FormatException(
+ "Expected map at $path, actually ${result.runtimeType}: $result",
+ _jsonText,
+ );
+ }
+
+ String _requiredString(Map<String, Object> map, String name) {
+ Object result = map[name];
+ if (result is String) {
+ return result;
+ }
+
+ String path = _parsePath.join(' / ');
+ throw new FormatException(
+ "Expected string at $path, actually ${result.runtimeType}: $result",
+ _jsonText,
+ );
+ }
+
+ void _withParsePath(String name, void Function() f) {
+ _parsePath.add(name);
+ try {
+ f();
+ } finally {
+ _parsePath.removeLast();
+ }
+ }
+}
diff --git a/pkg/_fe_analyzer_shared/test/sdk/allowed_experiments_test.dart b/pkg/_fe_analyzer_shared/test/sdk/allowed_experiments_test.dart
new file mode 100644
index 0000000..ad70c28
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/sdk/allowed_experiments_test.dart
@@ -0,0 +1,279 @@
+// 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:_fe_analyzer_shared/src/sdk/allowed_experiments.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+
+main() {
+ group('invalid', () {
+ void assertFormalException(String text) {
+ expect(() {
+ return parseAllowedExperiments(text);
+ }, throwsFormatException);
+ }
+
+ test('not map', () {
+ assertFormalException('42');
+ });
+
+ test('no version', () {
+ assertFormalException('{}');
+ });
+
+ test('version not int', () {
+ assertFormalException('''
+{
+ "version": "abc"
+}
+''');
+ });
+
+ test('version not int 1', () {
+ assertFormalException('''
+{
+ "version": 2
+}
+''');
+ });
+
+ test('no experiment sets', () {
+ assertFormalException('''
+{
+ "version": 1,
+}
+''');
+ });
+
+ test('experimentSet: not map', () {
+ assertFormalException('''
+{
+ "version": 1,
+ "experimentSets": 42
+}
+''');
+ });
+
+ test('experimentSet entry: not list', () {
+ assertFormalException('''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": 42
+ }
+}
+''');
+ });
+
+ test('no sdk', () {
+ assertFormalException('''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ }
+}
+''');
+ });
+
+ test('no sdk / default', () {
+ assertFormalException('''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {}
+}
+''');
+ });
+
+ test('experimentSet not string', () {
+ assertFormalException('''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": 42
+ }
+ }
+}
+''');
+ });
+
+ test('experimentSet not defined', () {
+ assertFormalException('''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "notDefined"
+ }
+ }
+}
+''');
+ });
+
+ test('sdk libraries not map', () {
+ assertFormalException('''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "nullSafety"
+ },
+ "libraries": 42
+ }
+}
+''');
+ });
+
+ test('packages not map', () {
+ assertFormalException('''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "nullSafety"
+ }
+ },
+ "packages": 42
+}
+''');
+ });
+ });
+
+ group('valid', () {
+ void assertExperiments(
+ AllowedExperiments experiments, {
+ @required List<String> sdkDefaultExperiments,
+ @required Map<String, List<String>> sdkLibraryExperiments,
+ @required Map<String, List<String>> packageExperiments,
+ }) {
+ expect(experiments.sdkDefaultExperiments, sdkDefaultExperiments);
+ expect(experiments.sdkLibraryExperiments, sdkLibraryExperiments);
+ expect(experiments.packageExperiments, packageExperiments);
+ }
+
+ test('sdk default, no sdk libraries, no packages', () {
+ var experiments = parseAllowedExperiments('''
+{
+ "version": 1,
+ "experimentSets": {
+ "foo": ["foo1"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "foo"
+ }
+ }
+}
+''');
+ assertExperiments(
+ experiments,
+ sdkDefaultExperiments: ['foo1'],
+ sdkLibraryExperiments: {},
+ packageExperiments: {},
+ );
+ });
+
+ test('sdk default, sdk libraries, no packages', () {
+ var experiments = parseAllowedExperiments('''
+{
+ "version": 1,
+ "experimentSets": {
+ "foo": ["foo1"],
+ "bar": ["bar1", "bar2"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "foo"
+ },
+ "libraries": {
+ "sdkA": {
+ "experimentSet": "foo"
+ },
+ "sdkB": {
+ "experimentSet": "bar"
+ }
+ }
+ }
+}
+''');
+ assertExperiments(
+ experiments,
+ sdkDefaultExperiments: ['foo1'],
+ sdkLibraryExperiments: {
+ "sdkA": ['foo1'],
+ "sdkB": ['bar1', 'bar2'],
+ },
+ packageExperiments: {},
+ );
+ });
+
+ test('sdk default, sdk libraries, packages', () {
+ var experiments = parseAllowedExperiments('''
+{
+ "version": 1,
+ "experimentSets": {
+ "foo": ["foo1"],
+ "bar": ["bar1", "bar2"],
+ "baz": ["baz1", "baz2"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "foo"
+ },
+ "libraries": {
+ "sdkA": {
+ "experimentSet": "bar"
+ },
+ "sdkB": {
+ "experimentSet": "baz"
+ }
+ }
+ },
+ "packages": {
+ "pkgA": {
+ "experimentSet": "bar"
+ },
+ "pkgB": {
+ "experimentSet": "baz"
+ }
+ }
+}
+''');
+ assertExperiments(
+ experiments,
+ sdkDefaultExperiments: ['foo1'],
+ sdkLibraryExperiments: {
+ "sdkA": ['bar1', 'bar2'],
+ "sdkB": ['baz1', 'baz2'],
+ },
+ packageExperiments: {
+ "pkgA": ['bar1', 'bar2'],
+ "pkgB": ['baz1', 'baz2'],
+ },
+ );
+ expect(experiments.forSdkLibrary('core'), ['foo1']);
+ expect(experiments.forSdkLibrary('sdkA'), ['bar1', 'bar2']);
+ expect(experiments.forSdkLibrary('sdkB'), ['baz1', 'baz2']);
+ expect(experiments.forPackage('pkgA'), ['bar1', 'bar2']);
+ expect(experiments.forPackage('pkgB'), ['baz1', 'baz2']);
+ expect(experiments.forPackage('pkgC'), isNull);
+ });
+ });
+}
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 31adb88..78b4b44 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -7,7 +7,6 @@
import 'dart:io' as io;
import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/api_for_nnbd_migration.dart';
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';
@@ -51,7 +50,7 @@
/// Implementations of [AbstractAnalysisServer] implement a server that listens
/// on a [CommunicationChannel] for analysis messages and process them.
-abstract class AbstractAnalysisServer implements DriverProvider {
+abstract class AbstractAnalysisServer {
/// The options of this server instance.
AnalysisServerOptions options;
@@ -128,7 +127,6 @@
];
/// The [ResourceProvider] using which paths are converted into [Resource]s.
- @override
final OverlayResourceProvider resourceProvider;
/// The next modification stamp for a changed file in the [resourceProvider].
@@ -284,7 +282,8 @@
return null;
}
- @override
+ /// Return the appropriate analysis session for the file with the given
+ /// [path].
AnalysisSession getAnalysisSession(String path) =>
getAnalysisDriver(path).currentSession;
diff --git a/pkg/analysis_server/lib/src/api_for_nnbd_migration.dart b/pkg/analysis_server/lib/src/api_for_nnbd_migration.dart
deleted file mode 100644
index f39fbd3..0000000
--- a/pkg/analysis_server/lib/src/api_for_nnbd_migration.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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/session.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-
-/// Abstract interface formerly used by NNBD migration to report changes to the
-/// analysis server. Now that the analysis server no longer integrates with
-/// NNBD migration, this exists only to support some tests that haven't yet been
-/// modified to use the new NNBD migration infrastructure.
-///
-/// TODO(paulberry): remove this interface once it's no longer needed.
-abstract class DartFixListenerInterface {
- DriverProvider get server;
-
- SourceChange get sourceChange;
-
- /// Add the given [detail] to the list of details to be returned to the
- /// client.
- void addDetail(String detail);
-
- /// Record an edit to be sent to the client.
- ///
- /// The associated suggestion should be separately added by calling
- /// [addSuggestion].
- void addEditWithoutSuggestion(Source source, SourceEdit edit);
-
- /// Record a recommendation to be sent to the client.
- void addRecommendation(String description, [Location location]);
-
- /// Record a source change to be sent to the client.
- void addSourceFileEdit(
- String description, Location location, SourceFileEdit fileEdit);
-
- /// Record a suggestion to be sent to the client.
- ///
- /// The associated edits should be separately added by calling
- /// [addEditWithoutRecommendation].
- void addSuggestion(String description, Location location);
-}
-
-/// Abstract interface formerly used by NNBD migration to access the resource
-/// provider and the analysis session. Now that the analysis server no longer
-/// integrates with NNBD migration, this exists only to support some tests that
-/// haven't yet been modified to use the new NNBD migration infrastructure.
-///
-/// TODO(paulberry): remove this interface once it's no longer needed.
-abstract class DriverProvider {
- ResourceProvider get resourceProvider;
-
- /// Return the appropriate analysis session for the file with the given
- /// [path].
- AnalysisSession getAnalysisSession(String path);
-}
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index 77e9970..506cab6 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -155,24 +155,46 @@
// parameter for a field that does not exist.
return null;
}
- // The documentation of the element itself.
- if (element.documentationComment != null) {
- return dartdocInfo.processDartdoc(element.documentationComment);
- }
- // Look for documentation comments of overridden members.
+
+ Element documentedElement;
+ Element documentedGetter;
+
+ // Look for documentation comments of overridden members
var overridden = findOverriddenElements(element);
- for (var superElement in [
+ for (var candidate in [
+ element,
...overridden.superElements,
...overridden.interfaceElements
]) {
- var rawDoc = superElement.documentationComment;
- if (rawDoc != null) {
- var interfaceClass = superElement.enclosingElement;
- return dartdocInfo.processDartdoc(rawDoc) +
- '\n\nCopied from `${interfaceClass.displayName}`.';
+ if (candidate.documentationComment != null) {
+ documentedElement = candidate;
+ break;
+ }
+ if (documentedGetter == null &&
+ candidate is PropertyAccessorElement &&
+ candidate.isSetter) {
+ var getter = candidate.correspondingGetter;
+ if (getter != null && getter.documentationComment != null) {
+ documentedGetter = getter;
+ }
}
}
- return null;
+
+ // Use documentation of a corresponding getter if setters don't have it
+ documentedElement ??= documentedGetter;
+ if (documentedElement == null) {
+ return null;
+ }
+
+ var rawDoc = documentedElement.documentationComment;
+ var result = dartdocInfo.processDartdoc(rawDoc);
+
+ var documentedElementClass = documentedElement.enclosingElement;
+ if (documentedElementClass != element.enclosingElement) {
+ result += '\n\nCopied from `${documentedElementClass.displayName}`.';
+ }
+
+ return result;
}
static DartType _getTypeOfDeclarationOrReference(Expression node) {
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 862fd83..cf3de34 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -41,6 +41,8 @@
// ignore: deprecated_member_use
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/analysis/library_context.dart'
+ show LibraryCycleLinkException;
import 'package:analyzer/src/dart/analysis/results.dart' as engine;
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart' as engine;
@@ -599,7 +601,23 @@
name,
);
});
- var fixes = await DartFixContributor().computeFixes(context);
+
+ List<Fix> fixes;
+ try {
+ fixes = await DartFixContributor().computeFixes(context);
+ } catch (exception, stackTrace) {
+ var parametersFile = '''
+offset: $offset
+error: $error
+error.errorCode: ${error.errorCode}
+''';
+ // TODO(scheglov) Use CaughtExceptionWithFiles when patch changed.
+ throw LibraryCycleLinkException(exception, stackTrace, {
+ file: result.content,
+ 'parameters': parametersFile,
+ });
+ }
+
if (fixes.isNotEmpty) {
fixes.sort(Fix.SORT_BY_RELEVANCE);
var serverError = newAnalysisError_fromEngine(result, error);
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
index fd2b337..5823ad7 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
@@ -4,7 +4,6 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/api_for_nnbd_migration.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -12,14 +11,12 @@
show Location, SourceChange, SourceEdit, SourceFileEdit;
/// Tasks use this API to report results.
-class DartFixListener implements DartFixListenerInterface {
- @override
+class DartFixListener {
final AnalysisServer server;
final List<DartFixSuggestion> suggestions = <DartFixSuggestion>[];
final List<DartFixSuggestion> otherSuggestions = <DartFixSuggestion>[];
- @override
final SourceChange sourceChange = SourceChange('dartfix');
/// The details to be returned to the client.
@@ -31,7 +28,6 @@
/// Add the given [detail] to the list of details to be returned to the
/// client.
- @override
void addDetail(String detail) {
if (details.length < 200) {
details.add(detail);
@@ -42,13 +38,11 @@
///
/// The associated suggestion should be separately added by calling
/// [addSuggestion].
- @override
void addEditWithoutSuggestion(Source source, SourceEdit edit) {
sourceChange.addEdit(source.fullName, -1, edit);
}
/// Record a recommendation to be sent to the client.
- @override
void addRecommendation(String description, [Location location]) {
otherSuggestions.add(DartFixSuggestion(description, location: location));
}
@@ -74,7 +68,6 @@
}
/// Record a source change to be sent to the client.
- @override
void addSourceFileEdit(
String description, Location location, SourceFileEdit fileEdit) {
suggestions.add(DartFixSuggestion(description, location: location));
@@ -87,7 +80,6 @@
///
/// The associated edits should be separately added by calling
/// [addEditWithoutRecommendation].
- @override
void addSuggestion(String description, Location location) {
suggestions.add(DartFixSuggestion(description, location: location));
}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
index cf04772..d38cd5b 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -56,6 +56,9 @@
/// Return `true` if free standing identifiers should be suggested
bool get includeIdentifiers;
+ /// Return `true` if the completion is occurring in a constant context.
+ bool get inConstantContext;
+
/// Return the library element which contains the unit in which the completion
/// is occurring. This may return `null` if the library cannot be determined
/// (e.g. unlinked part file).
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 41e52a4..ba10f46 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -44,6 +44,7 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -444,6 +445,12 @@
}
@override
+ bool get inConstantContext {
+ var entity = target.entity;
+ return entity is ExpressionImpl && entity.inConstantContext;
+ }
+
+ @override
LibraryElement get libraryElement {
//TODO(danrubel) build the library element rather than all the declarations
var unit = target.unit;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
index 7139b46..ef43347 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
@@ -13,7 +13,14 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart'
- show ClassElement, Element, FieldElement, LibraryElement;
+ show
+ ClassElement,
+ ConstructorElement,
+ Element,
+ FieldElement,
+ LibraryElement,
+ PropertyAccessorElement,
+ TopLevelVariableElement;
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/dart/element/type_system.dart';
@@ -152,6 +159,23 @@
return _distanceToPercent(distance);
}
+ /// Return the value of the _is constant_ feature for the given [element].
+ double isConstantFeature(Element element) {
+ if (element is ConstructorElement && element.isConst) {
+ return 1.0;
+ } else if (element is FieldElement && element.isStatic && element.isConst) {
+ return 1.0;
+ } else if (element is TopLevelVariableElement && element.isConst) {
+ return 1.0;
+ } else if (element is PropertyAccessorElement &&
+ element.isSynthetic &&
+ element.variable.isStatic &&
+ element.variable.isConst) {
+ return 1.0;
+ }
+ return 0.0;
+ }
+
/// Return the value of the _starts with dollar_ feature.
double startsWithDollarFeature(String name) =>
name.startsWith('\$') ? 0.0 : 1.0;
@@ -406,22 +430,21 @@
@override
DartType visitListLiteral(ListLiteral node) {
- var typeArguments = node.typeArguments?.arguments;
- if (typeArguments != null && typeArguments.length == 1) {
- return typeArguments[0].type;
+ if (node.elements.contains(childNode)) {
+ return (node.staticType as InterfaceType).typeArguments[0];
}
return null;
}
@override
DartType visitMapLiteralEntry(MapLiteralEntry node) {
- var typeArguments =
- node.thisOrAncestorOfType<SetOrMapLiteral>()?.typeArguments;
- if (typeArguments != null && typeArguments.length == 2) {
+ var literal = node.thisOrAncestorOfType<SetOrMapLiteral>();
+ if (literal != null && literal.staticType.isDartCoreMap) {
+ var typeArguments = (literal.staticType as InterfaceType).typeArguments;
if (childNode == node.key) {
- return typeArguments.arguments[0].type;
+ return typeArguments[0];
} else {
- return typeArguments.arguments[1].type;
+ return typeArguments[1];
}
}
return null;
@@ -436,6 +459,14 @@
}
@override
+ DartType visitNamedExpression(NamedExpression node) {
+ if (childNode == node.expression) {
+ return _visitParent(node);
+ }
+ return super.visitNamedExpression(node);
+ }
+
+ @override
DartType visitParenthesizedExpression(ParenthesizedExpression node) {
return _visitParent(node);
}
@@ -473,11 +504,10 @@
@override
DartType visitSetOrMapLiteral(SetOrMapLiteral node) {
- if (node.isSet) {
- var typeArguments = node.typeArguments?.arguments;
- if (typeArguments != null && typeArguments.length == 1) {
- return typeArguments[0].type;
- }
+ var type = node.staticType;
+ if (node.elements.contains(childNode) &&
+ (type.isDartCoreMap || type.isDartCoreSet)) {
+ return (type as InterfaceType).typeArguments[0];
}
return null;
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart b/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
index a214ef6..8a2e044 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
@@ -7,7 +7,6 @@
import 'dart:typed_data';
import 'package:path/path.dart' as path;
-import 'package:quiver/check.dart';
import 'package:tflite_native/tflite.dart' as tfl;
/// Interface to TensorFlow-based Dart language model for next-token prediction.
@@ -41,9 +40,10 @@
// Get lookback size from model input tensor shape.
final tensorShape = interpreter.getInputTensors().single.shape;
- checkArgument(tensorShape.length == 2 && tensorShape.first == 1,
- message:
- 'tensor shape $tensorShape does not match the expected [1, X]');
+ if (tensorShape.length != 2 || tensorShape.first != 1) {
+ throw ArgumentError(
+ 'tensor shape $tensorShape does not match the expected [1, X]');
+ }
final lookback = tensorShape.last;
return LanguageModel._(interpreter, word2idx, idx2word, lookback);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index c836fb5..d7f8154 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -19,48 +19,58 @@
@override
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request, SuggestionBuilder builder) async {
- if (request.libraryElement == null) {
+ var library = request.libraryElement;
+ if (library == null) {
// Gracefully degrade if the library could not be determined, such as a
// detached part file or source change.
// TODO(brianwilkerson) Consider testing for this before invoking _any_ of
// the contributors.
return const <CompletionSuggestion>[];
}
+ bool isVisible(Element element) => element.isAccessibleIn(library);
var targetId = request.dotTarget;
if (targetId is Identifier && !request.target.isCascade) {
var element = targetId.staticElement;
if (element is ClassElement) {
for (var accessor in element.accessors) {
- if (accessor.isStatic) {
+ if (accessor.isStatic &&
+ !accessor.isSynthetic &&
+ isVisible(accessor)) {
builder.suggestAccessor(accessor, inheritanceDistance: -1.0);
}
}
for (var constructor in element.constructors) {
- builder.suggestConstructor(constructor, hasClassName: true);
+ if (isVisible(constructor)) {
+ builder.suggestConstructor(constructor, hasClassName: true);
+ }
}
for (var field in element.fields) {
- if (field.isStatic && (!field.isSynthetic || element.isEnum)) {
+ if (field.isStatic &&
+ (!field.isSynthetic || element.isEnum) &&
+ isVisible(field)) {
builder.suggestField(field, inheritanceDistance: -1.0);
}
}
for (var method in element.methods) {
- if (method.isStatic) {
+ if (method.isStatic && isVisible(method)) {
builder.suggestMethod(method, inheritanceDistance: -1.0);
}
}
} else if (element is ExtensionElement) {
for (var accessor in element.accessors) {
- if (accessor.isStatic) {
+ if (accessor.isStatic &&
+ !accessor.isSynthetic &&
+ isVisible(accessor)) {
builder.suggestAccessor(accessor, inheritanceDistance: -1.0);
}
}
for (var field in element.fields) {
- if (field.isStatic) {
+ if (field.isStatic && !field.isSynthetic && isVisible(field)) {
builder.suggestField(field, inheritanceDistance: -1.0);
}
}
for (var method in element.methods) {
- if (method.isStatic) {
+ if (method.isStatic && isVisible(method)) {
builder.suggestMethod(method, inheritanceDistance: -1.0);
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index b2eb79a..7d74ff0 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -229,6 +229,9 @@
featureComputer.contextTypeFeature(request.contextType, type);
var elementKind = _computeElementKind(accessor);
var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
+ var isConstant = request.inConstantContext
+ ? featureComputer.isConstantFeature(accessor)
+ : -1.0;
var startsWithDollar =
featureComputer.startsWithDollarFeature(accessor.name);
var superMatches = featureComputer.superMatchesFeature(
@@ -238,6 +241,7 @@
elementKind: elementKind,
hasDeprecated: hasDeprecated,
inheritanceDistance: inheritanceDistance,
+ isConstant: isConstant,
startsWithDollar: startsWithDollar,
superMatches: superMatches);
listener?.computedFeatures(
@@ -271,8 +275,13 @@
var contextType = request.featureComputer
.contextTypeFeature(request.contextType, variableType);
var elementKind = _computeElementKind(parameter);
+ var isConstant = request.inConstantContext
+ ? request.featureComputer.isConstantFeature(parameter)
+ : -1.0;
relevance = toRelevance(
- weightedAverage([contextType, elementKind], [1.0, 1.0]), 800);
+ weightedAverage(
+ [contextType, elementKind, isConstant], [1.0, 1.0, 1.0]),
+ 800);
listener?.computedFeatures(contextType: contextType);
} else {
relevance = _computeOldMemberRelevance(parameter);
@@ -500,6 +509,9 @@
featureComputer.contextTypeFeature(request.contextType, field.type);
var elementKind = _computeElementKind(field);
var hasDeprecated = featureComputer.hasDeprecatedFeature(field);
+ var isConstant = request.inConstantContext
+ ? featureComputer.isConstantFeature(field)
+ : -1.0;
var startsWithDollar =
featureComputer.startsWithDollarFeature(field.name);
var superMatches = featureComputer.superMatchesFeature(
@@ -509,6 +521,7 @@
elementKind: elementKind,
hasDeprecated: hasDeprecated,
inheritanceDistance: inheritanceDistance,
+ isConstant: isConstant,
startsWithDollar: startsWithDollar,
superMatches: superMatches);
listener?.computedFeatures(
@@ -544,12 +557,12 @@
/// Add a suggestion for the `call` method defined on functions.
void suggestFunctionCall() {
- const callString = 'call()';
+ const callString = 'call';
final element = protocol.Element(
protocol.ElementKind.METHOD, callString, protocol.Element.makeFlags(),
location: null,
typeParameters: null,
- parameters: null,
+ parameters: '()',
returnType: 'void');
_add(CompletionSuggestion(
CompletionSuggestionKind.INVOCATION,
@@ -559,9 +572,13 @@
0,
false,
false,
- displayText: callString,
+ displayText: 'call()',
element: element,
returnType: 'void',
+ parameterNames: [],
+ parameterTypes: [],
+ requiredParameterCount: 0,
+ hasNamedParameters: false,
));
}
@@ -644,8 +661,13 @@
var contextType = request.featureComputer
.contextTypeFeature(request.contextType, variableType);
var elementKind = _computeElementKind(variable);
+ var isConstant = request.inConstantContext
+ ? request.featureComputer.isConstantFeature(variable)
+ : -1.0;
relevance = toRelevance(
- weightedAverage([contextType, elementKind], [1.0, 1.0]), 800);
+ weightedAverage(
+ [contextType, elementKind, isConstant], [1.0, 1.0, 1.0]),
+ 800);
listener?.computedFeatures(contextType: contextType);
} else {
relevance = _computeOldMemberRelevance(variable);
@@ -676,6 +698,9 @@
request.contextType, method.returnType);
var elementKind = _computeElementKind(method);
var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
+ var isConstant = request.inConstantContext
+ ? featureComputer.isConstantFeature(method)
+ : -1.0;
var startsWithDollar =
featureComputer.startsWithDollarFeature(method.name);
var superMatches = featureComputer.superMatchesFeature(
@@ -685,6 +710,7 @@
elementKind: elementKind,
hasDeprecated: hasDeprecated,
inheritanceDistance: inheritanceDistance,
+ isConstant: isConstant,
startsWithDollar: startsWithDollar,
superMatches: superMatches);
listener?.computedFeatures(
@@ -885,8 +911,13 @@
var contextType = request.featureComputer
.contextTypeFeature(request.contextType, variableType);
var elementKind = _computeElementKind(parameter);
+ var isConstant = request.inConstantContext
+ ? request.featureComputer.isConstantFeature(parameter)
+ : -1.0;
relevance = toRelevance(
- weightedAverage([contextType, elementKind], [1.0, 1.0]), 800);
+ weightedAverage(
+ [contextType, elementKind, isConstant], [1.0, 1.0, 1.0]),
+ 800);
listener?.computedFeatures(contextType: contextType);
} else {
relevance = _computeOldMemberRelevance(parameter);
@@ -905,6 +936,9 @@
var relevance;
if (request.useNewRelevance) {
var elementKind = _computeElementKind(library);
+ // TODO(brianwilkerson) If we are in a constant context it would be nice
+ // to promote prefixes for libraries that define constants, but that
+ // might be more work than it's worth.
relevance = toRelevance(elementKind, Relevance.prefix);
listener?.computedFeatures(elementKind: elementKind);
} else {
@@ -971,6 +1005,9 @@
featureComputer.contextTypeFeature(request.contextType, type);
var elementKind = _computeElementKind(accessor);
var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
+ var isConstant = request.inConstantContext
+ ? featureComputer.isConstantFeature(accessor)
+ : -1.0;
var startsWithDollar =
featureComputer.startsWithDollarFeature(accessor.name);
relevance = _computeMemberRelevance(
@@ -978,6 +1015,7 @@
elementKind: elementKind,
hasDeprecated: hasDeprecated,
inheritanceDistance: -1.0,
+ isConstant: isConstant,
startsWithDollar: startsWithDollar,
superMatches: -1.0);
listener?.computedFeatures(
@@ -1032,7 +1070,12 @@
int relevance;
if (request.useNewRelevance) {
var elementKind = _computeElementKind(parameter);
- relevance = toRelevance(elementKind, Relevance.typeParameter);
+ var isConstant = request.inConstantContext
+ ? request.featureComputer.isConstantFeature(parameter)
+ : -1.0;
+ relevance = toRelevance(
+ weightedAverage([elementKind, isConstant], [1.0, 1.0]),
+ Relevance.typeParameter);
listener?.computedFeatures(elementKind: elementKind);
} else {
relevance = _computeOldMemberRelevance(parameter);
@@ -1105,6 +1148,7 @@
@required double elementKind,
@required double hasDeprecated,
@required double inheritanceDistance,
+ @required double isConstant,
@required double startsWithDollar,
@required double superMatches}) {
var score = weightedAverage([
@@ -1112,15 +1156,17 @@
elementKind,
hasDeprecated,
inheritanceDistance,
+ isConstant,
startsWithDollar,
superMatches
], [
- 1.0,
- 0.75,
- 0.5,
- 1.0,
- 0.5,
- 1.0
+ 1.00, // contextType
+ 0.75, // elementKind
+ 0.50, // hasDeprecated
+ 1.00, // inheritanceDistance
+ 1.00, // isConstant
+ 0.50, // startsWithDollar
+ 1.00, // superMatches
]);
return toRelevance(score, Relevance.member);
}
@@ -1177,9 +1223,12 @@
featureComputer.contextTypeFeature(request.contextType, elementType);
var elementKind = _computeElementKind(element);
var hasDeprecated = featureComputer.hasDeprecatedFeature(element);
+ var isConstant = request.inConstantContext
+ ? featureComputer.isConstantFeature(element)
+ : -1.0;
var relevance = toRelevance(
- weightedAverage(
- [contextType, elementKind, hasDeprecated], [1.0, 0.75, 0.2]),
+ weightedAverage([contextType, elementKind, hasDeprecated, isConstant],
+ [1.0, 0.75, 0.2, 1.0]),
defaultRelevance);
listener?.computedFeatures(
contextType: contextType,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 1be5e6e..09832e6 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -82,7 +82,10 @@
superclassConstraints = (type as InterfaceType).superclassConstraints;
type = (type as InterfaceType).superclass;
}
- if (type == null || type.isDynamic) {
+ if (type is FunctionType) {
+ builder.suggestFunctionCall();
+ type = request.objectType;
+ } else if (type == null || type.isDynamic) {
// Suggest members from object if target is "dynamic".
type = request.objectType;
}
@@ -92,8 +95,6 @@
var memberBuilder = _SuggestionBuilder(request, builder);
memberBuilder.buildSuggestions(type,
mixins: mixins, superclassConstraints: superclassConstraints);
- } else if (type is FunctionType) {
- builder.suggestFunctionCall();
}
return const <CompletionSuggestion>[];
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 234e13d..77859c9 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
@@ -81,7 +81,7 @@
AstNode get node => _node;
- /// Return `true` the lint with the given [name] is enabled.
+ /// Return `true` if the lint with the given [name] is enabled.
bool isLintEnabled(String name) {
var analysisOptions = session.analysisContext.analysisOptions;
return analysisOptions.isLintEnabled(name);
@@ -157,6 +157,10 @@
TypeProvider get typeProvider => _context.typeProvider;
+ /// Return the type system appropriate to the library in which the correction
+ /// was requested.
+ TypeSystem get typeSystem => _context.resolvedResult.typeSystem;
+
CompilationUnit get unit => _context.unit;
CorrectionUtils get utils => _context.utils;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
index 6ec06fc..fc6de6b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
@@ -12,7 +12,9 @@
import 'package:analyzer_plugin/utilities/range_factory.dart';
class ChangeArgumentName extends MultiCorrectionProducer {
- static const maxDistance = 4;
+ /// The maximum Levenshtein distance between the existing name and a possible
+ /// replacement before the replacement is deemed to not be worth offering.
+ static const _maxDistance = 4;
@override
Iterable<CorrectionProducer> get producers sync* {
@@ -24,7 +26,7 @@
var invalidName = argumentName.name;
for (var proposedName in names) {
var distance = _computeDistance(invalidName, proposedName);
- if (distance <= maxDistance) {
+ if (distance <= _maxDistance) {
// TODO(brianwilkerson) Create a way to use the distance as part of the
// computation of the priority (so that closer names sort first).
yield _ChangeName(argumentName, proposedName);
@@ -40,7 +42,7 @@
// value is changed to improve results.
return 1;
}
- return levenshtein(current, proposal, maxDistance, caseSensitive: false);
+ return levenshtein(current, proposal, _maxDistance, caseSensitive: false);
}
List<String> _getNamedParameterNames() {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to_nearest_precise_value.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to_nearest_precise_value.dart
new file mode 100644
index 0000000..89888e1
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to_nearest_precise_value.dart
@@ -0,0 +1,39 @@
+// 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/src/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 ChangeToNearestPreciseValue extends CorrectionProducer {
+ /// The value to which the code will be changed.
+ String correction = '';
+
+ @override
+ List<Object> get fixArguments => [correction];
+
+ @override
+ FixKind get fixKind => DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ IntegerLiteral integer = node;
+ var lexeme = integer.literal.lexeme;
+ var precise = BigInt.from(IntegerLiteralImpl.nearestValidDouble(lexeme));
+ correction = lexeme.toLowerCase().contains('x')
+ ? '0x${precise.toRadixString(16).toUpperCase()}'
+ : precise.toString();
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.node(integer), correction);
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ChangeToNearestPreciseValue newInstance() =>
+ ChangeToNearestPreciseValue();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart
new file mode 100644
index 0000000..0467c08
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart
@@ -0,0 +1,54 @@
+// 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/element/type.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 ChangeTypeAnnotation extends CorrectionProducer {
+ String oldAnnotation = '';
+
+ String newAnnotation = '';
+
+ @override
+ List<Object> get fixArguments => [oldAnnotation, newAnnotation];
+
+ @override
+ FixKind get fixKind => DartFixKind.CHANGE_TYPE_ANNOTATION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var declaration = coveredNode.parent;
+ if (declaration is VariableDeclaration &&
+ declaration.initializer == coveredNode) {
+ var variableList = declaration.parent;
+ if (variableList is VariableDeclarationList &&
+ variableList.variables.length == 1) {
+ var typeNode = variableList.type;
+ if (typeNode != null) {
+ Expression initializer = coveredNode;
+ var newType = initializer.staticType;
+ if (newType is InterfaceType || newType is FunctionType) {
+ oldAnnotation =
+ typeNode.type.getDisplayString(withNullability: false);
+ newAnnotation = newType.getDisplayString(withNullability: false);
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(typeNode),
+ (DartEditBuilder builder) {
+ builder.writeType(newType);
+ });
+ });
+ }
+ }
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ChangeTypeAnnotation newInstance() => ChangeTypeAnnotation();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_child.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_child.dart
new file mode 100644
index 0000000..a6029d6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_child.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.
+
+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 ConvertFlutterChild extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_FLUTTER_CHILD;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var named = flutter.findNamedExpression(node, 'child');
+ if (named == null) {
+ return;
+ }
+
+ // child: widget
+ var expression = named.expression;
+ if (flutter.isWidgetExpression(expression)) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ flutter.convertChildToChildren2(
+ builder,
+ expression,
+ named,
+ eol,
+ utils.getNodeText,
+ utils.getLinePrefix,
+ utils.getIndent,
+ utils.getText,
+ range.node);
+ });
+ return;
+ }
+
+ // child: [widget1, widget2]
+ if (expression is ListLiteral &&
+ expression.elements.every(flutter.isWidgetExpression)) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.node(named.name), 'children:');
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ConvertFlutterChild newInstance() => ConvertFlutterChild();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_children.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_children.dart
new file mode 100644
index 0000000..df8469f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_flutter_children.dart
@@ -0,0 +1,50 @@
+// 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 ConvertFlutterChildren extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_FLUTTER_CHILDREN;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is SimpleIdentifier &&
+ node.name == 'children' &&
+ node.parent?.parent is NamedExpression) {
+ NamedExpression named = node.parent?.parent;
+ var expression = named.expression;
+ if (expression is ListLiteral && expression.elements.length == 1) {
+ var widget = expression.elements[0];
+ if (flutter.isWidgetExpression(widget)) {
+ var widgetText = utils.getNodeText(widget);
+ var indentOld = utils.getLinePrefix(widget.offset);
+ var indentNew = utils.getLinePrefix(named.offset);
+ widgetText = _replaceSourceIndent(widgetText, indentOld, indentNew);
+
+ await builder.addFileEdit(file, (builder) {
+ builder.addReplacement(range.node(named), (builder) {
+ builder.write('child: ');
+ builder.write(widgetText);
+ });
+ });
+ }
+ }
+ }
+ }
+
+ String _replaceSourceIndent(
+ String source, String indentOld, String indentNew) {
+ return source.replaceAll(RegExp('^$indentOld', multiLine: true), indentNew);
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ConvertFlutterChildren newInstance() => ConvertFlutterChildren();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
new file mode 100644
index 0000000..e18304d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.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: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/token.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 ConvertToIfNull extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_IF_NULL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var conditional = node.thisOrAncestorOfType<ConditionalExpression>();
+ if (conditional == null) {
+ return;
+ }
+ var condition = conditional.condition as BinaryExpression;
+ Expression nullableExpression;
+ Expression defaultExpression;
+ if (condition.operator.type == TokenType.EQ_EQ) {
+ nullableExpression = conditional.elseExpression;
+ defaultExpression = conditional.thenExpression;
+ } else {
+ nullableExpression = conditional.thenExpression;
+ defaultExpression = conditional.elseExpression;
+ }
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(conditional), (builder) {
+ builder.write(utils.getNodeText(nullableExpression));
+ builder.write(' ?? ');
+ builder.write(utils.getNodeText(defaultExpression));
+ });
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ConvertToIfNull newInstance() => ConvertToIfNull();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
new file mode 100644
index 0000000..7b4d5ba
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
@@ -0,0 +1,94 @@
+// 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/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ConvertToNamedArguments extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.CONVERT_TO_NAMED_ARGUMENTS;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var argumentList = node;
+ if (argumentList is ArgumentList) {
+ // Prepare parameters.
+ List<ParameterElement> parameters;
+ var parent = argumentList.parent;
+ if (parent is FunctionExpressionInvocation) {
+ var invokeType = parent.staticInvokeType;
+ if (invokeType is FunctionType) {
+ parameters = invokeType.parameters;
+ }
+ } else if (parent is InstanceCreationExpression) {
+ parameters = parent.staticElement?.parameters;
+ } else if (parent is MethodInvocation) {
+ var invokeType = parent.staticInvokeType;
+ if (invokeType is FunctionType) {
+ parameters = invokeType.parameters;
+ }
+ }
+ if (parameters == null) {
+ return;
+ }
+
+ // Prepare named parameters.
+ var numberOfPositionalParameters = 0;
+ var namedParameters = <ParameterElement>[];
+ for (var parameter in parameters) {
+ if (parameter.isNamed) {
+ namedParameters.add(parameter);
+ } else {
+ numberOfPositionalParameters++;
+ }
+ }
+ if (argumentList.arguments.length <= numberOfPositionalParameters) {
+ return;
+ }
+
+ // Find named parameters for extra arguments.
+ var argumentToParameter = <Expression, ParameterElement>{};
+ var extraArguments =
+ argumentList.arguments.skip(numberOfPositionalParameters);
+ for (var argument in extraArguments) {
+ if (argument is! NamedExpression) {
+ ParameterElement uniqueNamedParameter;
+ for (var namedParameter in namedParameters) {
+ if (typeSystem.isSubtypeOf(
+ argument.staticType, namedParameter.type)) {
+ if (uniqueNamedParameter == null) {
+ uniqueNamedParameter = namedParameter;
+ } else {
+ uniqueNamedParameter = null;
+ break;
+ }
+ }
+ }
+ if (uniqueNamedParameter != null) {
+ argumentToParameter[argument] = uniqueNamedParameter;
+ namedParameters.remove(uniqueNamedParameter);
+ }
+ }
+ }
+ if (argumentToParameter.isEmpty) {
+ return;
+ }
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ for (var argument in argumentToParameter.keys) {
+ var parameter = argumentToParameter[argument];
+ builder.addSimpleInsertion(argument.offset, '${parameter.name}: ');
+ }
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ConvertToNamedArguments newInstance() => ConvertToNamedArguments();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
new file mode 100644
index 0000000..5e211d6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
@@ -0,0 +1,56 @@
+// 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/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class CreateMethod extends CorrectionProducer {
+ String memberName;
+
+ @override
+ List<Object> get fixArguments => [memberName];
+
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_METHOD;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ final methodDecl = node.thisOrAncestorOfType<MethodDeclaration>();
+ final classDecl = methodDecl.thisOrAncestorOfType<ClassDeclaration>();
+ if (methodDecl != null && classDecl != null) {
+ final classElement = classDecl.declaredElement;
+
+ var element;
+ if (methodDecl.name.name == 'hashCode') {
+ memberName = '==';
+ element = classElement.lookUpInheritedMethod(
+ memberName, classElement.library);
+ } else {
+ memberName = 'hashCode';
+ element = classElement.lookUpInheritedConcreteGetter(
+ memberName, classElement.library);
+ }
+
+ final location =
+ utils.prepareNewClassMemberLocation(classDecl, (_) => true);
+
+ await builder.addFileEdit(file, (fileBuilder) {
+ fileBuilder.addInsertion(location.offset, (builder) {
+ builder.write(location.prefix);
+ builder.writeOverride(element, invokeSuper: true);
+ builder.write(location.suffix);
+ });
+ });
+
+ builder.setSelection(Position(file, location.offset));
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateMethod newInstance() => CreateMethod();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
new file mode 100644
index 0000000..f1ecfa1
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_final.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: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/token.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 MakeFinal extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.MAKE_FINAL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ VariableDeclarationList list;
+ var node = this.node;
+ if (node is SimpleIdentifier &&
+ node.parent is VariableDeclaration &&
+ node.parent.parent is VariableDeclarationList) {
+ list = node.parent.parent;
+ } else if (node is VariableDeclaration &&
+ node.parent is VariableDeclarationList) {
+ list = node.parent;
+ }
+ if (list != null) {
+ if (list.variables.length == 1) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ if (list.keyword == null) {
+ builder.addSimpleInsertion(list.offset, 'final ');
+ } else if (list.keyword.keyword == Keyword.VAR) {
+ builder.addSimpleReplacement(range.token(list.keyword), 'final');
+ }
+ });
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static MakeFinal newInstance() => MakeFinal();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart
new file mode 100644
index 0000000..4ae3553
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart
@@ -0,0 +1,33 @@
+// 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 RemoveArgument extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_ARGUMENT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var arg = node;
+ if (arg.parent is NamedExpression) {
+ arg = arg.parent;
+ }
+ var argumentList = arg.parent.thisOrAncestorOfType<ArgumentList>();
+ if (argumentList != null) {
+ await builder.addFileEdit(file, (builder) {
+ final sourceRange = range.nodeInList(argumentList.arguments, arg);
+ builder.addDeletion(sourceRange);
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveArgument newInstance() => RemoveArgument();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart
new file mode 100644
index 0000000..ddde92d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart
@@ -0,0 +1,29 @@
+// 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 RemoveAwait extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_AWAIT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ final awaitExpression = node;
+ if (awaitExpression is AwaitExpression) {
+ final awaitToken = awaitExpression.awaitKeyword;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(awaitToken, awaitToken.next));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveAwait newInstance() => RemoveAwait();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
new file mode 100644
index 0000000..956fd02
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
@@ -0,0 +1,45 @@
+// 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/src/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 RemoveConst extends _RemoveConst {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_CONST;
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveConst newInstance() => RemoveConst();
+}
+
+class RemoveUnnecesaryConst extends _RemoveConst {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_CONST;
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnnecesaryConst newInstance() => RemoveUnnecesaryConst();
+}
+
+abstract class _RemoveConst extends CorrectionProducer {
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ final expression = node;
+ if (expression is InstanceCreationExpression) {
+ final constToken = expression.keyword;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(constToken, constToken.next));
+ });
+ } else if (expression is TypedLiteralImpl) {
+ final constToken = expression.constKeyword;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(constToken, constToken.next));
+ });
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
new file mode 100644
index 0000000..ee6d03e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
@@ -0,0 +1,27 @@
+// 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 RemoveDuplicateCase extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_DUPLICATE_CASE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (coveredNode is SwitchCase) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(utils.getLinesRange(range.node(coveredNode)));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveDuplicateCase newInstance() => RemoveDuplicateCase();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart
new file mode 100644
index 0000000..ae79f6c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart
@@ -0,0 +1,39 @@
+// 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 RemoveEmptyCatch extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_EMPTY_CATCH;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node.parent is! CatchClause) {
+ return;
+ }
+ var catchClause = node.parent as CatchClause;
+
+ if (catchClause.parent is! TryStatement) {
+ return;
+ }
+ var tryStatement = catchClause.parent as TryStatement;
+ if (tryStatement.catchClauses.length == 1 &&
+ tryStatement.finallyBlock == null) {
+ return;
+ }
+
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(utils.getLinesRange(range.node(catchClause)));
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveEmptyCatch newInstance() => RemoveEmptyCatch();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart
new file mode 100644
index 0000000..67fa65a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.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 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.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 RemoveEmptyConstructorBody extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ utils.getLinesRange(range.node(node.parent)), ';');
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveEmptyConstructorBody newInstance() =>
+ RemoveEmptyConstructorBody();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart
new file mode 100644
index 0000000..d915e1f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart
@@ -0,0 +1,29 @@
+// 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 RemoveEmptyElse extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_EMPTY_ELSE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var parent = node.parent;
+ if (parent is IfStatement) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(utils.getLinesRange(
+ range.startEnd(parent.elseKeyword, parent.elseStatement)));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveEmptyElse newInstance() => RemoveEmptyElse();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart
new file mode 100644
index 0000000..0a1f98e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart
@@ -0,0 +1,27 @@
+// 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 RemoveEmptyStatement extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_EMPTY_STATEMENT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is EmptyStatement && node.parent is Block) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(utils.getLinesRange(range.node(node)));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveEmptyStatement newInstance() => RemoveEmptyStatement();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
new file mode 100644
index 0000000..809a5fe
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
@@ -0,0 +1,39 @@
+// 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 RemoveInitializer extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_INITIALIZER;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var parameter = node.thisOrAncestorOfType<DefaultFormalParameter>();
+ if (parameter != null) {
+ // Handle formal parameters with default values.
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(
+ range.endEnd(parameter.identifier, parameter.defaultValue));
+ });
+ } else {
+ // Handle variable declarations with default values.
+ var variable = node.thisOrAncestorOfType<VariableDeclaration>();
+ if (variable != null) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder
+ .addDeletion(range.endEnd(variable.name, variable.initializer));
+ });
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveInitializer newInstance() => RemoveInitializer();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart
new file mode 100644
index 0000000..1420230
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart
@@ -0,0 +1,33 @@
+// 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 RemoveInterpolationBraces extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_INTERPOLATION_BRACES;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is InterpolationExpression) {
+ var right = node.rightBracket;
+ if (node.expression != null && right != null) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ range.startStart(node, node.expression), r'$');
+ builder.addDeletion(range.token(right));
+ });
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveInterpolationBraces newInstance() => RemoveInterpolationBraces();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart
new file mode 100644
index 0000000..675d2ca
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart
@@ -0,0 +1,28 @@
+// 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 RemoveMethodDeclaration extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_METHOD_DECLARATION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var declaration = node.thisOrAncestorOfType<MethodDeclaration>();
+ if (declaration != null) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(utils.getLinesRange(range.node(declaration)));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveMethodDeclaration newInstance() => RemoveMethodDeclaration();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart
new file mode 100644
index 0000000..256b063
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart
@@ -0,0 +1,30 @@
+// 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 RemoveOperator extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_OPERATOR;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is BinaryExpression) {
+ var expression = node as BinaryExpression;
+ var operator = expression.operator;
+ var rightOperand = expression.rightOperand;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(operator, rightOperand));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveOperator newInstance() => RemoveOperator();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
index ae50eb6..860f571 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
@@ -15,10 +15,10 @@
@override
Future<void> compute(DartChangeBuilder builder) async {
- if (node is! SimpleIdentifier || node.parent is! TypeName) {
+ if (node is! TypeName) {
return;
}
- var typeName = node.parent as TypeName;
+ var typeName = node as TypeName;
var questionMark = typeName.question;
if (questionMark == null) {
return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart
new file mode 100644
index 0000000..3b82f5c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart
@@ -0,0 +1,41 @@
+// 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 RemoveThisExpression extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_THIS_EXPRESSION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is ConstructorFieldInitializer) {
+ var thisKeyword = node.thisKeyword;
+ if (thisKeyword != null) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var fieldName = node.fieldName;
+ builder.addDeletion(range.startStart(thisKeyword, fieldName));
+ });
+ }
+ return;
+ } else if (node is PropertyAccess && node.target is ThisExpression) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startEnd(node, node.operator));
+ });
+ } else if (node is MethodInvocation && node.target is ThisExpression) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startEnd(node, node.operator));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveThisExpression newInstance() => RemoveThisExpression();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
index 023a9cf..923891d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
@@ -20,13 +20,24 @@
@override
Future<void> compute(DartChangeBuilder builder) async {
- // todo (pq): unify w/ fix (and then add a guard to not assist on lints:
- // avoid_return_types_on_setters, type_init_formals)
+ var parameter = node.thisOrAncestorOfType<FormalParameter>();
+ if (parameter is SimpleFormalParameter) {
+ var type = parameter.type;
+ if (type != null) {
+ return _removeTypeAnnotation(builder, type);
+ }
+ }
var declarationList = node.thisOrAncestorOfType<VariableDeclarationList>();
- if (declarationList == null) {
- await _removeFromDeclaredIdentifier(builder);
- } else {
- await _removeFromDeclarationList(builder, declarationList);
+ if (declarationList != null) {
+ return _removeFromDeclarationList(builder, declarationList);
+ }
+ var declaredIdentifier = node.thisOrAncestorOfType<DeclaredIdentifier>();
+ if (declaredIdentifier != null) {
+ return _removeFromDeclaredIdentifier(builder, declaredIdentifier);
+ }
+ var type = node.thisOrAncestorOfType<TypeAnnotation>();
+ if (type != null) {
+ return _removeTypeAnnotation(builder, type);
}
}
@@ -63,11 +74,8 @@
});
}
- Future<void> _removeFromDeclaredIdentifier(DartChangeBuilder builder) async {
- var declaration = node.thisOrAncestorOfType<DeclaredIdentifier>();
- if (declaration == null) {
- return;
- }
+ Future<void> _removeFromDeclaredIdentifier(
+ DartChangeBuilder builder, DeclaredIdentifier declaration) async {
var typeNode = declaration.type;
if (typeNode == null) {
return;
@@ -83,4 +91,14 @@
}
});
}
+
+ Future<void> _removeTypeAnnotation(
+ DartChangeBuilder builder, TypeAnnotation type) async {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(type, type.endToken.next));
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveTypeAnnotation newInstance() => RemoveTypeAnnotation();
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart
new file mode 100644
index 0000000..a5aca38
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart
@@ -0,0 +1,29 @@
+// 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 RemoveUnnecessaryNew extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_NEW;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ final instanceCreationExpression = node;
+ if (instanceCreationExpression is InstanceCreationExpression) {
+ final newToken = instanceCreationExpression.keyword;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(newToken, newToken.next));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnnecessaryNew newInstance() => RemoveUnnecessaryNew();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
new file mode 100644
index 0000000..afb6973
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
@@ -0,0 +1,67 @@
+// 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:analysis_server/src/services/correction/util.dart';
+import 'package:analysis_server/src/utilities/strings.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.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 RenameToCamelCase extends CorrectionProducer {
+ /// The camel-case version of the name.
+ String _newName;
+
+ @override
+ List<Object> get fixArguments => [_newName];
+
+ @override
+ FixKind get fixKind => DartFixKind.RENAME_TO_CAMEL_CASE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ SimpleIdentifier identifier = node;
+
+ // Prepare the new name.
+ var words = identifier.name.split('_');
+ if (words.length < 2) {
+ return;
+ }
+ _newName = words.first + words.skip(1).map((w) => capitalize(w)).join();
+
+ // Find references to the identifier.
+ List<SimpleIdentifier> references;
+ var element = identifier.staticElement;
+ if (element is LocalVariableElement) {
+ AstNode root = node.thisOrAncestorOfType<Block>();
+ references = findLocalElementReferences(root, element);
+ } else if (element is ParameterElement) {
+ if (!element.isNamed) {
+ var root = node.thisOrAncestorMatching((node) =>
+ node.parent is ClassOrMixinDeclaration ||
+ node.parent is CompilationUnit);
+ references = findLocalElementReferences(root, element);
+ }
+ }
+ if (references == null) {
+ return;
+ }
+
+ // Compute the change.
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ for (var reference in references) {
+ builder.addSimpleReplacement(range.node(reference), _newName);
+ }
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RenameToCamelCase newInstance() => RenameToCamelCase();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_boolean_with_bool.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_boolean_with_bool.dart
new file mode 100644
index 0000000..68c0905
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_boolean_with_bool.dart
@@ -0,0 +1,24 @@
+// 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_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 ReplaceBooleanWithBool extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_BOOLEAN_WITH_BOOL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.error(diagnostic), 'bool');
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceBooleanWithBool newInstance() => ReplaceBooleanWithBool();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart
new file mode 100644
index 0000000..49973fb
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart
@@ -0,0 +1,28 @@
+// 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 ReplaceColonWithEquals extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_COLON_WITH_EQUALS;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is DefaultFormalParameter) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ range.token((node as DefaultFormalParameter).separator), ' =');
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceColonWithEquals newInstance() => ReplaceColonWithEquals();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
new file mode 100644
index 0000000..5043c39
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
@@ -0,0 +1,28 @@
+// 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 ReplaceFinalWithConst extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_FINAL_WITH_CONST;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is VariableDeclarationList) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ range.token((node as VariableDeclarationList).keyword), 'const');
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceFinalWithConst newInstance() => ReplaceFinalWithConst();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart
new file mode 100644
index 0000000..f9a6020
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.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.
+
+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/element/element.dart';
+import 'package:analyzer/dart/element/type.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 ReplaceNullWithClosure extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_NULL_WITH_CLOSURE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var nodeToFix;
+ var parameters = const <ParameterElement>[];
+ if (coveredNode is NamedExpression) {
+ NamedExpression namedExpression = coveredNode;
+ var expression = namedExpression.expression;
+ if (expression is NullLiteral) {
+ var element = namedExpression.element;
+ if (element is ParameterElement) {
+ var type = element.type;
+ if (type is FunctionType) {
+ parameters = type.parameters;
+ }
+ }
+ nodeToFix = expression;
+ }
+ } else if (coveredNode is NullLiteral) {
+ nodeToFix = coveredNode;
+ }
+
+ if (nodeToFix != null) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(nodeToFix),
+ (DartEditBuilder builder) {
+ builder.writeParameters(parameters);
+ builder.write(' => null');
+ });
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceNullWithClosure newInstance() => ReplaceNullWithClosure();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart
new file mode 100644
index 0000000..d2e6840
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart
@@ -0,0 +1,30 @@
+// 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 ReplaceWithBrackets extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_WITH_BRACKETS;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is EmptyStatement && node.parent is! Block) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var previous = node.findPrevious(node.beginToken);
+ if (previous != null) {
+ builder.addSimpleReplacement(range.endEnd(previous, node), ' {}');
+ }
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceWithBrackets newInstance() => ReplaceWithBrackets();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart
new file mode 100644
index 0000000..bd6f0c1
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart
@@ -0,0 +1,51 @@
+// 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 ReplaceWithConditionalAssignment extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ IfStatement ifStatement =
+ node is IfStatement ? node : node.thisOrAncestorOfType<IfStatement>();
+ if (ifStatement == null) {
+ return;
+ }
+ var thenStatement = ifStatement.thenStatement;
+ Statement uniqueStatement(Statement statement) {
+ if (statement is Block) {
+ return uniqueStatement(statement.statements.first);
+ }
+ return statement;
+ }
+
+ thenStatement = uniqueStatement(thenStatement);
+ if (thenStatement is ExpressionStatement) {
+ final expression = thenStatement.expression.unParenthesized;
+ if (expression is AssignmentExpression) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(ifStatement),
+ (DartEditBuilder builder) {
+ builder.write(utils.getNodeText(expression.leftHandSide));
+ builder.write(' ??= ');
+ builder.write(utils.getNodeText(expression.rightHandSide));
+ builder.write(';');
+ });
+ });
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceWithConditionalAssignment newInstance() =>
+ ReplaceWithConditionalAssignment();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart
new file mode 100644
index 0000000..2b810b2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart
@@ -0,0 +1,30 @@
+// 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 ReplaceWithIdentifier extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_WITH_IDENTIFIER;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var functionTyped =
+ node.thisOrAncestorOfType<FunctionTypedFormalParameter>();
+ if (functionTyped != null) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.node(functionTyped),
+ utils.getNodeText(functionTyped.identifier));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceWithIdentifier newInstance() => ReplaceWithIdentifier();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart
index 2c36432..6842ebb 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_interpolation.dart
@@ -21,10 +21,10 @@
// Validate the fix.
//
BinaryExpression binary;
- var parent = node.parent;
- while (_isStringConcatenation(parent)) {
- binary = parent;
- parent = parent.parent;
+ var candidate = node;
+ while (_isStringConcatenation(candidate)) {
+ binary = candidate;
+ candidate = candidate.parent;
}
if (binary == null) {
return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart
new file mode 100644
index 0000000..f32b089
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart
@@ -0,0 +1,111 @@
+// 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/token.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 ReplaceWithIsEmpty extends CorrectionProducer {
+ @override
+ FixKind fixKind;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ /// Return the value of an integer literal or prefix expression with a
+ /// minus and then an integer literal. For anything else, returns `null`.
+ int getIntValue(Expression expressions) {
+ // Copied from package:linter/src/rules/prefer_is_empty.dart.
+ if (expressions is IntegerLiteral) {
+ return expressions.value;
+ } else if (expressions is PrefixExpression) {
+ var operand = expressions.operand;
+ if (expressions.operator.type == TokenType.MINUS &&
+ operand is IntegerLiteral) {
+ return -operand.value;
+ }
+ }
+ return null;
+ }
+
+ /// Return the expression producing the object on which `length` is being
+ /// invoked, or `null` if there is no such expression.
+ Expression getLengthTarget(Expression expression) {
+ if (expression is PropertyAccess &&
+ expression.propertyName.name == 'length') {
+ return expression.target;
+ } else if (expression is PrefixedIdentifier &&
+ expression.identifier.name == 'length') {
+ return expression.prefix;
+ }
+ return null;
+ }
+
+ var binary = node.thisOrAncestorOfType<BinaryExpression>();
+ var operator = binary.operator.type;
+ String getter;
+ Expression lengthTarget;
+ var rightValue = getIntValue(binary.rightOperand);
+ if (rightValue != null) {
+ lengthTarget = getLengthTarget(binary.leftOperand);
+ if (rightValue == 0) {
+ if (operator == TokenType.EQ_EQ || operator == TokenType.LT_EQ) {
+ getter = 'isEmpty';
+ fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+ } else if (operator == TokenType.GT || operator == TokenType.BANG_EQ) {
+ getter = 'isNotEmpty';
+ fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+ }
+ } else if (rightValue == 1) {
+ // 'length >= 1' is same as 'isNotEmpty',
+ // and 'length < 1' is same as 'isEmpty'
+ if (operator == TokenType.GT_EQ) {
+ getter = 'isNotEmpty';
+ fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+ } else if (operator == TokenType.LT) {
+ getter = 'isEmpty';
+ fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+ }
+ }
+ } else {
+ var leftValue = getIntValue(binary.leftOperand);
+ if (leftValue != null) {
+ lengthTarget = getLengthTarget(binary.rightOperand);
+ if (leftValue == 0) {
+ if (operator == TokenType.EQ_EQ || operator == TokenType.GT_EQ) {
+ getter = 'isEmpty';
+ fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+ } else if (operator == TokenType.LT ||
+ operator == TokenType.BANG_EQ) {
+ getter = 'isNotEmpty';
+ fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+ }
+ } else if (leftValue == 1) {
+ // '1 <= length' is same as 'isNotEmpty',
+ // and '1 > length' is same as 'isEmpty'
+ if (operator == TokenType.LT_EQ) {
+ getter = 'isNotEmpty';
+ fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+ } else if (operator == TokenType.GT) {
+ getter = 'isEmpty';
+ fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+ }
+ }
+ }
+ }
+ if (lengthTarget == null || getter == null || fixKind == null) {
+ return;
+ }
+ var target = utils.getNodeText(lengthTarget);
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.node(binary), '$target.$getter');
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceWithIsEmpty newInstance() => ReplaceWithIsEmpty();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart
new file mode 100644
index 0000000..2699b40
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_null_aware.dart
@@ -0,0 +1,39 @@
+// 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 ReplaceWithNullAware extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_WITH_NULL_AWARE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = coveredNode;
+ if (node is Expression) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var parent = node.parent;
+ while (parent != null) {
+ if (parent is MethodInvocation && parent.target == node) {
+ builder.addSimpleReplacement(range.token(parent.operator), '?.');
+ } else if (parent is PropertyAccess && parent.target == node) {
+ builder.addSimpleReplacement(range.token(parent.operator), '?.');
+ } else {
+ break;
+ }
+ node = parent;
+ parent = node.parent;
+ }
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceWithNullAware newInstance() => ReplaceWithNullAware();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart
new file mode 100644
index 0000000..da55b5e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.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.
+
+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 ReplaceWithTearOff extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_WITH_TEAR_OFF;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var ancestor = node.thisOrAncestorOfType<FunctionExpression>();
+ if (ancestor == null) {
+ return;
+ }
+ Future<void> addFixOfExpression(InvocationExpression expression) async {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(ancestor), (DartEditBuilder builder) {
+ if (expression is MethodInvocation && expression.target != null) {
+ builder.write(utils.getNodeText(expression.target));
+ builder.write('.');
+ }
+ builder.write(utils.getNodeText(expression.function));
+ });
+ });
+ }
+
+ final body = ancestor.body;
+ if (body is ExpressionFunctionBody) {
+ final expression = body.expression;
+ await addFixOfExpression(expression.unParenthesized);
+ } else if (body is BlockFunctionBody) {
+ final statement = body.block.statements.first;
+ if (statement is ExpressionStatement) {
+ final expression = statement.expression;
+ await addFixOfExpression(expression.unParenthesized);
+ } else if (statement is ReturnStatement) {
+ final expression = statement.expression;
+ await addFixOfExpression(expression.unParenthesized);
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceWithTearOff newInstance() => ReplaceWithTearOff();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
index 2f8f19a..76a64d3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
@@ -21,7 +21,7 @@
@override
Future<void> compute(DartChangeBuilder builder) async {
- var type = node.thisOrAncestorOfType<TypeAnnotation>();
+ var type = _findType(node);
if (type == null) {
return;
}
@@ -133,6 +133,15 @@
return false;
}
+ /// Using the [node] as a starting point, return the type annotation that is
+ /// to be replaced, or `null` if there is no type annotation.
+ TypeAnnotation _findType(AstNode node) {
+ if (node is VariableDeclarationList) {
+ return node.type;
+ }
+ return node.thisOrAncestorOfType<TypeAnnotation>();
+ }
+
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
static ReplaceWithVar newInstance() => ReplaceWithVar();
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
index c4a0c23..1ce35bc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
@@ -21,8 +21,7 @@
@override
Future<void> compute(DartChangeBuilder builder) async {
- var childProp = flutter.findNamedExpression(node, 'child');
- childProp ??= flutter.findNamedExpression(node, 'children');
+ var childProp = _findNamedExpression(node);
if (childProp == null) {
return;
}
@@ -55,6 +54,19 @@
});
}
+ /// Using the [node] as the starting point, find the named expression that is
+ /// for either the `child` or `children` parameter.
+ NamedExpression _findNamedExpression(AstNode node) {
+ if (node is NamedExpression) {
+ var name = node.name.label.name;
+ if (name == 'child' || name == 'children') {
+ return node;
+ }
+ }
+ return flutter.findNamedExpression(node, 'child') ??
+ flutter.findNamedExpression(node, 'children');
+ }
+
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
static SortChildPropertyLast newInstance() => SortChildPropertyLast();
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_directives.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_directives.dart
new file mode 100644
index 0000000..2a09341
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_directives.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:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/organize_directives.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';
+
+class SortDirectives extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.SORT_DIRECTIVES;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var organizer =
+ DirectiveOrganizer(resolvedResult.content, unit, resolvedResult.errors);
+ // todo (pq): consider restructuring organizer to allow a passed-in change
+ // builder
+ for (var edit in organizer.organize()) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ SourceRange(edit.offset, edit.length), edit.replacement);
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static SortDirectives newInstance() => SortDirectives();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart
new file mode 100644
index 0000000..ec1506f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.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: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/token.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 UesIsNotEmpty extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.USE_IS_NOT_EMPTY;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! PrefixExpression) {
+ return;
+ }
+ PrefixExpression prefixExpression = node;
+ var negation = prefixExpression.operator;
+ if (negation.type != TokenType.BANG) {
+ return;
+ }
+ SimpleIdentifier identifier;
+ var expression = prefixExpression.operand;
+ if (expression is PrefixedIdentifier) {
+ identifier = expression.identifier;
+ } else if (expression is PropertyAccess) {
+ identifier = expression.propertyName;
+ } else {
+ return;
+ }
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.token(negation));
+ builder.addSimpleReplacement(range.node(identifier), 'isNotEmpty');
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static UesIsNotEmpty newInstance() => UesIsNotEmpty();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart
new file mode 100644
index 0000000..03861e3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart
@@ -0,0 +1,27 @@
+// 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 UseRethrow extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.USE_RETHROW;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (coveredNode is ThrowExpression) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.node(coveredNode), 'rethrow');
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static UseRethrow newInstance() => UseRethrow();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart
index e45c057..fbfc65e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_text.dart
@@ -50,17 +50,11 @@
/// corresponding parameter to [_parameterElement]. Leave the fields `null`
/// if not a named argument, or not a `String` typed expression.
void _extractContextInformation(AstNode node) {
- if (node is SimpleIdentifier) {
- var label = node.parent;
- if (label is Label) {
- var namedExpression = label.parent;
- if (namedExpression is NamedExpression) {
- var expression = namedExpression.expression;
- if (expression.staticType.isDartCoreString) {
- _parameterElement = node.staticElement;
- _stringExpression = expression;
- }
- }
+ if (node is NamedExpression) {
+ var expression = node.expression;
+ if (expression.staticType.isDartCoreString) {
+ _parameterElement = node.name.label.staticElement;
+ _stringExpression = expression;
}
}
}
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 db30359..131e355 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -26,43 +26,79 @@
import 'package:analysis_server/src/services/correction/dart/add_static.dart';
import 'package:analysis_server/src/services/correction/dart/add_type_annotation.dart';
import 'package:analysis_server/src/services/correction/dart/change_argument_name.dart';
+import 'package:analysis_server/src/services/correction/dart/change_to_nearest_precise_value.dart';
+import 'package:analysis_server/src/services/correction/dart/change_type_annotation.dart';
import 'package:analysis_server/src/services/correction/dart/convert_add_all_to_spread.dart';
import 'package:analysis_server/src/services/correction/dart/convert_conditional_expression_to_if_element.dart';
import 'package:analysis_server/src/services/correction/dart/convert_documentation_into_line.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_flutter_child.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_flutter_children.dart';
import 'package:analysis_server/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_quotes.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_contains.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_expression_function_body.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_if_null.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_int_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_list_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_named_arguments.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_on_type.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_package_import.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.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/create_method.dart';
import 'package:analysis_server/src/services/correction/dart/inline_invocation.dart';
import 'package:analysis_server/src/services/correction/dart/inline_typedef.dart';
+import 'package:analysis_server/src/services/correction/dart/make_final.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_argument.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_await.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_const.dart';
import 'package:analysis_server/src/services/correction/dart/remove_dead_if_null.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_duplicate_case.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_empty_catch.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_empty_constructor_body.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_empty_else.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_empty_statement.dart';
import 'package:analysis_server/src/services/correction/dart/remove_if_null_operator.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_initializer.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_interpolation_braces.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_method_declaration.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_operator.dart';
import 'package:analysis_server/src/services/correction/dart/remove_question_mark.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_this_expression.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_type_annotation.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_new.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unused.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unused_local_variable.dart';
+import 'package:analysis_server/src/services/correction/dart/rename_to_camel_case.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_boolean_with_bool.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_colon_with_equals.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_final_with_const.dart';
import 'package:analysis_server/src/services/correction/dart/replace_new_with_const.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_null_with_closure.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_brackets.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_conditional_assignment.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_eight_digit_hex.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_identifier.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_interpolation.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_is_empty.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_null_aware.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_tear_off.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart';
import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart';
+import 'package:analysis_server/src/services/correction/dart/sort_directives.dart';
import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
+import 'package:analysis_server/src/services/correction/dart/use_is_not_empty.dart';
+import 'package:analysis_server/src/services/correction/dart/use_rethrow.dart';
import 'package:analysis_server/src/services/correction/dart/wrap_in_future.dart';
import 'package:analysis_server/src/services/correction/dart/wrap_in_text.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';
import 'package:analysis_server/src/services/correction/namespace.dart';
-import 'package:analysis_server/src/services/correction/organize_directives.dart';
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
@@ -225,17 +261,27 @@
LintNames.annotate_overrides: [
AddOverride.newInstance,
],
-// LintNames.avoid_annotating_with_dynamic : [],
-// LintNames.avoid_empty_else : [],
-// LintNames.avoid_init_to_null : [],
+ LintNames.avoid_annotating_with_dynamic: [
+ RemoveTypeAnnotation.newInstance,
+ ],
+ LintNames.avoid_empty_else: [
+ RemoveEmptyElse.newInstance,
+ ],
+ LintNames.avoid_init_to_null: [
+ RemoveInitializer.newInstance,
+ ],
LintNames.avoid_private_typedef_functions: [
InlineTypedef.newInstance,
],
-// LintNames.avoid_redundant_argument_values : [],
+ LintNames.avoid_redundant_argument_values: [
+ RemoveArgument.newInstance,
+ ],
LintNames.avoid_relative_lib_imports: [
ConvertToPackageImport.newInstance,
],
-// LintNames.avoid_return_types_on_setters : [],
+ LintNames.avoid_return_types_on_setters: [
+ RemoveTypeAnnotation.newInstance,
+ ],
LintNames.avoid_returning_null_for_future: [
AddSync.newInstance,
WrapInFuture.newInstance,
@@ -243,32 +289,58 @@
LintNames.avoid_types_as_parameter_names: [
ConvertToOnType.newInstance,
],
-// LintNames.avoid_types_on_closure_parameters : [],
-// LintNames.await_only_futures : [],
+ LintNames.avoid_types_on_closure_parameters: [
+ ReplaceWithIdentifier.newInstance,
+ RemoveTypeAnnotation.newInstance,
+ ],
+ LintNames.await_only_futures: [
+ RemoveAwait.newInstance,
+ ],
LintNames.curly_braces_in_flow_control_structures: [
UseCurlyBraces.newInstance,
],
LintNames.diagnostic_describe_all_properties: [
AddDiagnosticPropertyReference.newInstance,
],
-// LintNames.directives_ordering : [],
-// LintNames.empty_catches : [],
-// LintNames.empty_constructor_bodies : [],
-// LintNames.empty_statements : [],
-// LintNames.hash_and_equals : [],
-// LintNames.no_duplicate_case_values : [],
-// LintNames.non_constant_identifier_names : [],
-// LintNames.null_closures : [],
+ LintNames.directives_ordering: [
+ SortDirectives.newInstance,
+ ],
+ LintNames.empty_catches: [
+ RemoveEmptyCatch.newInstance,
+ ],
+ LintNames.empty_constructor_bodies: [
+ RemoveEmptyConstructorBody.newInstance,
+ ],
+ LintNames.empty_statements: [
+ RemoveEmptyStatement.newInstance,
+ ReplaceWithBrackets.newInstance,
+ ],
+ LintNames.hash_and_equals: [
+ CreateMethod.newInstance,
+ ],
+ LintNames.no_duplicate_case_values: [
+ RemoveDuplicateCase.newInstance,
+ ],
+ LintNames.non_constant_identifier_names: [
+ RenameToCamelCase.newInstance,
+ ],
+ LintNames.null_closures: [
+ ReplaceNullWithClosure.newInstance,
+ ],
LintNames.omit_local_variable_types: [
ReplaceWithVar.newInstance,
],
-// LintNames.prefer_adjacent_string_concatenation : [],
+ LintNames.prefer_adjacent_string_concatenation: [
+ RemoveOperator.newInstance,
+ ],
LintNames.prefer_collection_literals: [
ConvertToListLiteral.newInstance,
ConvertToMapLiteral.newInstance,
ConvertToSetLiteral.newInstance,
],
-// LintNames.prefer_conditional_assignment : [],
+ LintNames.prefer_conditional_assignment: [
+ ReplaceWithConditionalAssignment.newInstance,
+ ],
LintNames.prefer_const_constructors: [
AddConst.newInstance,
ReplaceNewWithConst.newInstance,
@@ -276,16 +348,24 @@
LintNames.prefer_const_constructors_in_immutables: [
AddConst.newInstance,
],
-// LintNames.prefer_const_declarations : [],
+ LintNames.prefer_const_declarations: [
+ ReplaceFinalWithConst.newInstance,
+ ],
LintNames.prefer_contains: [
ConvertToContains.newInstance,
],
-// LintNames.prefer_equal_for_default_values : [],
+ LintNames.prefer_equal_for_default_values: [
+ ReplaceColonWithEquals.newInstance,
+ ],
LintNames.prefer_expression_function_bodies: [
ConvertToExpressionFunctionBody.newInstance,
],
-// LintNames.prefer_final_fields : [],
-// LintNames.prefer_final_locals : [],
+ LintNames.prefer_final_fields: [
+ MakeFinal.newInstance,
+ ],
+ LintNames.prefer_final_locals: [
+ MakeFinal.newInstance,
+ ],
LintNames.prefer_for_elements_to_map_fromIterable: [
ConvertMapFromIterableToForLiteral.newInstance,
],
@@ -295,9 +375,15 @@
LintNames.prefer_if_elements_to_conditional_expressions: [
ConvertConditionalExpressionToIfElement.newInstance,
],
-// LintNames.prefer_is_empty : [],
-// LintNames.prefer_is_not_empty : [],
-// LintNames.prefer_if_null_operators : [],
+ LintNames.prefer_is_empty: [
+ ReplaceWithIsEmpty.newInstance,
+ ],
+ LintNames.prefer_is_not_empty: [
+ UesIsNotEmpty.newInstance,
+ ],
+ LintNames.prefer_if_null_operators: [
+ ConvertToIfNull.newInstance,
+ ],
LintNames.prefer_inlined_adds: [
InlineInvocation.newInstance,
],
@@ -331,26 +417,42 @@
LintNames.type_annotate_public_apis: [
AddTypeAnnotation.newInstance,
],
-// LintNames.type_init_formals : [],
+ LintNames.type_init_formals: [
+ RemoveTypeAnnotation.newInstance,
+ ],
LintNames.unawaited_futures: [
AddAwait.newInstance,
],
-// LintNames.unnecessary_brace_in_string_interps : [],
-// LintNames.unnecessary_const : [],
-// LintNames.unnecessary_lambdas : [],
-// LintNames.unnecessary_new : [],
+ LintNames.unnecessary_brace_in_string_interps: [
+ RemoveInterpolationBraces.newInstance,
+ ],
+ LintNames.unnecessary_const: [
+ RemoveUnnecesaryConst.newInstance,
+ ],
+ LintNames.unnecessary_lambdas: [
+ ReplaceWithTearOff.newInstance,
+ ],
+ LintNames.unnecessary_new: [
+ RemoveUnnecessaryNew.newInstance,
+ ],
LintNames.unnecessary_null_in_if_null_operators: [
RemoveIfNullOperator.newInstance,
],
-// LintNames.unnecessary_overrides : [],
-// LintNames.unnecessary_this : [],
+ LintNames.unnecessary_overrides: [
+ RemoveMethodDeclaration.newInstance,
+ ],
+ LintNames.unnecessary_this: [
+ RemoveThisExpression.newInstance,
+ ],
LintNames.use_full_hex_values_for_flutter_colors: [
ReplaceWithEightDigitHex.newInstance,
],
LintNames.use_function_type_syntax_for_parameters: [
ConvertToGenericFunctionSyntax.newInstance,
],
-// LintNames.use_rethrow_when_possible : [],
+ LintNames.use_rethrow_when_possible: [
+ UseRethrow.newInstance,
+ ],
};
/// A map from error codes to a list of generators used to create multiple
@@ -377,12 +479,18 @@
CompileTimeErrorCode.CONST_INSTANCE_FIELD: [
AddStatic.newInstance,
],
-// CompileTimeErrorCode.CONST_WITH_NON_CONST : [],
+ CompileTimeErrorCode.CONST_WITH_NON_CONST: [
+ RemoveConst.newInstance,
+ ],
// CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER : [],
// CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS : [],
-// CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED : [],
+ CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED: [
+ ConvertToNamedArguments.newInstance,
+ ],
// CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD : [],
-// CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE : [],
+ CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE: [
+ ChangeToNearestPreciseValue.newInstance,
+ ],
// CompileTimeErrorCode.INVALID_ANNOTATION : [],
CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER: [
AddRequiredKeyword.newInstance,
@@ -408,11 +516,16 @@
// CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER : [],
// CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD : [],
// CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER : [],
-// CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER : [],
+ CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER: [
+ ConvertFlutterChild.newInstance,
+ ConvertFlutterChildren.newInstance,
+ ],
// CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE : [],
// CompileTimeErrorCode.URI_DOES_NOT_EXIST : [],
-// HintCode.CAN_BE_NULL_AFTER_NULL_AWARE : [],
+ HintCode.CAN_BE_NULL_AFTER_NULL_AWARE: [
+ ReplaceWithNullAware.newInstance,
+ ],
// HintCode.DEAD_CODE : [],
// HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH : [],
// HintCode.DEAD_CODE_ON_CATCH_SUBTYPE : [],
@@ -480,6 +593,7 @@
// StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER : [],
StaticTypeWarningCode.INVALID_ASSIGNMENT: [
AddExplicitCast.newInstance,
+ ChangeTypeAnnotation.newInstance,
],
// StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION : [],
// StaticTypeWarningCode.NON_BOOL_CONDITION : [],
@@ -523,7 +637,9 @@
// StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE : [],
// StaticWarningCode.NOT_A_TYPE : [],
// StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME : [],
-// StaticWarningCode.UNDEFINED_CLASS_BOOLEAN : [],
+ StaticWarningCode.UNDEFINED_CLASS_BOOLEAN: [
+ ReplaceBooleanWithBool.newInstance
+ ],
// StaticWarningCode.UNDEFINED_IDENTIFIER : [],
StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT: [
AddSync.newInstance,
@@ -580,17 +696,10 @@
// analyze ErrorCode
var errorCode = error.errorCode;
- if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) {
- await _addFix_boolInsteadOfBoolean();
- }
if (errorCode ==
CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) {
await _addFix_replaceWithConstInstanceCreation();
}
- if (errorCode == CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE) {
- await _addFix_changeToNearestPreciseValue();
- }
-
if (errorCode == CompileTimeErrorCode.INVALID_ANNOTATION ||
errorCode == CompileTimeErrorCode.UNDEFINED_ANNOTATION) {
if (node is Annotation) {
@@ -628,9 +737,6 @@
await _addFix_createImportUri();
await _addFix_createPartUri();
}
- if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) {
- await _addFix_canBeNullAfterNullAware();
- }
if (errorCode == HintCode.DEAD_CODE) {
await _addFix_removeDeadCode();
}
@@ -793,10 +899,6 @@
if (errorCode == StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE) {
await _addFix_importLibrary_withType();
}
- if (errorCode ==
- CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED) {
- await _addFix_convertToNamedArgument();
- }
if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) {
await _addFix_createConstructor_forUninitializedFinalFields();
}
@@ -824,9 +926,6 @@
await _addFix_useStaticAccess_method();
await _addFix_useStaticAccess_property();
}
- if (errorCode == StaticTypeWarningCode.INVALID_ASSIGNMENT) {
- await _addFix_changeTypeAnnotation();
- }
if (errorCode ==
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION) {
await _addFix_removeParentheses_inGetterInvocation();
@@ -839,9 +938,6 @@
await _addFix_createClass();
await _addFix_createMixin();
}
- if (errorCode == CompileTimeErrorCode.CONST_WITH_NON_CONST) {
- await _addFix_removeConstKeyword(DartFixKind.REMOVE_CONST);
- }
if (errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION) {
await _addFix_createClass();
await _addFix_importLibrary_withExtension();
@@ -888,10 +984,6 @@
await _addFix_undefinedClassAccessor_useSimilar();
await _addFix_createSetter();
}
- if (errorCode == CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER) {
- await _addFix_convertFlutterChild();
- await _addFix_convertFlutterChildren();
- }
if (errorCode ==
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD) {
await _addFix_createField_initializingFormal();
@@ -925,107 +1017,6 @@
// method or setter. The existing _addFix methods would need to be
// updated so that only the appropriate subset is generated.
}
- // lints
- if (errorCode is LintCode) {
- var name = errorCode.name;
- if (name == LintNames.avoid_annotating_with_dynamic) {
- await _addFix_removeTypeAnnotation();
- }
- if (name == LintNames.avoid_empty_else) {
- await _addFix_removeEmptyElse();
- }
- if (name == LintNames.avoid_init_to_null) {
- await _addFix_removeInitializer();
- }
- if (name == LintNames.avoid_redundant_argument_values) {
- await _addFix_removeArgument();
- }
- if (name == LintNames.avoid_return_types_on_setters) {
- await _addFix_removeTypeAnnotation();
- }
- if (name == LintNames.avoid_types_on_closure_parameters) {
- await _addFix_replaceWithIdentifier();
- }
- if (name == LintNames.await_only_futures) {
- await _addFix_removeAwait();
- }
- if (name == LintNames.directives_ordering) {
- await _addFix_sortDirectives();
- }
- if (name == LintNames.empty_catches) {
- await _addFix_removeEmptyCatch();
- }
- if (name == LintNames.empty_constructor_bodies) {
- await _addFix_removeEmptyConstructorBody();
- }
- if (name == LintNames.empty_statements) {
- await _addFix_removeEmptyStatement();
- }
- if (name == LintNames.hash_and_equals) {
- await _addFix_addMissingHashOrEquals();
- }
- if (name == LintNames.no_duplicate_case_values) {
- await _addFix_removeCaseStatement();
- }
- if (name == LintNames.non_constant_identifier_names) {
- await _addFix_renameToCamelCase();
- }
- if (name == LintNames.null_closures) {
- await _addFix_replaceNullWithClosure();
- }
- if (name == LintNames.prefer_adjacent_string_concatenation) {
- await _addFix_removeOperator();
- }
- if (name == LintNames.prefer_conditional_assignment) {
- await _addFix_replaceWithConditionalAssignment();
- }
- if (errorCode.name == LintNames.prefer_const_declarations) {
- await _addFix_replaceFinalWithConst();
- }
- if (errorCode.name == LintNames.prefer_equal_for_default_values) {
- await _addFix_replaceColonWithEquals();
- }
- if (name == LintNames.prefer_final_fields) {
- await _addFix_makeVariableFinal();
- }
- if (name == LintNames.prefer_final_locals) {
- await _addFix_makeVariableFinal();
- }
- if (name == LintNames.prefer_is_empty) {
- await _addFix_replaceWithIsEmpty();
- }
- if (name == LintNames.prefer_is_not_empty) {
- await _addFix_isNotEmpty();
- }
- if (errorCode.name == LintNames.prefer_if_null_operators) {
- await _addFix_convertToIfNullOperator();
- }
- if (name == LintNames.type_init_formals) {
- await _addFix_removeTypeAnnotation();
- }
- if (name == LintNames.unnecessary_brace_in_string_interps) {
- await _addFix_removeInterpolationBraces();
- }
- if (name == LintNames.unnecessary_const) {
- await _addFix_removeConstKeyword(DartFixKind.REMOVE_UNNECESSARY_CONST);
- }
- if (name == LintNames.unnecessary_lambdas) {
- await _addFix_replaceWithTearOff();
- }
- if (name == LintNames.unnecessary_new) {
- await _addFix_removeNewKeyword();
- }
- if (name == LintNames.unnecessary_overrides) {
- await _addFix_removeMethodDeclaration();
- }
- if (name == LintNames.unnecessary_this) {
- await _addFix_removeThisExpression();
- }
- if (name == LintNames.use_rethrow_when_possible) {
- await _addFix_replaceWithRethrow();
- }
- }
-
await _addFromProducers();
// done
@@ -1038,42 +1029,6 @@
return fixes.isNotEmpty ? fixes.first : null;
}
- Future<void> _addFix_addMissingHashOrEquals() async {
- final methodDecl = node.thisOrAncestorOfType<MethodDeclaration>();
- final classDecl = node.thisOrAncestorOfType<ClassDeclaration>();
- if (methodDecl != null && classDecl != null) {
- final classElement = classDecl.declaredElement;
-
- var element;
- var memberName;
- if (methodDecl.name.name == 'hashCode') {
- memberName = '==';
- element = classElement.lookUpInheritedMethod(
- memberName, classElement.library);
- } else {
- memberName = 'hashCode';
- element = classElement.lookUpInheritedConcreteGetter(
- memberName, classElement.library);
- }
-
- final location =
- utils.prepareNewClassMemberLocation(classDecl, (_) => true);
-
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (fileBuilder) {
- fileBuilder.addInsertion(location.offset, (builder) {
- builder.write(location.prefix);
- builder.writeOverride(element, invokeSuper: true);
- builder.write(location.suffix);
- });
- });
-
- changeBuilder.setSelection(Position(file, location.offset));
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD,
- args: [memberName]);
- }
- }
-
Future<void> _addFix_addMissingParameter() async {
// The error is reported on ArgumentList.
if (node is! ArgumentList) {
@@ -1200,253 +1155,6 @@
}
}
- Future<void> _addFix_boolInsteadOfBoolean() async {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.error(error), 'bool');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_BOOLEAN_WITH_BOOL);
- }
-
- Future<void> _addFix_canBeNullAfterNullAware() async {
- var node = coveredNode;
- if (node is Expression) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var parent = node.parent;
- while (parent != null) {
- if (parent is MethodInvocation && parent.target == node) {
- builder.addSimpleReplacement(range.token(parent.operator), '?.');
- } else if (parent is PropertyAccess && parent.target == node) {
- builder.addSimpleReplacement(range.token(parent.operator), '?.');
- } else {
- break;
- }
- node = parent;
- parent = node.parent;
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_NULL_AWARE);
- }
- }
-
- Future<void> _addFix_changeToNearestPreciseValue() async {
- IntegerLiteral integer = node;
- var lexeme = integer.literal.lexeme;
- var precise = BigInt.from(IntegerLiteralImpl.nearestValidDouble(lexeme));
- var correction = lexeme.toLowerCase().contains('x')
- ? '0x${precise.toRadixString(16).toUpperCase()}'
- : precise.toString();
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.node(integer), correction);
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE,
- args: [correction]);
- }
-
- Future<void> _addFix_changeTypeAnnotation() async {
- var declaration = coveredNode.parent;
- if (declaration is VariableDeclaration &&
- declaration.initializer == coveredNode) {
- var variableList = declaration.parent;
- if (variableList is VariableDeclarationList &&
- variableList.variables.length == 1) {
- var typeNode = variableList.type;
- if (typeNode != null) {
- Expression initializer = coveredNode;
- var newType = initializer.staticType;
- if (newType is InterfaceType || newType is FunctionType) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file,
- (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(typeNode),
- (DartEditBuilder builder) {
- builder.writeType(newType);
- });
- });
- _addFixFromBuilder(
- changeBuilder,
- DartFixKind.CHANGE_TYPE_ANNOTATION,
- args: [
- typeNode.type.getDisplayString(withNullability: false),
- newType.getDisplayString(withNullability: false),
- ],
- );
- }
- }
- }
- }
- }
-
- Future<void> _addFix_convertFlutterChild() async {
- var named = flutter.findNamedExpression(node, 'child');
- if (named == null) {
- return;
- }
-
- // child: widget
- var expression = named.expression;
- if (flutter.isWidgetExpression(expression)) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- flutter.convertChildToChildren2(
- builder,
- expression,
- named,
- eol,
- utils.getNodeText,
- utils.getLinePrefix,
- utils.getIndent,
- utils.getText,
- range.node);
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_FLUTTER_CHILD);
- return;
- }
-
- // child: [widget1, widget2]
- if (expression is ListLiteral &&
- expression.elements.every(flutter.isWidgetExpression)) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.node(named.name), 'children:');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_FLUTTER_CHILD);
- }
- }
-
- Future<void> _addFix_convertFlutterChildren() async {
- var node = this.node;
- if (node is SimpleIdentifier &&
- node.name == 'children' &&
- node.parent?.parent is NamedExpression) {
- NamedExpression named = node.parent?.parent;
- var expression = named.expression;
- if (expression is ListLiteral && expression.elements.length == 1) {
- var widget = expression.elements[0];
- if (flutter.isWidgetExpression(widget)) {
- var widgetText = utils.getNodeText(widget);
- var indentOld = utils.getLinePrefix(widget.offset);
- var indentNew = utils.getLinePrefix(named.offset);
- widgetText = _replaceSourceIndent(widgetText, indentOld, indentNew);
-
- var builder = _newDartChangeBuilder();
- await builder.addFileEdit(file, (builder) {
- builder.addReplacement(range.node(named), (builder) {
- builder.write('child: ');
- builder.write(widgetText);
- });
- });
- _addFixFromBuilder(builder, DartFixKind.CONVERT_FLUTTER_CHILDREN);
- }
- }
- }
- }
-
- Future<void> _addFix_convertToIfNullOperator() async {
- var conditional = node.thisOrAncestorOfType<ConditionalExpression>();
- if (conditional == null) {
- return;
- }
- var condition = conditional.condition as BinaryExpression;
- Expression nullableExpression;
- Expression defaultExpression;
- if (condition.operator.type == TokenType.EQ_EQ) {
- nullableExpression = conditional.elseExpression;
- defaultExpression = conditional.thenExpression;
- } else {
- nullableExpression = conditional.thenExpression;
- defaultExpression = conditional.elseExpression;
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(conditional), (builder) {
- builder.write(utils.getNodeText(nullableExpression));
- builder.write(' ?? ');
- builder.write(utils.getNodeText(defaultExpression));
- });
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_IF_NULL);
- }
-
- Future<void> _addFix_convertToNamedArgument() async {
- var argumentList = node;
- if (argumentList is ArgumentList) {
- // Prepare parameters.
- List<ParameterElement> parameters;
- var parent = argumentList.parent;
- if (parent is FunctionExpressionInvocation) {
- var invokeType = parent.staticInvokeType;
- if (invokeType is FunctionType) {
- parameters = invokeType.parameters;
- }
- } else if (parent is InstanceCreationExpression) {
- parameters = parent.staticElement?.parameters;
- } else if (parent is MethodInvocation) {
- var invokeType = parent.staticInvokeType;
- if (invokeType is FunctionType) {
- parameters = invokeType.parameters;
- }
- }
- if (parameters == null) {
- return;
- }
-
- // Prepare named parameters.
- var numberOfPositionalParameters = 0;
- var namedParameters = <ParameterElement>[];
- for (var parameter in parameters) {
- if (parameter.isNamed) {
- namedParameters.add(parameter);
- } else {
- numberOfPositionalParameters++;
- }
- }
- if (argumentList.arguments.length <= numberOfPositionalParameters) {
- return;
- }
-
- // Find named parameters for extra arguments.
- var argumentToParameter = <Expression, ParameterElement>{};
- var extraArguments =
- argumentList.arguments.skip(numberOfPositionalParameters);
- for (var argument in extraArguments) {
- if (argument is! NamedExpression) {
- ParameterElement uniqueNamedParameter;
- for (var namedParameter in namedParameters) {
- if (typeSystem.isSubtypeOf(
- argument.staticType, namedParameter.type)) {
- if (uniqueNamedParameter == null) {
- uniqueNamedParameter = namedParameter;
- } else {
- uniqueNamedParameter = null;
- break;
- }
- }
- }
- if (uniqueNamedParameter != null) {
- argumentToParameter[argument] = uniqueNamedParameter;
- namedParameters.remove(uniqueNamedParameter);
- }
- }
- }
- if (argumentToParameter.isEmpty) {
- return;
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- for (var argument in argumentToParameter.keys) {
- var parameter = argumentToParameter[argument];
- builder.addSimpleInsertion(argument.offset, '${parameter.name}: ');
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_NAMED_ARGUMENTS);
- }
- }
-
Future<void> _addFix_createClass() async {
Element prefixElement;
String name;
@@ -2782,32 +2490,6 @@
}
}
- Future<void> _addFix_isNotEmpty() async {
- if (node is! PrefixExpression) {
- return;
- }
- PrefixExpression prefixExpression = node;
- var negation = prefixExpression.operator;
- if (negation.type != TokenType.BANG) {
- return;
- }
- SimpleIdentifier identifier;
- var expression = prefixExpression.operand;
- if (expression is PrefixedIdentifier) {
- identifier = expression.identifier;
- } else if (expression is PropertyAccess) {
- identifier = expression.propertyName;
- } else {
- return;
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.token(negation));
- builder.addSimpleReplacement(range.node(identifier), 'isNotEmpty');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.USE_IS_NOT_EMPTY);
- }
-
Future<void> _addFix_isNotNull() async {
if (coveredNode is IsExpression) {
var isExpression = coveredNode as IsExpression;
@@ -2896,25 +2578,6 @@
}
}
- Future<void> _addFix_makeVariableFinal() async {
- var node = this.node;
- if (node is SimpleIdentifier && node.parent is VariableDeclaration) {
- VariableDeclaration declaration = node.parent;
- VariableDeclarationList list = declaration.parent;
- if (list.variables.length == 1) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- if (list.keyword == null) {
- builder.addSimpleInsertion(list.offset, 'final ');
- } else if (list.keyword.keyword == Keyword.VAR) {
- builder.addSimpleReplacement(range.token(list.keyword), 'final');
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.MAKE_FINAL);
- }
- }
- }
-
Future<void> _addFix_makeVariableNotFinal() async {
var node = this.node;
if (node is SimpleIdentifier &&
@@ -3055,64 +2718,6 @@
}
}
- Future<void> _addFix_removeArgument() async {
- var arg = node;
- if (arg.parent is NamedExpression) {
- arg = arg.parent;
- }
-
- var argumentList = arg.parent.thisOrAncestorOfType<ArgumentList>();
- if (argumentList != null) {
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (builder) {
- final sourceRange = range.nodeInList(argumentList.arguments, arg);
- builder.addDeletion(sourceRange);
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_ARGUMENT);
- }
- }
-
- Future<void> _addFix_removeAwait() async {
- final awaitExpression = node;
- if (awaitExpression is AwaitExpression) {
- final awaitToken = awaitExpression.awaitKeyword;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startStart(awaitToken, awaitToken.next));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_AWAIT);
- }
- }
-
- Future<void> _addFix_removeCaseStatement() async {
- if (coveredNode is SwitchCase) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(utils.getLinesRange(range.node(coveredNode)));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DUPLICATE_CASE);
- }
- }
-
- Future<void> _addFix_removeConstKeyword(FixKind kind) async {
- final expression = node;
- if (expression is InstanceCreationExpression) {
- final constToken = expression.keyword;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startStart(constToken, constToken.next));
- });
- _addFixFromBuilder(changeBuilder, kind);
- } else if (expression is TypedLiteralImpl) {
- final constToken = expression.constKeyword;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startStart(constToken, constToken.next));
- });
- _addFixFromBuilder(changeBuilder, kind);
- }
- }
-
Future<void> _addFix_removeDeadCode() async {
var coveringNode = coveredNode;
if (coveringNode is Expression) {
@@ -3164,117 +2769,6 @@
}
}
- Future<void> _addFix_removeEmptyCatch() async {
- if (node.parent is! CatchClause) {
- return;
- }
- var catchClause = node.parent as CatchClause;
-
- var tryStatement = catchClause.parent as TryStatement;
- if (tryStatement.catchClauses.length == 1 &&
- tryStatement.finallyBlock == null) {
- return;
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(utils.getLinesRange(range.node(catchClause)));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_EMPTY_CATCH);
- }
-
- Future<void> _addFix_removeEmptyConstructorBody() async {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- utils.getLinesRange(range.node(node.parent)), ';');
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY);
- }
-
- Future<void> _addFix_removeEmptyElse() async {
- IfStatement ifStatement = node.parent;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(utils.getLinesRange(
- range.startEnd(ifStatement.elseKeyword, ifStatement.elseStatement)));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_EMPTY_ELSE);
- }
-
- Future<void> _addFix_removeEmptyStatement() async {
- EmptyStatement emptyStatement = node;
- if (emptyStatement.parent is Block) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(utils.getLinesRange(range.node(emptyStatement)));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_EMPTY_STATEMENT);
- } else {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var previous = emptyStatement.findPrevious(emptyStatement.beginToken);
- if (previous != null) {
- builder.addSimpleReplacement(
- range.endEnd(previous, emptyStatement), ' {}');
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_BRACKETS);
- }
- }
-
- Future<void> _addFix_removeInitializer() async {
- // Handle formal parameters with default values.
- var parameter = node.thisOrAncestorOfType<DefaultFormalParameter>();
- if (parameter != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(
- range.endEnd(parameter.identifier, parameter.defaultValue));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_INITIALIZER);
- return;
- }
- // Handle variable declarations with default values.
- var variable = node.thisOrAncestorOfType<VariableDeclaration>();
- if (variable != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.endEnd(variable.name, variable.initializer));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_INITIALIZER);
- }
- }
-
- Future<void> _addFix_removeInterpolationBraces() async {
- var node = this.node;
- if (node is InterpolationExpression) {
- var right = node.rightBracket;
- if (node.expression != null && right != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- range.startStart(node, node.expression), r'$');
- builder.addDeletion(range.token(right));
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REMOVE_INTERPOLATION_BRACES);
- } else {}
- }
- }
-
- Future<void> _addFix_removeMethodDeclaration() async {
- var declaration = node.thisOrAncestorOfType<MethodDeclaration>();
- if (declaration != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(utils.getLinesRange(range.node(declaration)));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_METHOD_DECLARATION);
- }
- }
-
Future<void> _addFix_removeNameFromCombinator() async {
SourceRange rangeForCombinator(Combinator combinator) {
var parent = combinator.parent;
@@ -3340,31 +2834,6 @@
}
}
- Future<void> _addFix_removeNewKeyword() async {
- final instanceCreationExpression = node;
- if (instanceCreationExpression is InstanceCreationExpression) {
- final newToken = instanceCreationExpression.keyword;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startStart(newToken, newToken.next));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNNECESSARY_NEW);
- }
- }
-
- Future<void> _addFix_removeOperator() async {
- if (node is BinaryExpression) {
- var expression = node as BinaryExpression;
- var operator = expression.operator;
- var rightOperand = expression.rightOperand;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startStart(operator, rightOperand));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_OPERATOR);
- }
- }
-
Future<void> _addFix_removeParameters_inGetterDeclaration() async {
if (node is MethodDeclaration) {
// Support for the analyzer error.
@@ -3402,50 +2871,6 @@
}
}
- Future<void> _addFix_removeThisExpression() async {
- if (node is ConstructorFieldInitializer) {
- var initializer = node as ConstructorFieldInitializer;
- var thisKeyword = initializer.thisKeyword;
- if (thisKeyword != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var fieldName = initializer.fieldName;
- builder.addDeletion(range.startStart(thisKeyword, fieldName));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION);
- }
- return;
- }
- final thisExpression = node is ThisExpression
- ? node
- : node.thisOrAncestorOfType<ThisExpression>();
- final parent = thisExpression?.parent;
- if (parent is PropertyAccess) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startEnd(parent, parent.operator));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION);
- } else if (parent is MethodInvocation) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startEnd(parent, parent.operator));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION);
- }
- }
-
- Future<void> _addFix_removeTypeAnnotation() async {
- var type = node.thisOrAncestorOfType<TypeAnnotation>();
- if (type != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startStart(type, type.endToken.next));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_TYPE_ANNOTATION);
- }
- }
-
Future<void> _addFix_removeTypeArguments() async {
if (coveredNode is TypeArgumentList) {
TypeArgumentList typeArguments = coveredNode;
@@ -3532,103 +2957,6 @@
}
}
- Future<void> _addFix_renameToCamelCase() async {
- if (node is! SimpleIdentifier) {
- return;
- }
- SimpleIdentifier identifier = node;
-
- // Prepare the new name.
- var words = identifier.name.split('_');
- if (words.length < 2) {
- return;
- }
- var newName = words.first + words.skip(1).map((w) => capitalize(w)).join();
-
- // Find references to the identifier.
- List<SimpleIdentifier> references;
- var element = identifier.staticElement;
- if (element is LocalVariableElement) {
- AstNode root = node.thisOrAncestorOfType<Block>();
- references = findLocalElementReferences(root, element);
- } else if (element is ParameterElement) {
- if (!element.isNamed) {
- var root = node.thisOrAncestorMatching((node) =>
- node.parent is ClassOrMixinDeclaration ||
- node.parent is CompilationUnit);
- references = findLocalElementReferences(root, element);
- }
- }
- if (references == null) {
- return;
- }
-
- // Compute the change.
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- for (var reference in references) {
- builder.addSimpleReplacement(range.node(reference), newName);
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.RENAME_TO_CAMEL_CASE,
- args: [newName]);
- }
-
- Future<void> _addFix_replaceColonWithEquals() async {
- if (node is DefaultFormalParameter) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- range.token((node as DefaultFormalParameter).separator), ' =');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_COLON_WITH_EQUALS);
- }
- }
-
- Future<void> _addFix_replaceFinalWithConst() async {
- if (node is VariableDeclarationList) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- range.token((node as VariableDeclarationList).keyword), 'const');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_FINAL_WITH_CONST);
- }
- }
-
- Future<void> _addFix_replaceNullWithClosure() async {
- var nodeToFix;
- var parameters = const <ParameterElement>[];
- if (coveredNode is NamedExpression) {
- NamedExpression namedExpression = coveredNode;
- var expression = namedExpression.expression;
- if (expression is NullLiteral) {
- var element = namedExpression.element;
- if (element is ParameterElement) {
- var type = element.type;
- if (type is FunctionType) {
- parameters = type.parameters;
- }
- }
- nodeToFix = expression;
- }
- } else if (coveredNode is NullLiteral) {
- nodeToFix = coveredNode;
- }
-
- if (nodeToFix != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(nodeToFix),
- (DartEditBuilder builder) {
- builder.writeParameters(parameters);
- builder.write(' => null');
- });
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_NULL_WITH_CLOSURE);
- }
- }
-
Future<void> _addFix_replaceVarWithDynamic() async {
var changeBuilder = _newDartChangeBuilder();
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -3637,40 +2965,6 @@
_addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_VAR_WITH_DYNAMIC);
}
- Future<void> _addFix_replaceWithConditionalAssignment() async {
- IfStatement ifStatement =
- node is IfStatement ? node : node.thisOrAncestorOfType<IfStatement>();
- if (ifStatement == null) {
- return;
- }
- var thenStatement = ifStatement.thenStatement;
- Statement uniqueStatement(Statement statement) {
- if (statement is Block) {
- return uniqueStatement(statement.statements.first);
- }
- return statement;
- }
-
- thenStatement = uniqueStatement(thenStatement);
- if (thenStatement is ExpressionStatement) {
- final expression = thenStatement.expression.unParenthesized;
- if (expression is AssignmentExpression) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(ifStatement),
- (DartEditBuilder builder) {
- builder.write(utils.getNodeText(expression.leftHandSide));
- builder.write(' ??= ');
- builder.write(utils.getNodeText(expression.rightHandSide));
- builder.write(';');
- });
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT);
- }
- }
- }
-
Future<void> _addFix_replaceWithConstInstanceCreation() async {
if (coveredNode is InstanceCreationExpression) {
var instanceCreation = coveredNode as InstanceCreationExpression;
@@ -3712,175 +3006,6 @@
args: [override.extensionName.name]);
}
- Future<void> _addFix_replaceWithIdentifier() async {
- var functionTyped =
- node.thisOrAncestorOfType<FunctionTypedFormalParameter>();
- if (functionTyped != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.node(functionTyped),
- utils.getNodeText(functionTyped.identifier));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_IDENTIFIER);
- } else {
- await _addFix_removeTypeAnnotation();
- }
- }
-
- Future<void> _addFix_replaceWithIsEmpty() async {
- /// Return the value of an integer literal or prefix expression with a
- /// minus and then an integer literal. For anything else, returns `null`.
- int getIntValue(Expression expressions) {
- // Copied from package:linter/src/rules/prefer_is_empty.dart.
- if (expressions is IntegerLiteral) {
- return expressions.value;
- } else if (expressions is PrefixExpression) {
- var operand = expressions.operand;
- if (expressions.operator.type == TokenType.MINUS &&
- operand is IntegerLiteral) {
- return -operand.value;
- }
- }
- return null;
- }
-
- /// Return the expression producing the object on which `length` is being
- /// invoked, or `null` if there is no such expression.
- Expression getLengthTarget(Expression expression) {
- if (expression is PropertyAccess &&
- expression.propertyName.name == 'length') {
- return expression.target;
- } else if (expression is PrefixedIdentifier &&
- expression.identifier.name == 'length') {
- return expression.prefix;
- }
- return null;
- }
-
- var binary = node.thisOrAncestorOfType<BinaryExpression>();
- var operator = binary.operator.type;
- String getter;
- FixKind kind;
- Expression lengthTarget;
- var rightValue = getIntValue(binary.rightOperand);
- if (rightValue != null) {
- lengthTarget = getLengthTarget(binary.leftOperand);
- if (rightValue == 0) {
- if (operator == TokenType.EQ_EQ || operator == TokenType.LT_EQ) {
- getter = 'isEmpty';
- kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
- } else if (operator == TokenType.GT || operator == TokenType.BANG_EQ) {
- getter = 'isNotEmpty';
- kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
- }
- } else if (rightValue == 1) {
- // 'length >= 1' is same as 'isNotEmpty',
- // and 'length < 1' is same as 'isEmpty'
- if (operator == TokenType.GT_EQ) {
- getter = 'isNotEmpty';
- kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
- } else if (operator == TokenType.LT) {
- getter = 'isEmpty';
- kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
- }
- }
- } else {
- var leftValue = getIntValue(binary.leftOperand);
- if (leftValue != null) {
- lengthTarget = getLengthTarget(binary.rightOperand);
- if (leftValue == 0) {
- if (operator == TokenType.EQ_EQ || operator == TokenType.GT_EQ) {
- getter = 'isEmpty';
- kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
- } else if (operator == TokenType.LT ||
- operator == TokenType.BANG_EQ) {
- getter = 'isNotEmpty';
- kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
- }
- } else if (leftValue == 1) {
- // '1 <= length' is same as 'isNotEmpty',
- // and '1 > length' is same as 'isEmpty'
- if (operator == TokenType.LT_EQ) {
- getter = 'isNotEmpty';
- kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
- } else if (operator == TokenType.GT) {
- getter = 'isEmpty';
- kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
- }
- }
- }
- }
- if (lengthTarget == null || getter == null || kind == null) {
- return;
- }
- var target = utils.getNodeText(lengthTarget);
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.node(binary), '$target.$getter');
- });
- _addFixFromBuilder(changeBuilder, kind);
- }
-
- Future<void> _addFix_replaceWithRethrow() async {
- if (coveredNode is ThrowExpression) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.node(coveredNode), 'rethrow');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.USE_RETHROW);
- }
- }
-
- Future<void> _addFix_replaceWithTearOff() async {
- var ancestor = node.thisOrAncestorOfType<FunctionExpression>();
- if (ancestor == null) {
- return;
- }
- Future<void> addFixOfExpression(InvocationExpression expression) async {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(ancestor), (DartEditBuilder builder) {
- if (expression is MethodInvocation && expression.target != null) {
- builder.write(utils.getNodeText(expression.target));
- builder.write('.');
- }
- builder.write(utils.getNodeText(expression.function));
- });
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_TEAR_OFF);
- }
-
- final body = ancestor.body;
- if (body is ExpressionFunctionBody) {
- final expression = body.expression;
- await addFixOfExpression(expression.unParenthesized);
- } else if (body is BlockFunctionBody) {
- final statement = body.block.statements.first;
- if (statement is ExpressionStatement) {
- final expression = statement.expression;
- await addFixOfExpression(expression.unParenthesized);
- } else if (statement is ReturnStatement) {
- final expression = statement.expression;
- await addFixOfExpression(expression.unParenthesized);
- }
- }
- }
-
- Future<void> _addFix_sortDirectives() async {
- var organizer =
- DirectiveOrganizer(resolvedResult.content, unit, resolvedResult.errors);
-
- var changeBuilder = _newDartChangeBuilder();
- // todo (pq): consider restructuring organizer to allow a passed-in change builder
- for (var edit in organizer.organize()) {
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- SourceRange(edit.offset, edit.length), edit.replacement);
- });
- }
- _addFixFromBuilder(changeBuilder, DartFixKind.SORT_DIRECTIVES);
- }
-
Future<void> _addFix_undefinedClass_useSimilar() async {
var node = this.node;
// Prepare the optional import prefix name.
@@ -4222,7 +3347,7 @@
diagnostic: error,
resolvedResult: resolvedResult,
selectionOffset: errorOffset,
- selectionLength: 0,
+ selectionLength: errorLength,
workspace: workspace,
);
@@ -4659,11 +3784,6 @@
}
return false;
}
-
- static String _replaceSourceIndent(
- String source, String indentOld, String indentNew) {
- return source.replaceAll(RegExp('^$indentOld', multiLine: true), indentNew);
- }
}
/// Helper for finding [Element] with name closest to the given.
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index b31a487..edcae43 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -723,4 +723,108 @@
expect(hover.elementKind, 'parameter');
expect(hover.staticType, 'int');
}
+
+ Future<void> test_setter_hasDocumentation() async {
+ addTestFile('''
+class A {
+ /// getting
+ int get foo => 42;
+ /// setting
+ set foo(int x) {}
+}
+main(A a) {
+ a.foo = 123;
+}
+''');
+ var hover = await prepareHover('foo = ');
+ expect(hover.containingClassDescription, 'A');
+ expect(hover.dartdoc, '''setting''');
+ expect(hover.elementDescription, 'void set foo(int x)');
+ expect(hover.elementKind, 'setter');
+ }
+
+ Future<void> test_setter_noDocumentation() async {
+ addTestFile('''
+class A {
+ /// getting
+ int get foo => 42;
+ set foo(int x) {}
+}
+main(A a) {
+ a.foo = 123;
+}
+''');
+ var hover = await prepareHover('foo = ');
+ expect(hover.containingClassDescription, 'A');
+ expect(hover.dartdoc, '''getting''');
+ expect(hover.elementDescription, 'void set foo(int x)');
+ expect(hover.elementKind, 'setter');
+ }
+
+ Future<void> test_setter_super_hasDocumentation() async {
+ addTestFile('''
+class A {
+ /// pgetting
+ int get foo => 42;
+ /// psetting
+ set foo(int x) {}
+}
+class B extends A {
+ /// getting
+ int get foo => 42;
+ set foo(int x) {}
+}
+main(B b) {
+ b.foo = 123;
+}
+''');
+ var hover = await prepareHover('foo = ');
+ expect(hover.containingClassDescription, 'B');
+ expect(hover.dartdoc, '''psetting\n\nCopied from `A`.''');
+ expect(hover.elementDescription, 'void set foo(int x)');
+ expect(hover.elementKind, 'setter');
+ }
+
+ Future<void> test_setter_super_noDocumentation() async {
+ addTestFile('''
+class A {
+ /// pgetting
+ int get foo => 42;
+ set foo(int x) {}
+}
+class B extends A {
+ int get foo => 42;
+ set foo(int x) {}
+}
+main(B b) {
+ b.foo = 123;
+}
+''');
+ var hover = await prepareHover('foo = ');
+ expect(hover.containingClassDescription, 'B');
+ expect(hover.dartdoc, '''pgetting\n\nCopied from `A`.''');
+ expect(hover.elementDescription, 'void set foo(int x)');
+ expect(hover.elementKind, 'setter');
+ }
+
+ @failingTest
+ Future<void> test_setter_super_noSetter() async {
+ addTestFile('''
+class A {
+ /// pgetting
+ int get foo => 42;
+}
+class B extends A {
+ set foo(int x) {}
+}
+main(B b) {
+ b.foo = 123;
+}
+''');
+ var hover = await prepareHover('foo = ');
+ expect(hover.containingClassDescription, 'B');
+ expect(hover.dartdoc, '''pgetting''');
+ expect(hover.elementDescription, 'void set foo(int x)');
+ expect(hover.elementKind, 'setter');
+ }
}
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 72c03d1..22e4923 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -314,9 +314,6 @@
<String>['1+v', '2+void'],
failingTests: '2');
- buildTests('testCommentSnippets059', '''
-f(){((int x) => x+4).!1call(1);}''', <String>['1-call']);
-
buildTests('testCommentSnippets060', '''
class Map{}
abstract class MM extends Map{factory MM() => new Map();}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index cd6b0a1..7b28181 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -219,7 +219,8 @@
String paramType,
String defaultArgListString = _UNCHECKED,
List<int> defaultArgumentListTextRanges,
- bool isSynthetic = false}) {
+ bool isSynthetic = false,
+ bool skipLocationCheck = false}) {
var cs =
getSuggest(completion: completion, csKind: csKind, elemKind: elemKind);
if (cs == null) {
@@ -235,7 +236,7 @@
expect(cs.selectionLength, equals(0));
expect(cs.isDeprecated, equals(isDeprecated));
expect(cs.isPotential, equals(isPotential));
- if (!isSynthetic && cs.element != null) {
+ if (!isSynthetic && cs.element != null && !skipLocationCheck) {
expect(cs.element.location, isNotNull);
expect(cs.element.location.file, isNotNull);
expect(cs.element.location.offset, isNotNull);
@@ -466,13 +467,15 @@
CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
bool isDeprecated = false,
String defaultArgListString = _UNCHECKED,
- List<int> defaultArgumentListTextRanges}) {
+ List<int> defaultArgumentListTextRanges,
+ bool skipLocationCheck = false}) {
var cs = assertSuggest(name,
csKind: kind,
relevance: relevance,
isDeprecated: isDeprecated,
defaultArgListString: defaultArgListString,
- defaultArgumentListTextRanges: defaultArgumentListTextRanges);
+ defaultArgumentListTextRanges: defaultArgumentListTextRanges,
+ skipLocationCheck: skipLocationCheck);
expect(cs.declaringType, equals(declaringType));
expect(cs.returnType, returnType ?? 'dynamic');
var element = cs.element;
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index ba32930..0ee70bf 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -22,6 +22,30 @@
return StaticMemberContributor();
}
+ Future<void> test_class_static_notPrivate() async {
+ addSource('/home/test/lib/a.dart', '''
+class A {
+ static int _f;
+ static String get _g => '';
+ static int _m() {}
+ static set _s(v) {}
+ A._();
+}
+''');
+ addTestSource('''
+import 'a.dart';
+void f() {
+ A.^;
+}
+''');
+ await computeSuggestions();
+ assertNotSuggested('_f');
+ assertNotSuggested('_g');
+ assertNotSuggested('_m');
+ assertNotSuggested('_s');
+ assertNotSuggested('A._');
+ }
+
Future<void> test_enumConst() async {
addTestSource('enum E { one, two } main() {E.^}');
await computeSuggestions();
@@ -108,6 +132,28 @@
assertSuggestField('s', 'String');
}
+ Future<void> test_extension_static_notPrivate() async {
+ addSource('/home/test/lib/a.dart', '''
+extension E {
+ static int _f;
+ static String get _g => '';
+ static int _m() {}
+ static set _s(v) {}
+}
+''');
+ addTestSource('''
+import 'a.dart';
+void f() {
+ E.^;
+}
+''');
+ await computeSuggestions();
+ assertNotSuggested('_f');
+ assertNotSuggested('_g');
+ assertNotSuggested('_m');
+ assertNotSuggested('_s');
+ }
+
Future<void> test_implicitCreation() async {
addSource('/home/test/lib/a.dart', '''
class A {
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index 3d6bdb5..3ac6f0f 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -2032,8 +2032,8 @@
await computeSuggestions();
assertSuggest(
- 'call()',
- selectionOffset: 6,
+ 'call',
+ selectionOffset: 4,
elemKind: ElementKind.METHOD,
isSynthetic: true,
);
@@ -2265,8 +2265,8 @@
await computeSuggestions();
assertSuggest(
- 'call()',
- selectionOffset: 6,
+ 'call',
+ selectionOffset: 4,
elemKind: ElementKind.METHOD,
isSynthetic: true,
);
@@ -2283,6 +2283,7 @@
await computeSuggestions();
assertNotSuggested('call');
+ assertNotSuggested('call()');
}
Future<void> test_InterfaceType_Function_implemented_call() async {
@@ -2296,6 +2297,7 @@
await computeSuggestions();
assertNotSuggested('call');
+ assertNotSuggested('call()');
}
Future<void> test_InterpolationExpression() async {
@@ -4165,6 +4167,29 @@
assertNotSuggested('C2');
}
+ Future<void> test_Typedef_members() async {
+ addTestSource('''
+ typedef Object Func();
+ class A {
+ Func f;
+ void a() => f.^;
+ }
+ main() {}''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a()');
+ assertNotSuggested('Func()');
+ assertSuggestMethod('call', null, 'void', skipLocationCheck: true);
+ assertSuggestGetter('hashCode', 'int');
+ assertSuggestGetter('runtimeType', 'Type');
+ assertSuggestMethod('toString', 'Object', 'String');
+ assertSuggestMethod('noSuchMethod', 'Object', 'dynamic');
+ assertNotSuggested('Object');
+ assertNotSuggested('A');
+ assertNotSuggested('==');
+ }
+
Future<void> test_VariableDeclaration_name() async {
// SimpleIdentifier VariableDeclaration VariableDeclarationList
// VariableDeclarationStatement Block
diff --git a/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart
index 696000e..ddff7c5 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart
@@ -187,7 +187,7 @@
assertRefactoringStatusOK(refactoring.checkNewName());
}
- Future<void> test_createChange_MethodElement_instance() async {
+ Future<void> test_createChange_named_MethodElement_instance() async {
await indexTestUnit('''
class A {}
@@ -223,7 +223,7 @@
''');
}
- Future<void> test_createChange_PropertyAccessorElement_getter() async {
+ Future<void> test_createChange_named_PropertyAccessorElement_getter() async {
await indexTestUnit('''
extension E on int {
get test {} // marker
@@ -266,7 +266,7 @@
''');
}
- Future<void> test_createChange_PropertyAccessorElement_setter() async {
+ Future<void> test_createChange_named_PropertyAccessorElement_setter() async {
await indexTestUnit('''
extension E on int {
get test {}
@@ -309,7 +309,7 @@
''');
}
- Future<void> test_createChange_TypeParameterElement() async {
+ Future<void> test_createChange_named_TypeParameterElement() async {
await indexTestUnit('''
extension E<Test> on int {
Test get g1 => null;
@@ -332,4 +332,32 @@
}
''');
}
+
+ Future<void> test_createChange_unnamed_MethodElement_instance() async {
+ await indexTestUnit('''
+extension on int {
+ void test() {} // marker
+}
+
+main() {
+ 0.test();
+}
+''');
+ // configure refactoring
+ createRenameRefactoringAtString('test() {} // marker');
+ expect(refactoring.refactoringName, 'Rename Method');
+ expect(refactoring.elementKindName, 'method');
+ expect(refactoring.oldName, 'test');
+ refactoring.newName = 'newName';
+ // validate change
+ return assertSuccessfulRefactoring('''
+extension on int {
+ void newName() {} // marker
+}
+
+main() {
+ 0.newName();
+}
+''');
+ }
}
diff --git a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
new file mode 100644
index 0000000..28d30aa
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
@@ -0,0 +1,197 @@
+// 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/completion/dart/feature_computer.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../abstract_single_unit.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FeatureComputerTest);
+ });
+}
+
+@reflectiveTest
+class FeatureComputerTest extends AbstractSingleUnitTest {
+ Future<void> assertContextType(String content, String expectedType) async {
+ var index = content.indexOf('^');
+ if (index < 0) {
+ fail('Missing node offset marker (^) in content');
+ }
+ content = content.substring(0, index) + content.substring(index + 1);
+ await resolveTestUnit(content);
+ var node = NodeLocator(index).searchWithin(testUnit);
+ var computer = FeatureComputer(
+ testAnalysisResult.typeSystem, testAnalysisResult.typeProvider);
+ var type = computer.computeContextType(node);
+
+ if (expectedType == null) {
+ expect(type, null);
+ } else {
+ expect(type?.getDisplayString(), expectedType);
+ }
+ }
+
+ Future<void> test_adjacentString_afterFirst() async {
+ await assertContextType('''
+void f(String s) {}
+void g() {
+ f('a' ^'b');
+}
+''', 'String');
+ }
+
+ Future<void> test_adjacentString_beforeFirst() async {
+ await assertContextType('''
+void f(String s) {}
+void g() {
+ f(^'a' 'b');
+}
+''', 'String');
+ }
+
+ Future<void> test_argumentList() async {
+ await assertContextType('''
+void f(int i) {}
+void g(int j) {
+ f(^j);
+}
+''', 'int');
+ }
+
+ Future<void> test_assertInitializer() async {
+ await assertContextType('''
+class C {
+ C(int i) : assert(^i > 0);
+}
+''', 'bool');
+ }
+
+ Future<void> test_assignmentExpression_withoutType() async {
+ await assertContextType('''
+void g(String s) {
+ var i = ^s.length;
+}
+''', null);
+ }
+
+ Future<void> test_assignmentExpression_withType() async {
+ await assertContextType('''
+void g(String s) {
+ int i = ^s.length;
+}
+''', 'int');
+ }
+
+ Future<void> test_listLiteral_beforeTypeParameter() async {
+ await assertContextType('''
+void f(int e) {
+ var l = ^<int>[e];
+}
+''', null);
+ }
+
+ Future<void> test_listLiteral_element() async {
+ await assertContextType('''
+void f(int e) {
+ var l = <int>[^e];
+}
+''', 'int');
+ }
+
+ Future<void> test_listLiteral_typeParameter() async {
+ await assertContextType('''
+void f(int e) {
+ var l = <^int>[e];
+}
+''', null);
+ }
+
+ Future<void> test_mapLiteralEntry_key() async {
+ await assertContextType('''
+void f(String k, int v) {
+ var m = <String, int>{^k : v};
+}
+''', 'String');
+ }
+
+ Future<void> test_mapLiteralEntry_value() async {
+ await assertContextType('''
+void f(String k, int v) {
+ var m = <String, int>{k : ^v};
+}
+''', 'int');
+ }
+
+ Future<void> test_namedExpression() async {
+ await assertContextType('''
+void f({int i}) {}
+void g(int j) {
+ f(i: ^j);
+}
+''', 'int');
+ }
+
+ Future<void> test_propertyAccess() async {
+ await assertContextType('''
+class C {
+ int f;
+}
+void g(C c) {
+ int i = c.^f;
+}
+''', 'int');
+ }
+
+ Future<void> test_setOrMapLiteral_map_beforeTypeParameter() async {
+ await assertContextType('''
+void f() {
+ var m = ^<int, int>{};
+}
+''', null);
+ }
+
+ Future<void> test_setOrMapLiteral_map_element() async {
+ await assertContextType('''
+void f(bool b, int e) {
+ var m = <int, String>{^if (b) e : ''};
+}
+''', 'int');
+ }
+
+ Future<void> test_setOrMapLiteral_map_typeParameter() async {
+ await assertContextType('''
+void f() {
+ var m = <int, ^int>{};
+}
+''', null);
+ }
+
+ Future<void> test_setOrMapLiteral_set_beforeTypeParameter() async {
+ await assertContextType('''
+void f() {
+ var s = ^<int>{};
+}
+''', null);
+ }
+
+ Future<void> test_setOrMapLiteral_set_element() async {
+ await assertContextType('''
+void f(int e) {
+ var s = <int>{^e};
+}
+''', 'int');
+ }
+
+ Future<void> test_setOrMapLiteral_set_typeParameter() async {
+ await assertContextType('''
+void f() {
+ var s = <^int>{};
+}
+''', null);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/completion/dart/test_all.dart b/pkg/analysis_server/test/src/services/completion/dart/test_all.dart
new file mode 100644
index 0000000..95e24ee
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/completion/dart/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 'feature_computer_test.dart' as feature_computer;
+
+void main() {
+ defineReflectiveSuite(() {
+ feature_computer.main();
+ }, name: 'dart');
+}
diff --git a/pkg/analysis_server/test/src/services/completion/test_all.dart b/pkg/analysis_server/test/src/services/completion/test_all.dart
index 1d82ee2..6055c7b 100644
--- a/pkg/analysis_server/test/src/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/src/services/completion/test_all.dart
@@ -4,10 +4,12 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'dart/test_all.dart' as dart;
import 'filtering/test_all.dart' as filtering;
void main() {
defineReflectiveSuite(() {
+ dart.main();
filtering.main();
}, name: 'completion');
}
diff --git a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
index 367c005..a32b546 100644
--- a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert';
import 'dart:io' as io;
import 'dart:math' as math;
@@ -875,12 +876,12 @@
print('');
print(' Rank: $rank');
print(' Location: ${expected.location}');
- print(' Suggestion: $suggestion');
+ print(' Suggestion: ${suggestion.description}');
print(' Features: $features');
print(' Top $topSuggestionCount suggestions:');
for (var i = 0; i < topSuggestionCount; i++) {
var topSuggestion = topSuggestions[i];
- print(' $i Suggestion: $topSuggestion');
+ print(' $i Suggestion: ${topSuggestion.description}');
if (result.listener != null) {
var feature = result.listener.featureMap[topSuggestion];
if (feature.isEmpty) {
@@ -1050,6 +1051,12 @@
}
}
+extension on protocol.CompletionSuggestion {
+ /// A shorter description of the suggestion than [toString] provides.
+ String get description =>
+ json.encode(toJson()..remove('docSummary')..remove('docComplete'));
+}
+
extension AvailableSuggestionsExtension on protocol.AvailableSuggestion {
// TODO(jwren) I am not sure if we want CompletionSuggestionKind.INVOCATION in
// call cases here, to iterate I need to figure out why this algorithm is
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index ae47f06..6f57735 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1480,7 +1480,7 @@
_fillSalt();
var featureSetProvider = FeatureSetProvider.build(
- resourceProvider: resourceProvider,
+ sourceFactory: sourceFactory,
packages: _packages,
packageDefaultFeatureSet: _analysisOptions.contextFeatures,
nonPackageDefaultFeatureSet: _analysisOptions.nonPackageFeatureSet,
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 b02965c..a46645f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
@@ -2,10 +2,15 @@
// 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/sdk/allowed_experiments.dart';
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/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:meta/meta.dart';
import 'package:pub_semver/pub_semver.dart';
@@ -14,17 +19,17 @@
/// so that the only SDK is the Null Safe SDK.
static const isNullSafetySdk = true;
- final FeatureSet _sdkFeatureSet;
+ final AllowedExperiments _allowedExperiments;
final Packages _packages;
final FeatureSet _packageDefaultFeatureSet;
final FeatureSet _nonPackageDefaultFeatureSet;
FeatureSetProvider._({
- FeatureSet sdkFeatureSet,
- Packages packages,
- FeatureSet packageDefaultFeatureSet,
- FeatureSet nonPackageDefaultFeatureSet,
- }) : _sdkFeatureSet = sdkFeatureSet,
+ @required AllowedExperiments allowedExperiments,
+ @required Packages packages,
+ @required FeatureSet packageDefaultFeatureSet,
+ @required FeatureSet nonPackageDefaultFeatureSet,
+ }) : _allowedExperiments = allowedExperiments,
_packages = packages,
_packageDefaultFeatureSet = packageDefaultFeatureSet,
_nonPackageDefaultFeatureSet = nonPackageDefaultFeatureSet;
@@ -32,7 +37,25 @@
/// Return the [FeatureSet] for the Dart file with the given [uri].
FeatureSet getFeatureSet(String path, Uri uri) {
if (uri.isScheme('dart')) {
- return _sdkFeatureSet;
+ var pathSegments = uri.pathSegments;
+ if (pathSegments.isNotEmpty) {
+ var libraryName = pathSegments.first;
+ var experiments = _allowedExperiments.forSdkLibrary(libraryName);
+ return FeatureSet.fromEnableFlags(experiments);
+ } else {
+ return FeatureSet.fromEnableFlags([]);
+ }
+ }
+
+ if (uri.isScheme('package')) {
+ var pathSegments = uri.pathSegments;
+ if (pathSegments.isNotEmpty) {
+ var packageName = pathSegments.first;
+ var experiments = _allowedExperiments.forPackage(packageName);
+ if (experiments != null) {
+ return FeatureSet.fromEnableFlags(experiments);
+ }
+ }
}
var package = _packages.packageForPath(path);
@@ -59,18 +82,43 @@
}
static FeatureSetProvider build({
- @required ResourceProvider resourceProvider,
+ @required SourceFactory sourceFactory,
@required Packages packages,
@required FeatureSet packageDefaultFeatureSet,
@required FeatureSet nonPackageDefaultFeatureSet,
}) {
- var sdkFeatureSet = FeatureSet.fromEnableFlags(['non-nullable']);
-
+ var allowedExperiments = _experimentsForSdk(sourceFactory.dartSdk);
return FeatureSetProvider._(
- sdkFeatureSet: sdkFeatureSet,
+ allowedExperiments: allowedExperiments,
packages: packages,
packageDefaultFeatureSet: packageDefaultFeatureSet,
nonPackageDefaultFeatureSet: nonPackageDefaultFeatureSet,
);
}
+
+ static AllowedExperiments _experimentsForSdk(DartSdk sdk) {
+ Folder sdkFolder;
+ if (sdk is FolderBasedDartSdk) {
+ sdkFolder = sdk.directory;
+ } else if (sdk is MockSdk) {
+ sdkFolder = sdk.directory;
+ }
+
+ if (sdkFolder != null) {
+ try {
+ var experimentsContent = sdkFolder
+ .getChildAssumingFolder('lib')
+ .getChildAssumingFolder('_internal')
+ .getChildAssumingFile('allowed_experiments.json')
+ .readAsStringSync();
+ return parseAllowedExperiments(experimentsContent);
+ } catch (_) {}
+ }
+
+ return AllowedExperiments(
+ sdkDefaultExperiments: [],
+ sdkLibraryExperiments: {},
+ packageExperiments: {},
+ );
+ }
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 8fd8770..5ef3e94 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -531,7 +531,13 @@
}
@override
- String toString() => path ?? '<unresolved>';
+ String toString() {
+ if (path == null) {
+ return '<unresolved>';
+ } else {
+ return '$uri = $path';
+ }
+ }
CompilationUnit _createEmptyCompilationUnit() {
var token = Token.eof(0);
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 89a1393..037c789 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:meta/meta.dart';
Element declaredParameterElement(
SimpleIdentifier node,
@@ -78,6 +79,49 @@
return _IndexAssembler().assemble(unit);
}
+class ElementNameComponents {
+ final String parameterName;
+ final String classMemberName;
+ final String unitMemberName;
+
+ factory ElementNameComponents(Element element) {
+ String parameterName;
+ if (element is ParameterElement) {
+ parameterName = element.name;
+ element = element.enclosingElement;
+ }
+
+ String classMemberName;
+ if (element.enclosingElement is ClassElement ||
+ element.enclosingElement is ExtensionElement) {
+ classMemberName = element.name;
+ element = element.enclosingElement;
+ }
+
+ String unitMemberName;
+ if (element.enclosingElement is CompilationUnitElement) {
+ unitMemberName = element.name;
+ if (element is ExtensionElement && unitMemberName == null) {
+ var enclosingUnit = element.enclosingElement as CompilationUnitElement;
+ var indexOf = enclosingUnit.extensions.indexOf(element);
+ unitMemberName = 'extension-$indexOf';
+ }
+ }
+
+ return ElementNameComponents._(
+ parameterName: parameterName,
+ classMemberName: classMemberName,
+ unitMemberName: unitMemberName,
+ );
+ }
+
+ ElementNameComponents._({
+ @required this.parameterName,
+ @required this.classMemberName,
+ @required this.unitMemberName,
+ });
+}
+
/**
* Information about an element that is actually put into index for some other
* related element. For example for a synthetic getter this is the corresponding
@@ -395,6 +439,10 @@
* field [_StringInfo.id] is filled by [assemble] during final sorting.
*/
_StringInfo _getStringInfo(String string) {
+ if (string == null) {
+ return nullString;
+ }
+
return stringMap.putIfAbsent(string, () {
return _StringInfo(string);
});
@@ -431,26 +479,15 @@
_ElementInfo _newElementInfo(int unitId, Element element) {
IndexElementInfo info = IndexElementInfo(element);
element = info.element;
- // Prepare name identifiers.
- _StringInfo nameIdParameter = nullString;
- _StringInfo nameIdClassMember = nullString;
- _StringInfo nameIdUnitMember = nullString;
- if (element is ParameterElement) {
- nameIdParameter = _getStringInfo(element.name);
- element = element.enclosingElement;
- }
- if (element?.enclosingElement is ClassElement ||
- element?.enclosingElement is ExtensionElement) {
- nameIdClassMember = _getStringInfo(element.name);
- element = element.enclosingElement;
- }
- if (element?.enclosingElement is CompilationUnitElement) {
- // Unnamed extensions have a null `name`, but _StringInfo instances must
- // have non-null values.
- nameIdUnitMember = _getStringInfo(element.name ?? '');
- }
- return _ElementInfo(unitId, nameIdUnitMember, nameIdClassMember,
- nameIdParameter, info.kind);
+
+ var components = ElementNameComponents(element);
+ return _ElementInfo(
+ unitId,
+ _getStringInfo(components.unitMemberName),
+ _getStringInfo(components.classMemberName),
+ _getStringInfo(components.parameterName),
+ info.kind,
+ );
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 0ad4a80..798129c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -5,7 +5,6 @@
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/element/element.dart'
show CompilationUnitElement, LibraryElement;
-import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -13,6 +12,7 @@
import 'package:analyzer/src/dart/analysis/library_graph.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
+import 'package:analyzer/src/exception/exception.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisContext, AnalysisOptions;
import 'package:analyzer/src/generated/source.dart';
@@ -54,7 +54,7 @@
AnalysisContextImpl analysisContext;
LinkedElementFactory elementFactory;
- var loadedBundles = Set<LibraryCycle>.identity();
+ Set<LibraryCycle> loadedBundles = Set<LibraryCycle>.identity();
LibraryContext({
@required AnalysisSessionImpl session,
@@ -164,13 +164,17 @@
var existingElement = existingLibraryReference.element;
if (existingElement != null) {
var existingSource = existingElement?.source;
+ var libraryRefs = elementFactory.rootReference.children;
+ var libraryUriList = libraryRefs.map((e) => e.name).toList();
throw StateError(
'[The library is already loaded]'
'[oldUri: ${existingSource.uri}]'
'[oldPath: ${existingSource.fullName}]'
'[newUri: ${libraryFile.uriStr}]'
'[newPath: ${libraryFile.path}]'
- '[cycle: $cycle]',
+ '[cycle: $cycle]'
+ '[loadedBundles: ${loadedBundles.toList()}]'
+ '[elementFactory.libraries: $libraryUriList]',
);
}
}
@@ -313,14 +317,11 @@
}
}
-/// Exception that wraps another exception that happened during linking, and
-/// includes the content of all files of the library cycle.
-class LibraryCycleLinkException extends CaughtException {
- final Map<String, String> fileContentMap;
-
+/// TODO(scheglov) replace in the internal patch
+class LibraryCycleLinkException extends CaughtExceptionWithFiles {
LibraryCycleLinkException(
Object exception,
StackTrace stackTrace,
- this.fileContentMap,
- ) : super(exception, stackTrace);
+ Map<String, String> fileContentMap,
+ ) : super(exception, stackTrace, fileContentMap);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index c2f4f13..2f263d9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -747,18 +747,20 @@
return -1;
}
// Prepare information about the element.
- int unitMemberId = getElementUnitMemberId(element);
+ var components = ElementNameComponents(element);
+ int unitMemberId = getStringId(components.unitMemberName);
if (unitMemberId == -1) {
return -1;
}
- int classMemberId = getElementClassMemberId(element);
+ int classMemberId = getStringId(components.classMemberName);
if (classMemberId == -1) {
return -1;
}
- int parameterId = getElementParameterId(element);
+ int parameterId = getStringId(components.parameterName);
if (parameterId == -1) {
return -1;
}
+
// Try to find the element id using classMemberId, parameterId, and kind.
int elementId =
_findFirstOccurrence(index.elementNameUnitMemberIds, unitMemberId);
@@ -780,46 +782,6 @@
}
/**
- * Return the [element]'s class member name identifier, `null` is not a class
- * member, or `-1` if the [element] is not referenced in the [index].
- */
- int getElementClassMemberId(Element element) {
- for (; element != null; element = element.enclosingElement) {
- if (element.enclosingElement is ClassElement ||
- element.enclosingElement is ExtensionElement) {
- return getStringId(element.name);
- }
- }
- return index.nullStringId;
- }
-
- /**
- * Return the [element]'s class member name identifier, `null` is not a class
- * member, or `-1` if the [element] is not referenced in the [index].
- */
- int getElementParameterId(Element element) {
- for (; element != null; element = element.enclosingElement) {
- if (element is ParameterElement) {
- return getStringId(element.name);
- }
- }
- return index.nullStringId;
- }
-
- /**
- * Return the [element]'s top-level name identifier, `0` is the unit, or
- * `-1` if the [element] is not referenced in the [index].
- */
- int getElementUnitMemberId(Element element) {
- for (; element != null; element = element.enclosingElement) {
- if (element.enclosingElement is CompilationUnitElement) {
- return getStringId(element.name);
- }
- }
- return index.nullStringId;
- }
-
- /**
* Return a list of results where an element with the given [elementId] has
* a relation with the kind from [relationToResultKind].
*
@@ -868,6 +830,10 @@
* used in the [index].
*/
int getStringId(String str) {
+ if (str == null) {
+ return index.nullStringId;
+ }
+
return binarySearch(index.strings, str);
}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 834bb39..aba8c07 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -758,6 +758,11 @@
return hasModifier(Modifier.MIXIN_APPLICATION);
}
+ /// Set whether this class is a mixin application.
+ set isMixinApplication(bool isMixinApplication) {
+ setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
+ }
+
@override
bool get isOrInheritsProxy => false;
@@ -821,11 +826,6 @@
_methods = methods;
}
- /// Set whether this class is a mixin application.
- set mixinApplication(bool isMixinApplication) {
- setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
- }
-
@override
List<InterfaceType> get mixins {
if (linkedMixinInferenceCallback != null) {
@@ -2004,11 +2004,6 @@
ClassElementImpl get enclosingElement =>
super.enclosingElement as ClassElementImpl;
- /// Set whether this constructor represents a factory method.
- set factory(bool isFactory) {
- setModifier(Modifier.FACTORY, isFactory);
- }
-
@override
bool get isConst {
if (linkedNode != null) {
@@ -2059,6 +2054,11 @@
return hasModifier(Modifier.FACTORY);
}
+ /// Set whether this constructor represents a factory method.
+ set isFactory(bool isFactory) {
+ setModifier(Modifier.FACTORY, isFactory);
+ }
+
@override
bool get isStatic => false;
@@ -3567,11 +3567,6 @@
ElementImpl enclosing, Reference reference, AstNode linkedNode)
: super.forLinkedNode(enclosing, reference, linkedNode);
- /// Set whether this executable element's body is asynchronous.
- set asynchronous(bool isAsynchronous) {
- setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
- }
-
@override
int get codeLength {
if (linkedNode != null) {
@@ -3606,16 +3601,6 @@
return super.documentationComment;
}
- /// Set whether this executable element is external.
- set external(bool isExternal) {
- setModifier(Modifier.EXTERNAL, isExternal);
- }
-
- /// Set whether this method's body is a generator.
- set generator(bool isGenerator) {
- setModifier(Modifier.GENERATOR, isGenerator);
- }
-
@override
bool get hasImplicitReturnType {
if (linkedNode != null) {
@@ -3645,6 +3630,11 @@
return hasModifier(Modifier.ASYNCHRONOUS);
}
+ /// Set whether this executable element's body is asynchronous.
+ set isAsynchronous(bool isAsynchronous) {
+ setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
+ }
+
@override
bool get isExternal {
if (linkedNode != null) {
@@ -3653,6 +3643,11 @@
return hasModifier(Modifier.EXTERNAL);
}
+ /// Set whether this executable element is external.
+ set isExternal(bool isExternal) {
+ setModifier(Modifier.EXTERNAL, isExternal);
+ }
+
@override
bool get isGenerator {
if (linkedNode != null) {
@@ -3661,6 +3656,11 @@
return hasModifier(Modifier.GENERATOR);
}
+ /// Set whether this method's body is a generator.
+ set isGenerator(bool isGenerator) {
+ setModifier(Modifier.GENERATOR, isGenerator);
+ }
+
@override
bool get isOperator => false;
@@ -4958,11 +4958,6 @@
_combinators = combinators;
}
- /// Set whether this import is for a deferred library.
- set deferred(bool isDeferred) {
- setModifier(Modifier.DEFERRED, isDeferred);
- }
-
@override
CompilationUnitElementImpl get enclosingUnit {
LibraryElementImpl enclosingLibrary = enclosingElement;
@@ -4996,6 +4991,11 @@
return hasModifier(Modifier.DEFERRED);
}
+ /// Set whether this import is for a deferred library.
+ set isDeferred(bool isDeferred) {
+ setModifier(Modifier.DEFERRED, isDeferred);
+ }
+
@override
ElementKind get kind => ElementKind.IMPORT;
@@ -7022,11 +7022,6 @@
@override
PropertyAccessorElement get declaration => this;
- /// Set whether this accessor is a getter.
- set getter(bool isGetter) {
- setModifier(Modifier.GETTER, isGetter);
- }
-
@override
String get identifier {
String name = displayName;
@@ -7047,6 +7042,11 @@
return hasModifier(Modifier.GETTER);
}
+ /// Set whether this accessor is a getter.
+ set isGetter(bool isGetter) {
+ setModifier(Modifier.GETTER, isGetter);
+ }
+
@override
bool get isSetter {
if (linkedNode != null) {
@@ -7055,6 +7055,11 @@
return hasModifier(Modifier.SETTER);
}
+ /// Set whether this accessor is a setter.
+ set isSetter(bool isSetter) {
+ setModifier(Modifier.SETTER, isSetter);
+ }
+
@override
bool get isStatic {
if (linkedNode != null) {
@@ -7091,11 +7096,6 @@
return super.name;
}
- /// Set whether this accessor is a setter.
- set setter(bool isSetter) {
- setModifier(Modifier.SETTER, isSetter);
- }
-
@override
T accept<T>(ElementVisitor<T> visitor) =>
visitor.visitPropertyAccessorElement(this);
diff --git a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
index a74cca0..4834c4a 100644
--- a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
@@ -576,7 +576,9 @@
var constraints = this.constraints[t1.element];
if (constraints != null) {
if (!identical(t2, UnknownInferredType.instance)) {
- if (t1.nullabilitySuffix == NullabilitySuffix.question) {
+ if (t1.nullabilitySuffix == NullabilitySuffix.question &&
+ t2.nullabilitySuffix == NullabilitySuffix.question) {
+ t1 = _typeSystem.promoteToNonNull(t1);
t2 = _typeSystem.promoteToNonNull(t2);
}
var constraint = _TypeConstraint(origin, t1.element, upper: t2);
@@ -590,8 +592,10 @@
var constraints = this.constraints[t2.element];
if (constraints != null) {
if (!identical(t1, UnknownInferredType.instance)) {
- if (t2.nullabilitySuffix == NullabilitySuffix.question) {
+ if (t1.nullabilitySuffix == NullabilitySuffix.question &&
+ t2.nullabilitySuffix == NullabilitySuffix.question) {
t1 = _typeSystem.promoteToNonNull(t1);
+ t2 = _typeSystem.promoteToNonNull(t2);
}
var constraint = _TypeConstraint(origin, t2.element, lower: t1);
constraints.add(constraint);
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index 5ffaddc..825a272 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -739,7 +739,7 @@
var firstAccessor = first as PropertyAccessorElement;
var result = PropertyAccessorElementImpl(firstAccessor.name, -1);
result.enclosingElement = targetClass;
- result.getter = firstAccessor.isGetter;
+ result.isGetter = firstAccessor.isGetter;
result.returnType = resultType.returnType;
result.parameters = resultType.parameters;
return result;
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index ce6ced7..c4ceea2 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -897,20 +897,20 @@
@override
PropertyAccessorElement get correspondingGetter {
- return PropertyAccessorMember(
- declaration.correspondingGetter,
- _substitution,
- isLegacy,
- );
+ var baseGetter = declaration.correspondingGetter;
+ if (baseGetter == null) {
+ return null;
+ }
+ return PropertyAccessorMember(baseGetter, _substitution, isLegacy);
}
@override
PropertyAccessorElement get correspondingSetter {
- return PropertyAccessorMember(
- declaration.correspondingSetter,
- _substitution,
- isLegacy,
- );
+ var baseSetter = declaration.correspondingSetter;
+ if (baseSetter == null) {
+ return null;
+ }
+ return PropertyAccessorMember(baseSetter, _substitution, isLegacy);
}
@override
diff --git a/pkg/analyzer/lib/src/dart/element/subtype.dart b/pkg/analyzer/lib/src/dart/element/subtype.dart
index f38f1cd..7663496 100644
--- a/pkg/analyzer/lib/src/dart/element/subtype.dart
+++ b/pkg/analyzer/lib/src/dart/element/subtype.dart
@@ -81,11 +81,10 @@
if (T0_nullability == NullabilitySuffix.none &&
T0 is TypeParameterTypeImpl) {
var S = T0.promotedBound;
- var B = T0.element.bound;
- if (S == null && B != null) {
+ if (S == null) {
+ var B = T0.element.bound ?? _objectQuestion;
return isSubtypeOf(B, _objectNone);
- }
- if (S != null) {
+ } else {
return isSubtypeOf(S, _objectNone);
}
}
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 4d47e4d..3e80669 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -206,21 +206,29 @@
// Build the graph.
for (var directive in unlinked2.imports) {
var file = _fileForRelativeUri(directive.uri);
- importedFiles.add(file);
+ if (file != null) {
+ importedFiles.add(file);
+ }
}
for (var directive in unlinked2.exports) {
var file = _fileForRelativeUri(directive.uri);
- exportedFiles.add(file);
+ if (file != null) {
+ exportedFiles.add(file);
+ }
}
for (var uri in unlinked2.parts) {
var file = _fileForRelativeUri(uri);
- partedFiles.add(file);
+ if (file != null) {
+ partedFiles.add(file);
+ }
}
if (unlinked2.hasPartOfDirective) {
var uri = unlinked2.partOfUri;
if (uri.isNotEmpty) {
partOfLibrary = _fileForRelativeUri(uri);
- directReferencedFiles.add(partOfLibrary);
+ if (partOfLibrary != null) {
+ directReferencedFiles.add(partOfLibrary);
+ }
}
}
libraryFiles.add(this);
@@ -241,19 +249,22 @@
FileState _fileForRelativeUri(String relativeUri) {
if (relativeUri.isEmpty) {
- return _fsState.unresolvedFile;
+ return null;
}
Uri absoluteUri;
try {
absoluteUri = resolveRelativeUri(uri, Uri.parse(relativeUri));
} on FormatException {
- return _fsState.unresolvedFile;
+ return null;
}
var file = _fsState.getFileForUri(absoluteUri);
- file.referencingFiles.add(this);
+ if (file == null) {
+ return null;
+ }
+ file.referencingFiles.add(this);
return file;
}
@@ -389,11 +400,6 @@
*/
final void Function(List<String> paths) prefetchFiles;
- /**
- * The [FileState] instance that correspond to an unresolved URI.
- */
- FileState _unresolvedFile;
-
final FileSystemStateTimers timers = FileSystemStateTimers();
final FileSystemStateTestView testView = FileSystemStateTestView();
@@ -410,17 +416,6 @@
this.prefetchFiles,
);
- /**
- * Return the [FileState] instance that correspond to an unresolved URI.
- */
- FileState get unresolvedFile {
- if (_unresolvedFile == null) {
- _unresolvedFile = FileState._(this, null, null, null);
- _unresolvedFile.refresh();
- }
- return _unresolvedFile;
- }
-
/// Update the state to reflect the fact that the file with the given [path]
/// was changed. Specifically this means that we evict this file and every
/// file that referenced it.
@@ -468,7 +463,7 @@
if (file == null) {
var source = _sourceFactory.forUri2(uri);
if (source == null) {
- print('[library_graph] could not create source for $uri');
+ return null;
}
var path = source.fullName;
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 2c10232..c835175 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -260,7 +260,7 @@
if (fsState == null) {
var featureSetProvider = FeatureSetProvider.build(
- resourceProvider: resourceProvider,
+ sourceFactory: sourceFactory,
packages: Packages.empty,
packageDefaultFeatureSet: analysisOptions.contextFeatures,
nonPackageDefaultFeatureSet: analysisOptions.nonPackageFeatureSet,
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 4340e9d..1ce46ce 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -525,11 +525,11 @@
FunctionBody body = node.functionExpression.body;
if (node.externalKeyword != null || body is NativeFunctionBody) {
- element.external = true;
+ element.isExternal = true;
}
- element.asynchronous = body.isAsynchronous;
- element.generator = body.isGenerator;
+ element.isAsynchronous = body.isAsynchronous;
+ element.isGenerator = body.isGenerator;
if (node.returnType == null) {
element.hasImplicitReturnType = true;
}
@@ -591,8 +591,8 @@
element.hasImplicitReturnType = true;
FunctionBody body = node.body;
- element.asynchronous = body.isAsynchronous;
- element.generator = body.isGenerator;
+ element.isAsynchronous = body.isAsynchronous;
+ element.isGenerator = body.isGenerator;
var holder = ElementHolder(element);
_withElementHolder(holder, () {
diff --git a/pkg/analyzer/lib/src/error/return_type_verifier.dart b/pkg/analyzer/lib/src/error/return_type_verifier.dart
index 2f928d0..990b72e 100644
--- a/pkg/analyzer/lib/src/error/return_type_verifier.dart
+++ b/pkg/analyzer/lib/src/error/return_type_verifier.dart
@@ -90,6 +90,7 @@
StaticTypeWarningCode errorCode,
) {
if (!_isLegalReturnType(expectedElement)) {
+ enclosingExecutable.hasLegalReturnType = false;
_errorReporter.reportErrorForNode(errorCode, returnType);
}
}
@@ -117,14 +118,12 @@
/// Check that a type mismatch between the type of the [expression] and
/// the expected return type of the enclosing executable.
void _checkReturnExpression(Expression expression) {
- if (enclosingExecutable.isAsynchronous) {
- if (!_isLegalReturnType(_typeProvider.futureElement)) {
- // ILLEGAL_ASYNC_RETURN_TYPE has already been reported, meaning the
- // _declared_ return type is illegal; don't confuse by also reporting
- // that the type being returned here does not match that illegal return
- // type.
- return;
- }
+ if (!enclosingExecutable.hasLegalReturnType) {
+ // ILLEGAL_ASYNC_RETURN_TYPE has already been reported, meaning the
+ // _declared_ return type is illegal; don't confuse by also reporting
+ // that the type being returned here does not match that illegal return
+ // type.
+ return;
}
// `T` is the declared return type.
diff --git a/pkg/analyzer/lib/src/exception/exception.dart b/pkg/analyzer/lib/src/exception/exception.dart
new file mode 100644
index 0000000..3033672
--- /dev/null
+++ b/pkg/analyzer/lib/src/exception/exception.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.
+
+import 'package:analyzer/exception/exception.dart';
+
+/// Exception that wraps another exception, and includes the content of
+/// files that might be related to the exception, and help to identify the
+/// issue and fix it.
+class CaughtExceptionWithFiles extends CaughtException {
+ final Map<String, String> fileContentMap;
+
+ CaughtExceptionWithFiles(
+ Object exception,
+ StackTrace stackTrace,
+ this.fileContentMap,
+ ) : super(exception, stackTrace);
+}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 9a3104f..bd06d29 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -55,6 +55,10 @@
/// The return statements that do not have a value.
final List<ReturnStatement> _returnsWithout = [];
+ /// This flag is set to `false` when the declared return type is not legal
+ /// for the kind of the function body, e.g. not `Future` for `async`.
+ bool hasLegalReturnType = true;
+
EnclosingExecutableContext(this.element)
: isAsynchronous = element != null && element.isAsynchronous,
isConstConstructor = element is ConstructorElement && element.isConst,
@@ -75,7 +79,7 @@
static bool _isStaticMethod(ExecutableElement element) {
var enclosing = element?.enclosingElement;
- if (enclosing is ClassElement) {
+ if (enclosing is ClassElement || enclosing is ExtensionElement) {
return element.isStatic;
}
return false;
@@ -1012,7 +1016,12 @@
_checkForStaticAccessToInstanceMember(typeReference, propertyName);
_checkForInstanceAccessToStaticMember(
typeReference, node.target, propertyName);
- _checkForUnnecessaryNullAware(target, node.operator);
+
+ // For `C?.x` the type of `C` is not set, because it is not an expression.
+ if (target.staticType != null) {
+ _checkForUnnecessaryNullAware(target, node.operator);
+ }
+
super.visitPropertyAccess(node);
}
@@ -2764,7 +2773,8 @@
}
// not a class member
Element enclosingElement = element.enclosingElement;
- if (enclosingElement is! ClassElement) {
+ if (enclosingElement is! ClassElement &&
+ enclosingElement is! ExtensionElement) {
return;
}
// qualified method invocation
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 2fe0eb0..1833961 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -89,7 +89,7 @@
[List<String> parameterNames]) {
ClassElementImpl element =
classElement(typeName, superclassType, parameterNames);
- element.mixinApplication = true;
+ element.isMixinApplication = true;
return element;
}
@@ -426,7 +426,7 @@
field.isFinal = true;
PropertyAccessorElementImpl getter = PropertyAccessorElementImpl(name, 0);
getter.isSynthetic = false;
- getter.getter = true;
+ getter.isGetter = true;
getter.variable = field;
getter.returnType = type;
getter.isStatic = isStatic;
@@ -577,13 +577,13 @@
field.isSynthetic = true;
field.type = type;
PropertyAccessorElementImpl getter = PropertyAccessorElementImpl(name, -1);
- getter.getter = true;
+ getter.isGetter = true;
getter.variable = field;
getter.returnType = type;
field.getter = getter;
ParameterElementImpl parameter = requiredParameter2("a", type);
PropertyAccessorElementImpl setter = PropertyAccessorElementImpl(name, -1);
- setter.setter = true;
+ setter.isSetter = true;
setter.isSynthetic = true;
setter.variable = field;
setter.parameters = <ParameterElement>[parameter];
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 126e28a..3459910 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -1139,6 +1139,25 @@
);
}
+ resourceProvider.newFile(
+ resourceProvider.convertPath(
+ '$sdkRoot/lib/_internal/allowed_experiments.json',
+ ),
+ r'''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "nullSafety"
+ }
+ }
+}
+''',
+ );
+
if (generateSummaryFiles) {
List<int> bytes = _computeLinkedBundleBytes();
resourceProvider.newFileWithBytes(
@@ -1155,6 +1174,11 @@
return _analysisContext;
}
+ Folder get directory {
+ var convertedRoot = resourceProvider.convertPath(sdkRoot);
+ return resourceProvider.getFolder(convertedRoot);
+ }
+
@override
String get sdkVersion => throw UnimplementedError();
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
index 894e924..400a4bb 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
@@ -943,7 +943,7 @@
List<ParameterElement> parameters = const [],
}) {
var element = ConstructorElementImpl(name, 0);
- element.factory = isFactory;
+ element.isFactory = isFactory;
element.isConst = isConst;
element.parameters = parameters;
return element;
@@ -996,7 +996,7 @@
field.type = type;
var getter = PropertyAccessorElementImpl(name, 0);
- getter.getter = true;
+ getter.isGetter = true;
getter.isStatic = isStatic;
getter.isSynthetic = false;
getter.returnType = type;
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 558b322..15aac0f 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -1312,45 +1312,6 @@
]);
}
- test_instanceMemberAccessFromStatic_field() async {
- await assertErrorsInCode(r'''
-class A {
- int f;
- static foo() {
- f;
- }
-}
-''', [
- error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 40, 1),
- ]);
- }
-
- test_instanceMemberAccessFromStatic_getter() async {
- await assertErrorsInCode(r'''
-class A {
- get g => null;
- static foo() {
- g;
- }
-}
-''', [
- error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 48, 1),
- ]);
- }
-
- test_instanceMemberAccessFromStatic_method() async {
- await assertErrorsInCode(r'''
-class A {
- m() {}
- static foo() {
- m();
- }
-}
-''', [
- error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 40, 1),
- ]);
- }
-
test_instantiateEnum_const() async {
await assertErrorsInCode(r'''
enum E { ONE }
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 9de6844..d24901e 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
@@ -36,53 +36,62 @@
_createSourceFactory();
}
- test_nested() {
+ test_packages_allowedExperiments() {
var packages = Packages(
{
'aaa': Package(
name: 'aaa',
- rootFolder: getFolder('/packages/aaa'),
- libFolder: getFolder('/packages/aaa/lib'),
- languageVersion: Version.parse('2.5.0'),
+ rootFolder: newFolder('/packages/aaa'),
+ libFolder: newFolder('/packages/aaa/lib'),
+ languageVersion: Version(2, 7, 0),
),
'bbb': Package(
name: 'bbb',
- rootFolder: getFolder('/packages/aaa/bbb'),
- libFolder: getFolder('/packages/aaa/bbb/lib'),
- languageVersion: Version.parse('2.6.0'),
- ),
- 'ccc': Package(
- name: 'ccc',
- rootFolder: getFolder('/packages/ccc'),
- libFolder: getFolder('/packages/ccc/lib'),
- languageVersion: Version.parse('2.7.0'),
+ rootFolder: newFolder('/packages/bbb'),
+ libFolder: newFolder('/packages/bbb/lib'),
+ languageVersion: Version(2, 7, 0),
),
},
);
+ _createSourceFactory(
+ packageUriResolver: _createPackageMapUriResolver(packages),
+ );
+
+ _newSdkExperimentsFile(r'''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "nullSafety"
+ }
+ },
+ "packages": {
+ "aaa": {
+ "experimentSet": "nullSafety"
+ }
+ }
+}
+''');
+
provider = FeatureSetProvider.build(
- resourceProvider: resourceProvider,
+ sourceFactory: sourceFactory,
packages: packages,
packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
);
- void check(String posixPath, Version expected) {
- var path = convertPath(posixPath);
- var uri = Uri.parse('package:aaa/a.dart');
- expect(
- provider.getLanguageVersion(path, uri),
- expected,
- );
- }
+ _assertNonNullableForPath('/packages/aaa/lib/a.dart', true);
- check('/packages/aaa/a.dart', Version.parse('2.5.0'));
- check('/packages/aaa/bbb/b.dart', Version.parse('2.6.0'));
- check('/packages/ccc/c.dart', Version.parse('2.7.0'));
- check('/packages/ddd/d.dart', ExperimentStatus.currentVersion);
+ _assertNonNullableForPath('/packages/bbb/lib/b.dart', false);
+
+ _assertNonNullableForPath('/other/file.dart', false);
}
- test_packages() {
+ test_packages_contextExperiments_empty() {
var packages = Packages(
{
'aaa': Package(
@@ -111,7 +120,7 @@
);
provider = FeatureSetProvider.build(
- resourceProvider: resourceProvider,
+ sourceFactory: sourceFactory,
packages: packages,
packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
@@ -132,7 +141,53 @@
_assertNonNullableForPath('/other/file.dart', false);
}
- test_packages_enabledExperiment_nonNullable() {
+ test_packages_contextExperiments_nested() {
+ var packages = Packages(
+ {
+ 'aaa': Package(
+ name: 'aaa',
+ rootFolder: getFolder('/packages/aaa'),
+ libFolder: getFolder('/packages/aaa/lib'),
+ languageVersion: Version.parse('2.5.0'),
+ ),
+ 'bbb': Package(
+ name: 'bbb',
+ rootFolder: getFolder('/packages/aaa/bbb'),
+ libFolder: getFolder('/packages/aaa/bbb/lib'),
+ languageVersion: Version.parse('2.6.0'),
+ ),
+ 'ccc': Package(
+ name: 'ccc',
+ rootFolder: getFolder('/packages/ccc'),
+ libFolder: getFolder('/packages/ccc/lib'),
+ languageVersion: Version.parse('2.7.0'),
+ ),
+ },
+ );
+
+ provider = FeatureSetProvider.build(
+ sourceFactory: sourceFactory,
+ packages: packages,
+ packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ );
+
+ void check(String posixPath, Version expected) {
+ var path = convertPath(posixPath);
+ var uri = Uri.parse('package:aaa/a.dart');
+ expect(
+ provider.getLanguageVersion(path, uri),
+ expected,
+ );
+ }
+
+ check('/packages/aaa/a.dart', Version.parse('2.5.0'));
+ check('/packages/aaa/bbb/b.dart', Version.parse('2.6.0'));
+ check('/packages/ccc/c.dart', Version.parse('2.7.0'));
+ check('/packages/ddd/d.dart', ExperimentStatus.currentVersion);
+ }
+
+ test_packages_contextExperiments_nonNullable() {
var packages = Packages(
{
'aaa': Package(
@@ -161,7 +216,7 @@
);
provider = FeatureSetProvider.build(
- resourceProvider: resourceProvider,
+ sourceFactory: sourceFactory,
packages: packages,
packageDefaultFeatureSet: FeatureSet.fromEnableFlags(['non-nullable']),
nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
@@ -182,17 +237,75 @@
_assertNonNullableForPath('/other/file.dart', false);
}
- test_sdk() {
- _buildProvider([]);
+ test_sdk_allowedExperiments_default() {
+ _newSdkExperimentsFile(r'''
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "nullSafety"
+ }
+ }
+}
+''');
- var featureSet = _getSdkFeatureSet();
+ provider = FeatureSetProvider.build(
+ sourceFactory: sourceFactory,
+ packages: findPackagesFrom(resourceProvider, getFolder('/test')),
+ packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ );
+
+ var featureSet = _getSdkFeatureSet('dart:math');
expect(featureSet.isEnabled(Feature.non_nullable), isTrue);
}
- test_sdk_enabledExperiment_nonNullable() {
- _buildProvider(['non-nullable']);
+ test_sdk_allowedExperiments_library() {
+ _newSdkExperimentsFile(r'''
+{
+ "version": 1,
+ "experimentSets": {
+ "none": [],
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "none"
+ },
+ "libraries": {
+ "math": {
+ "experimentSet": "nullSafety"
+ }
+ }
+ }
+}
+''');
+ provider = FeatureSetProvider.build(
+ sourceFactory: sourceFactory,
+ packages: findPackagesFrom(resourceProvider, getFolder('/test')),
+ packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ );
- var featureSet = _getSdkFeatureSet();
+ var core_featureSet = _getSdkFeatureSet('dart:core');
+ expect(core_featureSet.isEnabled(Feature.non_nullable), isFalse);
+
+ var math_featureSet = _getSdkFeatureSet('dart:math');
+ expect(math_featureSet.isEnabled(Feature.non_nullable), isTrue);
+ }
+
+ test_sdk_allowedExperiments_mockDefault() {
+ provider = FeatureSetProvider.build(
+ sourceFactory: sourceFactory,
+ packages: findPackagesFrom(resourceProvider, getFolder('/test')),
+ packageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ nonPackageDefaultFeatureSet: FeatureSet.fromEnableFlags([]),
+ );
+
+ var featureSet = _getSdkFeatureSet('dart:math');
expect(featureSet.isEnabled(Feature.non_nullable), isTrue);
}
@@ -201,16 +314,6 @@
expect(featureSet.isEnabled(Feature.non_nullable), expected);
}
- void _buildProvider(List<String> enabledExperiments) {
- var featureSet = FeatureSet.fromEnableFlags(enabledExperiments);
- provider = FeatureSetProvider.build(
- resourceProvider: resourceProvider,
- packages: findPackagesFrom(resourceProvider, getFolder('/test')),
- packageDefaultFeatureSet: featureSet,
- nonPackageDefaultFeatureSet: featureSet,
- );
- }
-
PackageMapUriResolver _createPackageMapUriResolver(Packages packages) {
var map = <String, List<Folder>>{};
for (var package in packages.packages) {
@@ -239,9 +342,14 @@
return provider.getFeatureSet(path, uri);
}
- FeatureSet _getSdkFeatureSet() {
- var mathUri = Uri.parse('dart:math');
- var mathPath = sourceFactory.forUri2(mathUri).fullName;
- return provider.getFeatureSet(mathPath, mathUri);
+ FeatureSet _getSdkFeatureSet(String uriStr) {
+ var uri = Uri.parse(uriStr);
+ var path = sourceFactory.forUri2(uri).fullName;
+ return provider.getFeatureSet(path, uri);
+ }
+
+ void _newSdkExperimentsFile(String content) {
+ newFile('$sdkRoot/lib/_internal/allowed_experiments.json',
+ content: content);
}
}
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 07a09ca..5ec7d05 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -61,7 +61,7 @@
]);
AnalysisOptions analysisOptions = AnalysisOptionsImpl();
var featureSetProvider = FeatureSetProvider.build(
- resourceProvider: resourceProvider,
+ sourceFactory: sourceFactory,
packages: Packages.empty,
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 07c19df..0333e83 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -13,6 +13,7 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -1332,30 +1333,18 @@
* Return the [element] identifier in [index] or fail.
*/
int _findElementId(Element element) {
- int unitId = _getUnitId(element);
+ var unitId = _getUnitId(element);
+
// Prepare the element that was put into the index.
IndexElementInfo info = IndexElementInfo(element);
element = info.element;
+
// Prepare element's name components.
- int unitMemberId = index.nullStringId;
- int classMemberId = index.nullStringId;
- int parameterId = index.nullStringId;
- for (Element e = element; e != null; e = e.enclosingElement) {
- if (e.enclosingElement is CompilationUnitElement) {
- unitMemberId = _getStringId(e.name);
- break;
- }
- }
- for (Element e = element; e != null; e = e.enclosingElement) {
- if (e.enclosingElement is ClassElement ||
- e.enclosingElement is ExtensionElement) {
- classMemberId = _getStringId(e.name);
- break;
- }
- }
- if (element is ParameterElement) {
- parameterId = _getStringId(element.name);
- }
+ var components = ElementNameComponents(element);
+ var unitMemberId = _getStringId(components.unitMemberName);
+ var classMemberId = _getStringId(components.classMemberName);
+ var parameterId = _getStringId(components.parameterName);
+
// Find the element's id.
for (int elementId = 0;
elementId < index.elementUnits.length;
@@ -1391,6 +1380,10 @@
}
int _getStringId(String str) {
+ if (str == null) {
+ return index.nullStringId;
+ }
+
int id = index.strings.indexOf(str);
if (id < 0) {
_failWithIndexDump('String "$str" is not referenced');
@@ -1439,31 +1432,27 @@
..contextFeatures = FeatureSet.forTesting(
sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
- test_isInvokedBy_MethodElement_ofExtension_instance() async {
+ test_isInvokedBy_MethodElement_ofNamedExtension_instance() async {
await _indexTestUnit('''
-class A {}
-
-extension E on A {
+extension E on int {
void foo() {}
}
-main(A a) {
- a.foo();
+main() {
+ 0.foo();
}
''');
MethodElement element = findElement('foo');
assertThat(element)..isInvokedAt('foo();', true);
}
- test_isInvokedBy_MethodElement_ofExtension_static() async {
+ test_isInvokedBy_MethodElement_ofNamedExtension_static() async {
await _indexTestUnit('''
-class A {}
-
-extension E on A {
+extension E on int {
static void foo() {}
}
-main(A a) {
+main() {
E.foo();
}
''');
@@ -1471,6 +1460,32 @@
assertThat(element)..isInvokedAt('foo();', true);
}
+ test_isInvokedBy_MethodElement_ofUnnamedExtension_instance() async {
+ await _indexTestUnit('''
+extension on int {
+ void foo() {} // int
+}
+
+extension on double {
+ void foo() {} // double
+}
+
+main() {
+ 0.foo(); // int ref
+ (1.2).foo(); // double ref
+}
+''');
+ var findNode = FindNode(testCode, testUnit);
+
+ var intMethod = findNode.methodDeclaration('foo() {} // int');
+ assertThat(intMethod.declaredElement)
+ ..isInvokedAt('foo(); // int ref', true);
+
+ var doubleMethod = findNode.methodDeclaration('foo() {} // double');
+ assertThat(doubleMethod.declaredElement)
+ ..isInvokedAt('foo(); // double ref', true);
+ }
+
test_isReferencedBy_ClassElement_fromExtension() async {
await _indexTestUnit('''
class A<T> {}
@@ -1483,32 +1498,28 @@
test_isReferencedBy_ExtensionElement() async {
await _indexTestUnit('''
-class A {}
-
-extension E on A {
+extension E on int {
void foo() {}
}
-main(A a) {
- E(a).foo();
+main() {
+ E(0).foo();
}
''');
ExtensionElement element = findElement('E');
- assertThat(element)..isReferencedAt('E(a).foo()', false);
+ assertThat(element)..isReferencedAt('E(0).foo()', false);
}
- test_isReferencedBy_PropertyAccessor_ofExtension_instance() async {
+ test_isReferencedBy_PropertyAccessor_ofNamedExtension_instance() async {
await _indexTestUnit('''
-class A {}
-
-extension E on A {
+extension E on int {
int get foo => 0;
void set foo(int _) {}
}
-main(A a) {
- a.foo;
- a.foo = 0;
+main() {
+ 0.foo;
+ 0.foo = 0;
}
''');
PropertyAccessorElement getter = findElement('foo', ElementKind.GETTER);
@@ -1517,18 +1528,16 @@
assertThat(setter)..isReferencedAt('foo = 0;', true);
}
- test_isReferencedBy_PropertyAccessor_ofExtension_static() async {
+ test_isReferencedBy_PropertyAccessor_ofNamedExtension_static() async {
await _indexTestUnit('''
-class A {}
-
-extension E on A {
+extension E on int {
static int get foo => 0;
static void set foo(int _) {}
}
-main(A a) {
- a.foo;
- a.foo = 0;
+main() {
+ 0.foo;
+ 0.foo = 0;
}
''');
PropertyAccessorElement getter = findElement('foo', ElementKind.GETTER);
@@ -1536,6 +1545,42 @@
assertThat(getter)..isReferencedAt('foo;', true);
assertThat(setter)..isReferencedAt('foo = 0;', true);
}
+
+ test_isReferencedBy_PropertyAccessor_ofUnnamedExtension_instance() async {
+ await _indexTestUnit('''
+extension on int {
+ int get foo => 0; // int getter
+ void set foo(int _) {} // int setter
+}
+
+extension on double {
+ int get foo => 0; // double getter
+ void set foo(int _) {} // double setter
+}
+
+main() {
+ 0.foo; // int getter ref
+ 0.foo = 0; // int setter ref
+ (1.2).foo; // double getter ref
+ (1.2).foo = 0; // double setter ref
+}
+''');
+ var findNode = FindNode(testCode, testUnit);
+
+ var intGetter = findNode.methodDeclaration('0; // int getter');
+ var intSetter = findNode.methodDeclaration('{} // int setter');
+ assertThat(intGetter.declaredElement)
+ ..isReferencedAt('foo; // int getter ref', true);
+ assertThat(intSetter.declaredElement)
+ ..isReferencedAt('foo = 0; // int setter ref', true);
+
+ var doubleGetter = findNode.methodDeclaration('0; // double getter');
+ var doubleSetter = findNode.methodDeclaration('{} // double setter');
+ assertThat(doubleGetter.declaredElement)
+ ..isReferencedAt('foo; // double getter ref', true);
+ assertThat(doubleSetter.declaredElement)
+ ..isReferencedAt('foo = 0; // double setter ref', true);
+ }
}
class _ElementIndexAssert {
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 2f919bf..1fe3cf2 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -756,7 +756,7 @@
await _verifyReferences(element, expected);
}
- test_searchReferences_MethodElement() async {
+ test_searchReferences_MethodElement_class() async {
await _resolveTestUnit('''
class A {
m() {}
@@ -779,7 +779,55 @@
await _verifyReferences(method, expected);
}
- test_searchReferences_MethodMember() async {
+ test_searchReferences_MethodElement_extension_named() async {
+ await _resolveTestUnit('''
+extension E on int {
+ void foo() {}
+
+ void bar() {
+ foo(); // 1
+ this.foo(); // 2
+ print(foo); // 3
+ print(this.foo); // 4
+ }
+}
+''');
+ MethodElement method = _findElement('foo');
+ Element mainElement = _findElement('bar');
+ var expected = [
+ _expectId(mainElement, SearchResultKind.INVOCATION, 'foo(); // 1'),
+ _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'foo(); // 2'),
+ _expectId(mainElement, SearchResultKind.REFERENCE, 'foo); // 3'),
+ _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'foo); // 4')
+ ];
+ await _verifyReferences(method, expected);
+ }
+
+ test_searchReferences_MethodElement_extension_unnamed() async {
+ await _resolveTestUnit('''
+extension on int {
+ void foo() {}
+
+ void bar() {
+ foo(); // 1
+ this.foo(); // 2
+ print(foo); // 3
+ print(this.foo); // 4
+ }
+}
+''');
+ MethodElement method = _findElement('foo');
+ Element mainElement = _findElement('bar');
+ var expected = [
+ _expectId(mainElement, SearchResultKind.INVOCATION, 'foo(); // 1'),
+ _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'foo(); // 2'),
+ _expectId(mainElement, SearchResultKind.REFERENCE, 'foo); // 3'),
+ _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'foo); // 4')
+ ];
+ await _verifyReferences(method, expected);
+ }
+
+ test_searchReferences_MethodMember_class() async {
await _resolveTestUnit('''
class A<T> {
T m() => null;
diff --git a/pkg/analyzer/test/src/dart/element/subtype_test.dart b/pkg/analyzer/test/src/dart/element/subtype_test.dart
index e7c1853..1585cec 100644
--- a/pkg/analyzer/test/src/dart/element/subtype_test.dart
+++ b/pkg/analyzer/test/src/dart/element/subtype_test.dart
@@ -5399,6 +5399,17 @@
);
}
+ test_typeParameter_43() {
+ var T = typeParameter('T');
+
+ isNotSubtype(
+ typeParameterTypeNone(T),
+ objectNone,
+ strT0: 'T',
+ strT1: 'Object',
+ );
+ }
+
void _defineType(String str, DartType type) {
for (var key in _types.keys) {
if (key == 'Never' || _typeStr(type) == 'Never') {
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 86f64b0..fabe510 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -401,4 +401,12 @@
}
''');
}
+
+ test_unknown_uri() async {
+ await assertErrorsInCode(r'''
+import 'foo:bar';
+''', [
+ error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 9),
+ ]);
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/instance_member_access_from_static_test.dart b/pkg/analyzer/test/src/diagnostics/instance_member_access_from_static_test.dart
new file mode 100644
index 0000000..c54e3fd
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/instance_member_access_from_static_test.dart
@@ -0,0 +1,163 @@
+// 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/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InstanceMemberAccessFromStaticTest);
+ });
+}
+
+@reflectiveTest
+class InstanceMemberAccessFromStaticTest extends DriverResolutionTest {
+ test_class_field() async {
+ await assertErrorsInCode(r'''
+class A {
+ int foo;
+
+ static void bar() {
+ foo;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 48, 3),
+ ]);
+ }
+
+ test_class_getter() async {
+ await assertErrorsInCode(r'''
+class A {
+ int get foo => 0;
+
+ static void bar() {
+ foo;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 57, 3),
+ ]);
+ }
+
+ test_class_method() async {
+ await assertErrorsInCode(r'''
+class A {
+ void foo() {}
+
+ static void bar() {
+ foo();
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 53, 3),
+ ]);
+ }
+
+ test_class_setter() async {
+ await assertErrorsInCode(r'''
+class A {
+ set foo(int _) {}
+
+ static void bar() {
+ foo = 0;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 57, 3),
+ ]);
+ }
+
+ test_extension_external_getter() async {
+ await assertErrorsInCode(r'''
+extension E on A {
+ int get foo => 0;
+}
+
+class A {
+ static void bar() {
+ foo;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 78, 3),
+ ]);
+ }
+
+ test_extension_external_method() async {
+ await assertErrorsInCode(r'''
+extension E on A {
+ void foo() {}
+}
+
+class A {
+ static void bar() {
+ foo();
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 74, 3),
+ ]);
+ }
+
+ test_extension_external_setter() async {
+ await assertErrorsInCode(r'''
+extension E on A {
+ set foo(int _) {}
+}
+
+class A {
+ static void bar() {
+ foo = 0;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 78, 3),
+ ]);
+ }
+
+ test_extension_internal_getter() async {
+ await assertErrorsInCode(r'''
+extension E on int {
+ int get foo => 0;
+
+ static void bar() {
+ foo;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 68, 3),
+ ]);
+ }
+
+ test_extension_internal_method() async {
+ await assertErrorsInCode(r'''
+extension E on int {
+ void foo() {}
+
+ static void bar() {
+ foo();
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 64, 3),
+ ]);
+ }
+
+ test_extension_internal_setter() async {
+ await assertErrorsInCode(r'''
+extension E on int {
+ set foo(int _) {}
+
+ static void bar() {
+ foo = 0;
+ }
+}
+''', [
+ error(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, 68, 3),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_null_aware_operator_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_null_aware_operator_test.dart
index 4e2bdb7..87edfd6 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_null_aware_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_null_aware_operator_test.dart
@@ -61,6 +61,18 @@
''');
}
+ test_getter_Type() async {
+ await assertNoErrorsInCode('''
+class C {
+ static int x = 0;
+}
+
+f() {
+ C?.x;
+}
+''');
+ }
+
test_index_legacy() async {
newFile('/test/lib/a.dart', content: r'''
// @dart = 2.5
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 47eaec0..fce70a1 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -181,6 +181,8 @@
as inference_failure_on_untyped_parameter;
import 'instance_access_to_static_member_test.dart'
as instance_access_to_static_member;
+import 'instance_member_access_from_static_test.dart'
+ as instance_member_access_from_static;
import 'instantiate_abstract_class_test.dart' as instantiate_abstract_class;
import 'invalid_annotation_from_deferred_library_test.dart'
as invalid_annotation_from_deferred_library;
@@ -630,6 +632,7 @@
inference_failure_on_uninitialized_variable.main();
inference_failure_on_untyped_parameter.main();
instance_access_to_static_member.main();
+ instance_member_access_from_static.main();
instantiate_abstract_class.main();
invalid_annotation.main();
invalid_annotation_from_deferred_library.main();
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 327960b..6320f60 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -95,7 +95,7 @@
/// A set containing (eventually) all output units that will result from the
/// program.
- final List<OutputUnit> _allOutputUnits = new List<OutputUnit>();
+ final List<OutputUnit> _allOutputUnits = [];
/// Will be `true` if the program contains deferred libraries.
bool isProgramSplit = false;
@@ -104,29 +104,26 @@
/// A cache of the result of calling `computeImportDeferName` on the keys of
/// this map.
- final Map<ImportEntity, String> _importDeferName = <ImportEntity, String>{};
+ final Map<ImportEntity, String> _importDeferName = {};
/// A mapping from classes to their import set.
- Map<ClassEntity, ImportSet> _classToSet = new Map<ClassEntity, ImportSet>();
+ Map<ClassEntity, ImportSet> _classToSet = {};
/// A mapping from members to their import set.
- Map<MemberEntity, ImportSet> _memberToSet =
- new Map<MemberEntity, ImportSet>();
+ Map<MemberEntity, ImportSet> _memberToSet = {};
/// A mapping from local functions to their import set.
- Map<Local, ImportSet> _localFunctionToSet = new Map<Local, ImportSet>();
+ Map<Local, ImportSet> _localFunctionToSet = {};
/// A mapping from constants to their import set.
- Map<ConstantValue, ImportSet> _constantToSet =
- new Map<ConstantValue, ImportSet>();
+ Map<ConstantValue, ImportSet> _constantToSet = {};
Iterable<ImportEntity> get _allDeferredImports =>
_deferredImportDescriptions.keys;
/// Because the token-stream is forgotten later in the program, we cache a
/// description of each deferred import.
- final Map<ImportEntity, ImportDescription> _deferredImportDescriptions =
- <ImportEntity, ImportDescription>{};
+ final Map<ImportEntity, ImportDescription> _deferredImportDescriptions = {};
/// A lattice to compactly represent multiple subsets of imports.
ImportSetLattice importSets = ImportSetLattice();
@@ -139,7 +136,7 @@
compiler.options.reportInvalidInferredDeferredTypes;
DeferredLoadTask(this.compiler) : super(compiler.measurer) {
- _mainOutputUnit = new OutputUnit(true, 'main', new Set<ImportEntity>());
+ _mainOutputUnit = OutputUnit(true, 'main', <ImportEntity>{});
importSets.mainSet.unit = _mainOutputUnit;
_allOutputUnits.add(_mainOutputUnit);
}
@@ -256,14 +253,14 @@
/// Recursively collects all the dependencies of [type].
void _collectTypeDependencies(DartType type, Dependencies dependencies,
[ImportEntity import]) {
- new TypeDependencyVisitor(dependencies, import, commonElements).visit(type);
+ TypeDependencyVisitor(dependencies, import, commonElements).visit(type);
}
void _collectTypeArgumentDependencies(
Iterable<DartType> typeArguments, Dependencies dependencies,
[ImportEntity import]) {
if (typeArguments == null) return;
- new TypeDependencyVisitor(dependencies, import, commonElements)
+ TypeDependencyVisitor(dependencies, import, commonElements)
.visitList(typeArguments);
}
@@ -274,7 +271,7 @@
compiler.impactStrategy.visitImpact(
element,
worldImpact,
- new WorldImpactVisitorImpl(
+ WorldImpactVisitorImpl(
visitStaticUse: (MemberEntity member, StaticUse staticUse) {
Entity usedEntity = staticUse.element;
if (usedEntity is MemberEntity) {
@@ -437,7 +434,7 @@
// Continue recursively updating from [oldSet] to [newSet].
_classToSet[element] = newSet;
- Dependencies dependencies = new Dependencies();
+ Dependencies dependencies = Dependencies();
_collectAllElementsAndConstantsResolvedFromClass(
closedWorld, element, dependencies);
LibraryEntity library = element.library;
@@ -465,7 +462,7 @@
// Continue recursively updating from [oldSet] to [newSet].
_memberToSet[element] = newSet;
- Dependencies dependencies = new Dependencies();
+ Dependencies dependencies = Dependencies();
_collectAllElementsAndConstantsResolvedFromMember(
closedWorld, element, dependencies);
@@ -617,7 +614,7 @@
int counter = 1;
void addUnit(ImportSet importSet) {
if (importSet.unit != null) return;
- var unit = new OutputUnit(false, '$counter',
+ var unit = OutputUnit(false, '$counter',
importSet._collectImports().map((i) => i.declaration).toSet());
counter++;
importSet.unit = unit;
@@ -637,7 +634,7 @@
Map<String, List<OutputUnit>> _setupHunksToLoad() {
Map<String, List<OutputUnit>> hunksToLoad = {};
- Set<String> usedImportNames = new Set<String>();
+ Set<String> usedImportNames = {};
for (ImportEntity import in _allDeferredImports) {
String result = computeImportDeferName(import, compiler);
@@ -667,7 +664,7 @@
// We expect to find an entry for any call to `loadLibrary`, even if
// there is no code to load. In that case, the entry will be an empty
// list.
- hunksToLoad[_importDeferName[import]] = new List<OutputUnit>();
+ hunksToLoad[_importDeferName[import]] = [];
for (OutputUnit outputUnit in sortedOutputUnits) {
if (outputUnit == _mainOutputUnit) continue;
if (outputUnit._imports.contains(import)) {
@@ -773,7 +770,7 @@
}
work() {
- var queue = new WorkQueue(this.importSets);
+ var queue = WorkQueue(this.importSets);
// Add `main` and their recursive dependencies to the main output unit.
// We do this upfront to avoid wasting time visiting these elements when
@@ -814,10 +811,10 @@
OutputUnitData _buildResult() {
_createOutputUnits();
Map<String, List<OutputUnit>> hunksToLoad = _setupHunksToLoad();
- Map<ClassEntity, OutputUnit> classMap = <ClassEntity, OutputUnit>{};
- Map<MemberEntity, OutputUnit> memberMap = <MemberEntity, OutputUnit>{};
- Map<Local, OutputUnit> localFunctionMap = <Local, OutputUnit>{};
- Map<ConstantValue, OutputUnit> constantMap = <ConstantValue, OutputUnit>{};
+ Map<ClassEntity, OutputUnit> classMap = {};
+ Map<MemberEntity, OutputUnit> memberMap = {};
+ Map<Local, OutputUnit> localFunctionMap = {};
+ Map<ConstantValue, OutputUnit> constantMap = {};
_classToSet.forEach((cls, s) => classMap[cls] = s.unit);
_memberToSet.forEach((member, s) => memberMap[member] = s.unit);
_localFunctionToSet.forEach(
@@ -830,7 +827,7 @@
_constantToSet = null;
importSets = null;
cleanup();
- return new OutputUnitData(
+ return OutputUnitData(
this.isProgramSplit && !disableProgramSplit,
this._mainOutputUnit,
classMap,
@@ -855,7 +852,7 @@
for (ImportEntity import in elementEnvironment.getImports(library)) {
if (import.isDeferred) {
_deferredImportDescriptions[import] =
- new ImportDescription(import, library, rootLibraryUri);
+ ImportDescription(import, library, rootLibraryUri);
isProgramSplit = true;
}
}
@@ -875,8 +872,8 @@
/// Creates a textual representation of the output unit content.
String dump() {
- Map<OutputUnit, List<String>> elementMap = <OutputUnit, List<String>>{};
- Map<OutputUnit, List<String>> constantMap = <OutputUnit, List<String>>{};
+ Map<OutputUnit, List<String>> elementMap = {};
+ Map<OutputUnit, List<String>> constantMap = {};
_classToSet.forEach((ClassEntity element, ImportSet importSet) {
if (ignoreEntityInDump(element)) return;
var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
@@ -915,7 +912,7 @@
Map<OutputUnit, String> text = {};
for (OutputUnit outputUnit in _allOutputUnits) {
- StringBuffer unitText = new StringBuffer();
+ StringBuffer unitText = StringBuffer();
if (outputUnit.isMainOutput) {
unitText.write(' <MAIN UNIT>');
} else {
@@ -944,7 +941,7 @@
text[outputUnit] = '$unitText';
}
- StringBuffer sb = new StringBuffer();
+ StringBuffer sb = StringBuffer();
for (OutputUnit outputUnit in _allOutputUnits.toList()
..sort((a, b) => text[a].compareTo(text[b]))) {
sb.write('\n\n-------------------------------\n');
@@ -1061,8 +1058,8 @@
/// Get the index for an [import] according to the canonical order.
_DeferredImport _wrap(ImportEntity import) {
- return _importIndex.putIfAbsent(
- import, () => new _DeferredImport(import, _importIndex.length));
+ return _importIndex[import] ??=
+ _DeferredImport(import, _importIndex.length);
}
}
@@ -1117,7 +1114,7 @@
@override
String toString() {
- StringBuffer sb = new StringBuffer();
+ StringBuffer sb = StringBuffer();
sb.write('ImportSet(size: $length, ');
for (var import in _collectImports()) {
sb.write('${import.declaration.name} ');
@@ -1130,17 +1127,16 @@
/// The algorithm work queue.
class WorkQueue {
/// The actual queue of work that needs to be done.
- final Queue<WorkItem> queue = new Queue<WorkItem>();
+ final Queue<WorkItem> queue = Queue();
/// An index to find work items in the queue corresponding to a class.
- final Map<ClassEntity, WorkItem> pendingClasses = <ClassEntity, WorkItem>{};
+ final Map<ClassEntity, WorkItem> pendingClasses = {};
/// An index to find work items in the queue corresponding to a member.
- final Map<MemberEntity, WorkItem> pendingMembers = <MemberEntity, WorkItem>{};
+ final Map<MemberEntity, WorkItem> pendingMembers = {};
/// An index to find work items in the queue corresponding to a constant.
- final Map<ConstantValue, WorkItem> pendingConstants =
- <ConstantValue, WorkItem>{};
+ final Map<ConstantValue, WorkItem> pendingConstants = {};
/// Lattice used to compute unions of [ImportSet]s.
final ImportSetLattice _importSets;
@@ -1163,7 +1159,7 @@
void addClass(ClassEntity element, ImportSet importSet) {
var item = pendingClasses[element];
if (item == null) {
- item = new ClassWorkItem(element, importSet);
+ item = ClassWorkItem(element, importSet);
pendingClasses[element] = item;
queue.add(item);
} else {
@@ -1178,7 +1174,7 @@
void addMember(MemberEntity element, ImportSet importSet) {
var item = pendingMembers[element];
if (item == null) {
- item = new MemberWorkItem(element, importSet);
+ item = MemberWorkItem(element, importSet);
pendingMembers[element] = item;
queue.add(item);
} else {
@@ -1193,7 +1189,7 @@
void addConstant(ConstantValue constant, ImportSet importSet) {
var item = pendingConstants[constant];
if (item == null) {
- item = new ConstantWorkItem(constant, importSet);
+ item = ConstantWorkItem(constant, importSet);
pendingConstants[constant] = item;
queue.add(item);
} else {
@@ -1351,13 +1347,13 @@
Map<ImportEntity, ImportDescription> deferredImportDescriptions = {};
other._deferredImportDescriptions
.forEach((ImportEntity import, ImportDescription description) {
- deferredImportDescriptions[import] = new ImportDescription.internal(
+ deferredImportDescriptions[import] = ImportDescription.internal(
description.importingUri,
description.prefix,
convertLibrary(description._importingLibrary));
});
- return new OutputUnitData(
+ return OutputUnitData(
other.isProgramSplit,
other.mainOutputUnit,
classToUnit,
@@ -1379,7 +1375,7 @@
bool isMainOutput = source.readBool();
String name = source.readString();
Set<ImportEntity> importSet = source.readImports().toSet();
- return new OutputUnit(isMainOutput, name, importSet);
+ return OutputUnit(isMainOutput, name, importSet);
});
OutputUnit mainOutputUnit = outputUnits[source.readInt()];
@@ -1405,11 +1401,10 @@
String importingUri = source.readString();
String prefix = source.readString();
LibraryEntity importingLibrary = source.readLibrary();
- return new ImportDescription.internal(
- importingUri, prefix, importingLibrary);
+ return ImportDescription.internal(importingUri, prefix, importingLibrary);
});
source.end(tag);
- return new OutputUnitData(
+ return OutputUnitData(
isProgramSplit,
mainOutputUnit,
classToUnit,
@@ -1561,8 +1556,7 @@
String getImportDeferName(Spannable node, ImportEntity import) {
String name = _importDeferName[import];
if (name == null) {
- throw new SpannableAssertionFailure(
- node, "No deferred name for $import.");
+ throw SpannableAssertionFailure(node, "No deferred name for $import.");
}
return name;
}
@@ -1632,19 +1626,19 @@
class Dependencies {
final Map<ClassEntity, DependencyInfo> classes = {};
final Map<MemberEntity, DependencyInfo> members = {};
- final Set<Local> localFunctions = new Set<Local>();
+ final Set<Local> localFunctions = {};
final Map<ConstantValue, DependencyInfo> constants = {};
void addClass(ClassEntity cls, [ImportEntity import]) {
- (classes[cls] ??= new DependencyInfo()).registerImport(import);
+ (classes[cls] ??= DependencyInfo()).registerImport(import);
}
void addMember(MemberEntity m, [ImportEntity import]) {
- (members[m] ??= new DependencyInfo()).registerImport(import);
+ (members[m] ??= DependencyInfo()).registerImport(import);
}
void addConstant(ConstantValue c, [ImportEntity import]) {
- (constants[c] ??= new DependencyInfo()).registerImport(import);
+ (constants[c] ??= DependencyInfo()).registerImport(import);
}
}
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 3105010..62a40d7 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -33,6 +33,7 @@
new Map<OutputUnit, List<MemberEntity>>();
final Map<OutputUnit, List<FieldEntity>> outputStaticNonFinalFieldLists =
new Map<OutputUnit, List<FieldEntity>>();
+ final Map<OutputUnit, List<FieldEntity>> outputLazyStaticFieldLists = {};
final Map<OutputUnit, Set<LibraryEntity>> outputLibraryLists =
new Map<OutputUnit, Set<LibraryEntity>>();
@@ -287,6 +288,20 @@
eagerFields.forEach(addToOutputUnit);
}
+ void computeNeededLazyStaticFields() {
+ List<FieldEntity> lazyFields = [];
+ _codegenWorld.forEachStaticField((FieldEntity field) {
+ if (_closedWorld.fieldAnalysis.getFieldData(field).isLazy) {
+ lazyFields.add(field);
+ }
+ });
+
+ for (FieldEntity field in _sorter.sortMembers(lazyFields)) {
+ OutputUnit unit = _outputUnitData.outputUnitForMember(field);
+ (outputLazyStaticFieldLists[unit] ??= []).add(field);
+ }
+ }
+
void computeNeededLibraries() {
_generatedCode.keys.forEach((MemberEntity element) {
OutputUnit unit = _outputUnitData.outputUnitForMember(element);
@@ -309,6 +324,7 @@
computeNeededConstants();
computeNeededStatics();
computeNeededStaticNonFinalFields();
+ computeNeededLazyStaticFields();
computeNeededLibraries();
}
}
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index a400318..3287c1a 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -442,16 +442,10 @@
List<StaticField> _buildStaticLazilyInitializedFields(
LibrariesMap librariesMap) {
- List<FieldEntity> lazyFields = [];
- _codegenWorld.forEachStaticField((FieldEntity field) {
- if (_closedWorld.fieldAnalysis.getFieldData(field).isLazy &&
- _outputUnitData.outputUnitForMember(field) ==
- librariesMap.outputUnit) {
- lazyFields.add(field);
- }
- });
- return _sorter
- .sortMembers(lazyFields)
+ List<FieldEntity> lazyFields =
+ collector.outputLazyStaticFieldLists[librariesMap.outputUnit];
+ if (lazyFields == null) return const [];
+ return lazyFields
.map(_buildLazyField)
.where((field) => field != null) // Happens when the field was unused.
.toList(growable: false);
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index d628cc7..049814a 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -849,9 +849,14 @@
// Breakdown nullable type into TypeWithoutNullability|Null.
// Pre-nnbd Declared types are nullable, so we also add null in that case.
+ // TODO(41960): Remove check for legacy subtyping. This was added as a
+ // temporary workaround to unblock the null-safe unfork. At this time some
+ // native APIs are typed unsoundly because they don't consider browser
+ // compatibility or conditional support by context.
if (type is NullableType ||
type is LegacyType ||
- (!options.useNullSafety && type is! VoidType)) {
+ ((!options.useNullSafety || options.useLegacySubtyping) &&
+ type is! VoidType)) {
_behavior.typesReturned.add(commonElements.nullType);
}
}
diff --git a/pkg/compiler/tool/generate_kernel.dart b/pkg/compiler/tool/generate_kernel.dart
deleted file mode 100644
index 39fba2c..0000000
--- a/pkg/compiler/tool/generate_kernel.dart
+++ /dev/null
@@ -1,56 +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.
-
-/// Helper to run fasta with the right target configuration to build dart2js
-/// applications using the dart2js platform libraries.
-// TODO(sigmund): delete this file once we can configure fasta directly on the
-// command line.
-library compiler.tool.generate_kernel;
-
-import 'dart:io';
-
-import 'package:_fe_analyzer_shared/src/util/filenames.dart';
-import 'package:args/args.dart';
-import 'package:compiler/src/kernel/dart2js_target.dart';
-import 'package:front_end/src/api_unstable/dart2js.dart'
- show
- CompilerOptions,
- computePlatformBinariesLocation,
- kernelForProgram,
- relativizeUri;
-import 'package:kernel/kernel.dart';
-import 'package:kernel/target/targets.dart';
-
-main(List<String> args) async {
- ArgResults flags = _argParser.parse(args);
- var options = new CompilerOptions()
- ..target = new Dart2jsTarget("dart2js", new TargetFlags())
- ..packagesFileUri = Uri.base.resolve('.packages')
- ..setExitCodeOnProblem = true
- ..additionalDills = [Uri.base.resolve(nativeToUriPath(flags['platform']))];
-
- if (flags.rest.isEmpty) {
- var script = relativizeUri(Uri.base, Platform.script, false);
- var platform = relativizeUri(
- Uri.base, Uri.base.resolve(nativeToUriPath(flags['platform'])), false);
- print('usage: ${Platform.executable} $script '
- '[--platform=$platform] [--out=out.dill] program.dart');
- exit(1);
- }
-
- Uri entry = Uri.base.resolve(nativeToUriPath(flags.rest.first));
- var component = (await kernelForProgram(entry, options)).component;
- await writeComponentToBinary(component, flags['out']);
-}
-
-ArgParser _argParser = new ArgParser()
- ..addOption('platform',
- help: 'location of the precompiled dart2js sdk',
- defaultsTo: _defaultPlatform)
- ..addOption('out',
- abbr: 'o', help: 'output location', defaultsTo: 'out.dill');
-
-String _defaultPlatform = computePlatformBinariesLocation()
- .resolve('dart2js_platform.dill')
- .toFilePath();
diff --git a/pkg/compiler/tool/generate_kernel_test.dart b/pkg/compiler/tool/generate_kernel_test.dart
deleted file mode 100644
index b0c5f9d..0000000
--- a/pkg/compiler/tool/generate_kernel_test.dart
+++ /dev/null
@@ -1,24 +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.
-
-library compiler.tool.generate_kernel_test;
-
-import 'dart:io';
-import 'generate_kernel.dart' as m;
-import 'package:front_end/src/api_unstable/dart2js.dart'
- show computePlatformBinariesLocation;
-
-main() async {
- Directory dir;
- try {
- dir = Directory.systemTemp.createTempSync('generate_kernel_test');
- var file = dir.absolute.uri.resolve('hi.dart');
- new File.fromUri(file).writeAsStringSync("main() => print('hello world');");
- var platformUri =
- computePlatformBinariesLocation().resolve('dart2js_platform.dill');
- await m.main(['--platform=${platformUri.toFilePath()}', file.toFilePath()]);
- } finally {
- dir.deleteSync(recursive: true);
- }
-}
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 0f8bada..2f4a942 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -8,9 +8,11 @@
import 'package:args/args.dart';
import 'package:dds/dds.dart';
+import 'package:path/path.dart';
import '../core.dart';
import '../sdk.dart';
+import '../utils.dart';
class RunCommand extends DartdevCommand<int> {
final ArgParser argParser = ArgParser.allowAnything();
@@ -50,8 +52,47 @@
@override
FutureOr<int> run() async {
- // the command line arguments after 'run'
- final args = argResults.arguments;
+ // The command line arguments after 'run'
+ final args = argResults.arguments.toList();
+
+ var argsContainFileOrHelp = false;
+ for (var arg in args) {
+ // The arg.contains('.') matches a file name pattern, i.e. some 'foo.dart'
+ if (arg.contains('.') ||
+ arg == '--help' ||
+ arg == '-h' ||
+ arg == 'help') {
+ argsContainFileOrHelp = true;
+ break;
+ }
+ }
+
+ final cwd = Directory.current;
+ if (!argsContainFileOrHelp && cwd.existsSync()) {
+ var foundImplicitFileToRun = false;
+ var cwdName = cwd.name;
+ for (var entity in cwd.listSync(followLinks: false)) {
+ if (entity is Directory && entity.name == 'bin') {
+ var filesInBin =
+ entity.listSync(followLinks: false).whereType<File>();
+
+ // Search for a dart file in bin/ with the pattern foo/bin/foo.dart
+ for (var fileInBin in filesInBin) {
+ if (fileInBin.isDartFile && fileInBin.name == '$cwdName.dart') {
+ args.add('bin/${fileInBin.name}');
+ foundImplicitFileToRun = true;
+ break;
+ }
+ }
+ // break here, no actions taken on any entities that are not bin/
+ break;
+ }
+ }
+ if (!foundImplicitFileToRun) {
+ log.stderr(
+ 'Could not find the implicit file to run: bin$separator$cwdName.dart.');
+ }
+ }
// If the user wants to start a debugging session we need to do some extra
// work and spawn a Dart Development Service (DDS) instance. DDS is a VM
@@ -144,9 +185,8 @@
sdk.dart,
[
'--disable-dart-dev',
- _observe
- ? '--observe=0'
- : '--enable-vm-service=0', // We don't care which port the VM service binds to.
+ // We don't care which port the VM service binds to.
+ _observe ? '--observe=0' : '--enable-vm-service=0',
'--write-service-info=$serviceInfoUri',
..._args,
],
diff --git a/pkg/dartdev/lib/src/sdk.dart b/pkg/dartdev/lib/src/sdk.dart
index d80caad..583a030 100644
--- a/pkg/dartdev/lib/src/sdk.dart
+++ b/pkg/dartdev/lib/src/sdk.dart
@@ -12,7 +12,8 @@
// The common case, and how cli_util.dart computes the Dart SDK directory,
// path.dirname called twice on Platform.resolvedExecutable. We confirm by
// asserting that the directory ./bin/snapshots/ exists after this directory:
- var sdkPath = path.dirname(path.dirname(Platform.resolvedExecutable));
+ var sdkPath =
+ path.absolute(path.dirname(path.dirname(Platform.resolvedExecutable)));
var snapshotsDir = path.join(sdkPath, 'bin', 'snapshots');
if (Directory(snapshotsDir).existsSync()) {
return sdkPath;
@@ -23,10 +24,10 @@
// ./out/ReleaseX64/dart ...
// We confirm in a similar manner with the snapshot directory existence and
// then return the correct sdk path:
- snapshotsDir = path.join(path.dirname(Platform.resolvedExecutable),
+ snapshotsDir = path.absolute(path.dirname(Platform.resolvedExecutable),
'dart-sdk', 'bin', 'snapshots');
if (Directory(snapshotsDir).existsSync()) {
- return path.join(path.dirname(Platform.resolvedExecutable), 'dart-sdk');
+ return path.absolute(path.dirname(Platform.resolvedExecutable), 'dart-sdk');
}
// If neither returned above, we return the common case:
@@ -39,14 +40,14 @@
Sdk() : sdkPath = _computeSdkPath;
- String get dart => path.join(sdkPath, 'bin', _exeName('dart'));
+ String get dart => path.absolute(sdkPath, 'bin', _exeName('dart'));
- String get analysis_server_snapshot =>
- path.join(sdkPath, 'bin', 'snapshots', 'analysis_server.dart.snapshot');
+ String get analysis_server_snapshot => path.absolute(
+ sdkPath, 'bin', 'snapshots', 'analysis_server.dart.snapshot');
- String get dartfmt => path.join(sdkPath, 'bin', _binName('dartfmt'));
+ String get dartfmt => path.absolute(sdkPath, 'bin', _binName('dartfmt'));
- String get pub => path.join(sdkPath, 'bin', _binName('pub'));
+ String get pub => path.absolute(sdkPath, 'bin', _binName('pub'));
static String _binName(String base) =>
Platform.isWindows ? '$base.bat' : base;
diff --git a/pkg/dartdev/lib/src/utils.dart b/pkg/dartdev/lib/src/utils.dart
index 77dbe57..a4ec262 100644
--- a/pkg/dartdev/lib/src/utils.dart
+++ b/pkg/dartdev/lib/src/utils.dart
@@ -2,6 +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 'dart:io';
+import 'package:path/path.dart' as p;
+
/// Emit the given word with the correct pluralization.
String pluralize(String word, int count) => count == 1 ? word : '${word}s';
@@ -19,3 +22,9 @@
final Map<dynamic, dynamic> map = untyped as Map<dynamic, dynamic>;
return map?.cast<String, dynamic>();
}
+
+extension FileSystemEntityExtension on FileSystemEntity {
+ String get name => p.basename(path);
+
+ bool get isDartFile => this is File && p.extension(path) == '.dart';
+}
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 85ff6fa..a0df79e 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -11,8 +11,6 @@
group('migrate', defineMigrateTests, timeout: longTimeout);
}
-bool _nnbdIsEnabled = true;
-
void defineMigrateTests() {
final didYouForgetToRunPubGet = contains('Did you forget to run "pub get"?');
@@ -36,16 +34,16 @@
p = project(mainSrc: 'int get foo => 1;\n');
var result =
p.runSync('migrate', ['--no-web-preview'], workingDir: p.dirPath);
- expect(result.exitCode, _nnbdIsEnabled ? 0 : 2);
- expect(result.stderr, _nnbdIsEnabled ? isEmpty : isNotEmpty);
+ expect(result.exitCode, 0);
+ expect(result.stderr, isEmpty);
expect(result.stdout, contains('Generating migration suggestions'));
});
test('directory explicit', () {
p = project(mainSrc: 'int get foo => 1;\n');
var result = p.runSync('migrate', ['--no-web-preview', p.dirPath]);
- expect(result.exitCode, _nnbdIsEnabled ? 0 : 2);
- expect(result.stderr, _nnbdIsEnabled ? isEmpty : isNotEmpty);
+ expect(result.exitCode, 0);
+ expect(result.stderr, isEmpty);
expect(result.stdout, contains('Generating migration suggestions'));
});
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index 214207c..fcec9f5 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -44,4 +44,28 @@
expect(result.stderr, isNotEmpty);
expect(result.exitCode, isNot(0));
});
+
+ test('implicit packageName.dart', () {
+ // TODO(jwren) circle back to reimplement this test if possible, the file
+ // name (package name) will be the name of the temporary directory on disk
+ p = project(mainSrc: "void main() { print('Hello World'); }");
+ p.file('bin/main.dart', "void main() { print('Hello main.dart'); }");
+ ProcessResult result = p.runSync('run', []);
+
+ expect(result.stdout, contains('Hello main.dart'));
+ expect(result.stderr, isEmpty);
+ expect(result.exitCode, 0);
+ }, skip: true);
+
+ //Could not find the implicit file to run: bin
+ test('missing implicit packageName.dart', () {
+ p = project(mainSrc: "void main() { print('Hello World'); }");
+ p.file('bin/foo.dart', "void main() { print('Hello main.dart'); }");
+ ProcessResult result = p.runSync('run', []);
+
+ expect(result.stdout, isEmpty);
+ expect(result.stderr,
+ contains('Could not find the implicit file to run: bin'));
+ expect(result.exitCode, 255);
+ });
}
diff --git a/pkg/dartdev/test/utils_test.dart b/pkg/dartdev/test/utils_test.dart
index 932ab9e..489348c 100644
--- a/pkg/dartdev/test/utils_test.dart
+++ b/pkg/dartdev/test/utils_test.dart
@@ -3,8 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
+import 'dart:io';
import 'package:dartdev/src/utils.dart';
+import 'package:path/path.dart';
import 'package:test/test.dart';
void main() {
@@ -65,6 +67,27 @@
expect(packages, isList);
});
});
+
+ group('FileSystemEntityExtension', () {
+ test('isDartFile', () {
+ expect(File('foo.dart').isDartFile, isTrue);
+ expect(Directory('foo.dartt').isDartFile, isFalse);
+ expect(File('foo.dartt').isDartFile, isFalse);
+ expect(File('foo.darrt').isDartFile, isFalse);
+ expect(File('bar.bart').isDartFile, isFalse);
+ expect(File('bazdart').isDartFile, isFalse);
+ });
+
+ test('name', () {
+ expect(Directory('').name, '');
+ expect(Directory('dirName').name, 'dirName');
+ expect(Directory('dirName$separator').name, 'dirName');
+ expect(File('').name, '');
+ expect(File('foo.dart').name, 'foo.dart');
+ expect(File('${separator}foo.dart').name, 'foo.dart');
+ expect(File('bar.bart').name, 'bar.bart');
+ });
+ });
}
final String _packageData = '''{
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index d795355..09fffb4 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -3,6 +3,7 @@
- Added `getDartDevelopmentServiceVersion` RPC.
- Added DDS protocol to VM service `getSupportedProtocols` response.
- Added example/example.dart.
+- Allow for JSON-RPC 2.0 requests which are missing the `jsonrpc` parameter.
# 1.0.0
diff --git a/pkg/dds/lib/src/binary_compatible_peer.dart b/pkg/dds/lib/src/binary_compatible_peer.dart
index 645c1ca..de0a182 100644
--- a/pkg/dds/lib/src/binary_compatible_peer.dart
+++ b/pkg/dds/lib/src/binary_compatible_peer.dart
@@ -34,6 +34,8 @@
),
),
),
+ // Allow for requests without the jsonrpc parameter.
+ strictProtocolChecks: false,
);
static void _transformStream(
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index f1b4a25..1ab7910 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -12,7 +12,10 @@
this.ws,
json_rpc.Peer vmServicePeer,
) : _vmServicePeer = vmServicePeer {
- _clientPeer = json_rpc.Peer(ws.cast<String>());
+ _clientPeer = json_rpc.Peer(
+ ws.cast<String>(),
+ strictProtocolChecks: false,
+ );
_registerJsonRpcMethods();
}
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index 3282c47..bec795a 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -12,7 +12,7 @@
dependencies:
async: ^2.4.1
- json_rpc_2: ^2.1.0
+ json_rpc_2: ^2.2.0
meta: ^1.1.8
pedantic: ^1.7.0
shelf: ^0.7.5
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index ba7e03f..cbca683 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -101,12 +101,6 @@
FunctionNode _currentFunction;
- void setIncrementalCompilationScope(Library library, Class cls) {
- _currentLibrary = library;
- _staticTypeContext.enterLibrary(_currentLibrary);
- _currentClass = cls;
- }
-
/// Whether we are currently generating code for the body of a `JS()` call.
bool _isInForeignJS = false;
@@ -2356,7 +2350,8 @@
var c = classes.removeFirst();
var classesToCheck = [
if (c.supertype != null) c.supertype.classNode,
- for (var t in c.implementedTypes) if (t.classNode != null) t.classNode,
+ for (var t in c.implementedTypes)
+ if (t.classNode != null) t.classNode,
];
classes.addAll(classesToCheck);
for (var procedure in c.procedures) {
@@ -2856,8 +2851,28 @@
js_ast.Expression visitTypedefType(TypedefType type) =>
visitFunctionType(type.unalias as FunctionType);
- js_ast.Fun emitFunction(FunctionNode f, String name) =>
- _emitFunction(f, name);
+ /// Emits function after initial compilation.
+ ///
+ /// Emits function from kernel [functionNode] with name [name] in the context
+ /// of [library] and [cls], after the initial compilation of the module is
+ /// finished. For example, this happens in expression compilation during
+ /// expression evaluation initiated by the user from the IDE and coordinated
+ /// by the debugger.
+ js_ast.Fun emitFunctionIncremental(
+ Library library, Class cls, FunctionNode functionNode, String name) {
+ // setup context
+ _currentLibrary = library;
+ _staticTypeContext.enterLibrary(_currentLibrary);
+ _currentClass = cls;
+
+ // emit function with additional information,
+ // such as types that are used in the expression
+ var fun = _emitFunction(functionNode, name);
+ var items = _typeTable.discharge();
+ var body = js_ast.Block([...items, ...fun.body.statements]);
+
+ return js_ast.Fun(fun.params, body);
+ }
js_ast.Fun _emitFunction(FunctionNode f, String name) {
// normal function (sync), vs (sync*, async, async*)
@@ -4873,7 +4888,8 @@
types = types && _reifyGenericFunction(target);
final isJsInterop = target != null && isJsMember(target);
return [
- if (types) for (var typeArg in node.types) _emitType(typeArg),
+ if (types)
+ for (var typeArg in node.types) _emitType(typeArg),
for (var arg in node.positional)
if (arg is StaticInvocation &&
isJSSpreadInvocation(arg.target) &&
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index 67f259f..d39c7e6 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -505,13 +505,13 @@
// Print integer values as integers
return BigInt.from(c.value).toString();
}
- return c.toString();
+ return c.toConstantText();
}
return e.leakingDebugToString();
})
// Filter out our own NotNull annotations. The library prefix changes
// per test, so just filter on the suffix.
- .where((s) => !s.endsWith('::_NotNull {}'))
+ .where((s) => !s.endsWith('_NotNull{}'))
.join(', ');
expect(actualNotNull, equals(expectedNotNull));
}
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index d0e70a0..c44ed3f 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -269,6 +269,7 @@
'use strict';
if ($nnbd) {
sdk.dart.nullSafety($isNnbdStrong);
+ sdk.dart.weakNullSafetyWarnings(!$isNnbdStrong);
}
sdk._debugger.registerDevtoolsFormatter();
app.$libname.main();
@@ -301,6 +302,7 @@
try {
if ($nnbd) {
sdk.dart.nullSafety($isNnbdStrong);
+ sdk.dart.weakNullSafetyWarnings(!$isNnbdStrong);
}
sdk._isolate_helper.startRootIsolate(main, []);
} catch(e) {
@@ -334,6 +336,7 @@
try {
if ($nnbd) {
dart.nullSafety($isNnbdStrong);
+ dart.weakNullSafetyWarnings(!$isNnbdStrong);
}
_isolate_helper.startRootIsolate(() => {}, []);
main();
diff --git a/pkg/dev_compiler/tool/patch_sdk.dart b/pkg/dev_compiler/tool/patch_sdk.dart
index 3ef4057..06c87db 100755
--- a/pkg/dev_compiler/tool/patch_sdk.dart
+++ b/pkg/dev_compiler/tool/patch_sdk.dart
@@ -106,6 +106,12 @@
outLibRoot.resolve('_internal/sdk_library_metadata/lib/libraries.dart');
_writeSync(outLibrariesDart,
_generateLibrariesDart(libRoot, specification, useNnbd));
+
+ var experimentsPath = '_internal/allowed_experiments.json';
+ _writeSync(
+ outLibRoot.resolve(experimentsPath),
+ File.fromUri(libRoot.resolve(experimentsPath)).readAsStringSync(),
+ );
}
/// Writes a file, creating the directory if needed.
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index eba48ff..7376ca8 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -196,7 +196,7 @@
*
* Uses `[]` for objects that are only identical to themselves.
*/
- static List<List<int>> _findEquivalences(List<Object> objects) {
+ static List<List<int>> _findEquivalences(List<dynamic> objects) {
var equivalences = new List<List<int>>.generate(objects.length, (_) => []);
for (int i = 0; i < objects.length; i++) {
if (equivalences[i].isNotEmpty) continue;
@@ -214,8 +214,8 @@
return equivalences;
}
- static void _writeEquivalences(
- List<Object> objects, List<List<int>> equivalences, StringBuffer buffer) {
+ static void _writeEquivalences(List<dynamic> objects,
+ List<List<int>> equivalences, StringBuffer buffer) {
var separator = "";
for (int i = 0; i < objects.length; i++) {
buffer.write(separator);
@@ -233,7 +233,7 @@
}
}
- static void allIdentical(List<Object> objects, [String reason = ""]) {
+ static void allIdentical(List<dynamic> objects, [String reason = ""]) {
if (objects.length <= 1) return;
String msg = _getMessage(reason);
var equivalences = _findEquivalences(objects);
@@ -258,7 +258,7 @@
/**
* Checks that no two [objects] are `identical`.
*/
- static void allDistinct(List<Object> objects, [String reason = ""]) {
+ static void allDistinct(List<dynamic> objects, [String reason = ""]) {
String msg = _getMessage(reason);
var equivalences = _findEquivalences(objects);
diff --git a/pkg/expect/test/nnbd_mode_test.dart b/pkg/expect/test/nnbd_mode_test.dart
new file mode 100644
index 0000000..47fb624
--- /dev/null
+++ b/pkg/expect/test/nnbd_mode_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";
+
+final bool strong = () {
+ try {
+ int i = null as dynamic;
+ return false;
+ } catch (e) {
+ return true;
+ }
+}();
+
+void main() {
+ Expect.equals(strong, isStrongMode);
+ Expect.equals(!strong, isWeakMode);
+}
diff --git a/pkg/front_end/analysis_options_no_lints.yaml b/pkg/front_end/analysis_options_no_lints.yaml
index 44e9d25..6bbd1ac 100644
--- a/pkg/front_end/analysis_options_no_lints.yaml
+++ b/pkg/front_end/analysis_options_no_lints.yaml
@@ -11,7 +11,9 @@
- test/id_testing/data/**
- test/language_versioning/data/**
- test/patching/data/**
+ - test/predicates/data/**
- test/static_types/data/**
+ - test/text_representation/data/**
errors:
# Allow having TODOs in the code
todo: ignore
diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
new file mode 100644
index 0000000..ed9062f
--- /dev/null
+++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
@@ -0,0 +1,130 @@
+// 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';
+import '../fasta/kernel/late_lowering.dart';
+
+// TODO(johnniwinther): Add support for recognizing late lowered locals?
+
+/// Returns `true` if [node] is the field holding the value of a lowered late
+/// field.
+///
+/// For instance
+///
+/// late int field;
+///
+/// is lowered to (simplified):
+///
+/// int? _#field = null;
+/// int get field => _#field != null ? _#field : throw 'Uninitialized';
+/// void set field(int value) {
+/// _#field = value;
+/// }
+///
+/// where '_#field' is the field holding that value.
+///
+/// The default value of this field is `null`.
+bool isLateLoweredField(Field node) {
+ return node.isInternalImplementation &&
+ node.name != null &&
+ node.name.name.startsWith(lateFieldPrefix) &&
+ !node.name.name.endsWith(lateIsSetSuffix);
+}
+
+/// Returns `true` if [node] is the field holding the marker for whether a
+/// lowered late field has been set or not.
+///
+/// For instance
+///
+/// late int? field;
+///
+/// is lowered to (simplified):
+///
+/// bool _#field#isSet = false;
+/// int? _#field = null;
+/// int get field => _#field#isSet ? _#field : throw 'Uninitialized';
+/// void set field(int value) {
+/// _#field = value;
+/// _#field#isSet = true;
+/// }
+///
+/// where '_#field#isSet' is the field holding the marker.
+///
+/// The default value of this field is `false`.
+bool isLateLoweredIsSetField(Field node) {
+ return node.isInternalImplementation &&
+ node.name != null &&
+ node.name.name.startsWith(lateFieldPrefix) &&
+ node.name.name.endsWith(lateIsSetSuffix);
+}
+
+/// Returns `true` if [node] is the getter for reading the value of a lowered
+/// late field.
+///
+/// For instance
+///
+/// late int field;
+///
+/// is lowered to (simplified):
+///
+/// int? _#field = null;
+/// int get field => _#field != null ? _#field : throw 'Uninitialized';
+/// void set field(int value) {
+/// _#field = value;
+/// }
+///
+/// where 'int get field' is the getter for reading the field.
+///
+/// Note that the computation of this predicate is _not_ efficient and the
+/// result should be cached on the use site if queried repeatedly.
+bool isLateLoweredFieldGetter(Procedure node) {
+ if (node.kind == ProcedureKind.Getter) {
+ TreeNode parent = node.parent;
+ if (parent is Class) {
+ return parent.fields.any((Field field) =>
+ isLateLoweredField(field) &&
+ field.name.name.endsWith(node.name.name));
+ } else if (parent is Library) {
+ return parent.fields.any((Field field) =>
+ isLateLoweredField(field) &&
+ field.name.name.endsWith(node.name.name));
+ }
+ }
+ return false;
+}
+
+/// Returns `true` if [node] is the setter for setting the value of a lowered
+/// late field.
+///
+/// For instance
+///
+/// late int field;
+///
+/// is lowered to (simplified):
+///
+/// int? _#field = null;
+/// int get field => _#field != null ? _#field : throw 'Uninitialized';
+/// void set field(int value) {
+/// _#field = value;
+/// }
+///
+/// where 'void set field' is the setter for setting the value of the field.
+///
+/// Note that the computation of this predicate is _not_ efficient and the
+/// result should be cached on the use site if queried repeatedly.
+bool isLateLoweredFieldSetter(Procedure node) {
+ if (node.kind == ProcedureKind.Setter) {
+ TreeNode parent = node.parent;
+ if (parent is Class) {
+ return parent.fields.any((Field field) =>
+ isLateLoweredField(field) &&
+ field.name.name.endsWith(node.name.name));
+ } else if (parent is Library) {
+ return parent.fields.any((Field field) =>
+ isLateLoweredField(field) &&
+ field.name.name.endsWith(node.name.name));
+ }
+ }
+ return false;
+}
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index eaf6e00..68548a4 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -47,6 +47,8 @@
export '../api_prototype/kernel_generator.dart' show kernelForModule;
+export '../api_prototype/lowering_predicates.dart';
+
export '../api_prototype/memory_file_system.dart' show MemoryFileSystem;
export '../api_prototype/standard_file_system.dart' show StandardFileSystem;
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index be2f963..02a38dd 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -296,8 +296,10 @@
_fieldEncoding.completeSignature(coreTypes);
ClassBuilder classBuilder = isClassMember ? parent : null;
- MetadataBuilder.buildAnnotations(
- _fieldEncoding.annotatable, metadata, library, classBuilder, this);
+ for (Annotatable annotatable in _fieldEncoding.annotatables) {
+ MetadataBuilder.buildAnnotations(
+ annotatable, metadata, library, classBuilder, this);
+ }
// For modular compilation we need to include initializers of all const
// fields and all non-static final fields in classes with const constructors
@@ -406,14 +408,20 @@
@override
List<ClassMember> get localSetters => _fieldEncoding.getLocalSetters(this);
- static String createFieldName(
- bool isInstanceMember,
+ static String createFieldName(FieldNameType type, String name,
+ {bool isInstanceMember,
String className,
- bool isExtensionMethod,
+ bool isExtensionMethod: false,
String extensionName,
- String name,
- bool isSynthesized,
- FieldNameType type) {
+ bool isSynthesized: false}) {
+ assert(isSynthesized || type == FieldNameType.Field,
+ "Unexpected field name type for non-synthesized field: $type");
+ assert(isExtensionMethod || isInstanceMember != null,
+ "`isInstanceMember` is null for class member.");
+ assert(!(isExtensionMethod && extensionName == null),
+ "No extension name provided for extension member.");
+ assert(isInstanceMember == null || !(isInstanceMember && className == null),
+ "No class name provided for instance member.");
String baseName;
if (!isExtensionMethod) {
baseName = name;
@@ -422,10 +430,9 @@
}
if (!isSynthesized) {
- assert(type == FieldNameType.Field);
return baseName;
} else {
- String namePrefix = '_#';
+ String namePrefix = late_lowering.lateFieldPrefix;
if (isInstanceMember) {
namePrefix = '$namePrefix${className}#';
}
@@ -437,7 +444,7 @@
case FieldNameType.Setter:
return baseName;
case FieldNameType.IsSetField:
- return "$namePrefix$baseName#isSet";
+ return "$namePrefix$baseName${late_lowering.lateIsSetSuffix}";
}
}
throw new UnsupportedError("Unhandled case for field name.");
@@ -471,8 +478,8 @@
/// Returns the field that holds the field value at runtime.
Field get field;
- /// Returns the member that holds the field annotations.
- Annotatable get annotatable;
+ /// Returns the members that holds the field annotations.
+ Iterable<Annotatable> get annotatables;
/// Returns the member used to read the field value.
Member get readTarget;
@@ -555,8 +562,9 @@
String fieldName;
if (fieldBuilder.isExtensionMember) {
ExtensionBuilder extension = fieldBuilder.parent;
- fieldName = SourceFieldBuilder.createFieldName(false, null, true,
- extension.name, fieldBuilder.name, false, FieldNameType.Field);
+ fieldName = SourceFieldBuilder.createFieldName(
+ FieldNameType.Field, fieldBuilder.name,
+ isExtensionMethod: true, extensionName: extension.name);
_field
..hasImplicitGetter = false
..hasImplicitSetter = false
@@ -568,13 +576,8 @@
String className =
isInstanceMember ? fieldBuilder.classBuilder.name : null;
fieldName = SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- false,
- null,
- fieldBuilder.name,
- false,
- FieldNameType.Field);
+ FieldNameType.Field, fieldBuilder.name,
+ isInstanceMember: isInstanceMember, className: className);
_field
..hasImplicitGetter = isInstanceMember
..hasImplicitSetter = isInstanceMember &&
@@ -610,7 +613,7 @@
Field get field => _field;
@override
- Annotatable get annotatable => _field;
+ Iterable<Annotatable> get annotatables => [_field];
@override
Member get readTarget => _field;
@@ -725,6 +728,7 @@
_field.initializer = new NullLiteral()..parent = _field;
if (_lateIsSetField != null) {
_lateIsSetField.initializer = new BoolLiteral(false)
+ ..fileOffset = fileOffset
..parent = _lateIsSetField;
}
_lateGetter.function.body = _createGetterBody(coreTypes, name, initializer)
@@ -849,7 +853,13 @@
Field get field => _field;
@override
- Annotatable get annotatable => _field;
+ Iterable<Annotatable> get annotatables {
+ List<Annotatable> list = [_lateGetter];
+ if (_lateSetter != null) {
+ list.add(_lateSetter);
+ }
+ return list;
+ }
@override
Member get readTarget => _lateGetter;
@@ -886,25 +896,23 @@
}
_field.name ??= new Name(
SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtensionMember,
- extensionName,
- fieldBuilder.name,
- true,
- FieldNameType.Field),
+ FieldNameType.Field, fieldBuilder.name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtensionMember,
+ extensionName: extensionName,
+ isSynthesized: true),
libraryBuilder.library);
if (_lateIsSetField != null) {
_lateIsSetField
..name = new Name(
SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtensionMember,
- extensionName,
- fieldBuilder.name,
- true,
- FieldNameType.IsSetField),
+ FieldNameType.IsSetField, fieldBuilder.name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtensionMember,
+ extensionName: extensionName,
+ isSynthesized: true),
libraryBuilder.library)
..isStatic = !isInstanceMember
..hasImplicitGetter = isInstanceMember
@@ -915,13 +923,12 @@
_lateGetter
..name = new Name(
SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtensionMember,
- extensionName,
- fieldBuilder.name,
- true,
- FieldNameType.Getter),
+ FieldNameType.Getter, fieldBuilder.name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtensionMember,
+ extensionName: extensionName,
+ isSynthesized: true),
libraryBuilder.library)
..isStatic = !isInstanceMember
..isExtensionMember = isExtensionMember;
@@ -929,13 +936,12 @@
_lateSetter
..name = new Name(
SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtensionMember,
- extensionName,
- fieldBuilder.name,
- true,
- FieldNameType.Setter),
+ FieldNameType.Setter, fieldBuilder.name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtensionMember,
+ extensionName: extensionName,
+ isSynthesized: true),
libraryBuilder.library)
..isStatic = !isInstanceMember
..isExtensionMember = isExtensionMember;
@@ -1390,13 +1396,12 @@
}
_getter..isConst = fieldBuilder.isConst;
String getterName = SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtensionMember,
- extensionName,
- fieldBuilder.name,
- true,
- FieldNameType.Getter);
+ FieldNameType.Getter, fieldBuilder.name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtensionMember,
+ extensionName: extensionName,
+ isSynthesized: true);
_getter
..isStatic = !isInstanceMember
..isExtensionMember = isExtensionMember
@@ -1406,13 +1411,14 @@
if (_setter != null) {
String setterName = SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtensionMember,
- extensionName,
- fieldBuilder.name,
- true,
- FieldNameType.Setter);
+ FieldNameType.Setter,
+ fieldBuilder.name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtensionMember,
+ extensionName: extensionName,
+ isSynthesized: true,
+ );
_setter
..isStatic = !isInstanceMember
..isExtensionMember = isExtensionMember
@@ -1452,7 +1458,13 @@
}
@override
- Annotatable get annotatable => _getter;
+ Iterable<Annotatable> get annotatables {
+ List<Annotatable> list = [_getter];
+ if (_setter != null) {
+ list.add(_setter);
+ }
+ return list;
+ }
@override
Member get readTarget => _getter;
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 3da4fa2..a898f25 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -685,6 +685,15 @@
}
}
+ IncrementalKernelTarget createIncrementalKernelTarget(
+ FileSystem fileSystem,
+ bool includeComments,
+ DillTarget dillTarget,
+ UriTranslator uriTranslator) {
+ return new IncrementalKernelTarget(
+ fileSystem, includeComments, dillTarget, uriTranslator);
+ }
+
/// Create a new [userCode] object, and add the reused builders to it.
void setupNewUserCode(
CompilerContext c,
@@ -693,7 +702,7 @@
List<LibraryBuilder> reusedLibraries,
ExperimentalInvalidation experimentalInvalidation,
Uri firstEntryPoint) {
- userCode = new IncrementalKernelTarget(
+ userCode = createIncrementalKernelTarget(
new HybridFileSystem(
new MemoryFileSystem(
new Uri(scheme: "org-dartlang-debug", path: "/")),
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 38e392f..4714d44 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -2122,15 +2122,70 @@
..fileOffset = node.fileOffset
..flags = node.flags);
}
- if (constant is NullConstant && !node.isForNonNullableByDefault) {
- DartType nodeType = node.type;
- return makeBoolConstant(nodeType == typeEnvironment.nullType ||
- nodeType is InterfaceType &&
- nodeType.classNode == typeEnvironment.coreTypes.objectClass ||
- node.type is DynamicType);
+
+ DartType type = evaluateDartType(node, node.type);
+
+ bool performIs(Constant constant, {bool strongMode}) {
+ assert(strongMode != null);
+ if (strongMode) {
+ // In strong checking mode: if e evaluates to a value v and v has
+ // runtime type S, an instance check e is T occurring in a legacy
+ // library or an opted-in library is evaluated as follows:
+ //
+ // If v is null and T is a legacy type,
+ // return LEGACY_SUBTYPE(T, NULL) || LEGACY_SUBTYPE(Object, T)
+ // Otherwise return NNBD_SUBTYPE(S, T)
+ if (constant is NullConstant &&
+ type.nullability == Nullability.legacy) {
+ return typeEnvironment.isSubtypeOf(type, typeEnvironment.nullType,
+ SubtypeCheckMode.ignoringNullabilities) ||
+ typeEnvironment.isSubtypeOf(typeEnvironment.objectLegacyRawType,
+ type, SubtypeCheckMode.ignoringNullabilities);
+ }
+ return isSubtype(constant, type, SubtypeCheckMode.withNullabilities);
+ } else {
+ // In weak checking mode: if e evaluates to a value v and v has runtime
+ // type S, an instance check e is T occurring in a legacy library or an
+ // opted-in library is evaluated as follows:
+ //
+ // If v is null and T is a legacy type,
+ // return LEGACY_SUBTYPE(T, NULL) || LEGACY_SUBTYPE(Object, T)
+ // If v is null and T is not a legacy type,
+ // return NNBD_SUBTYPE(NULL, T)
+ // Otherwise return LEGACY_SUBTYPE(S, T)
+ if (constant is NullConstant) {
+ if (type.nullability == Nullability.legacy) {
+ // `null is Null` is handled below.
+ return typeEnvironment.isSubtypeOf(type, typeEnvironment.nullType,
+ SubtypeCheckMode.ignoringNullabilities) ||
+ typeEnvironment.isSubtypeOf(typeEnvironment.objectLegacyRawType,
+ type, SubtypeCheckMode.ignoringNullabilities);
+ } else {
+ return typeEnvironment.isSubtypeOf(typeEnvironment.nullType, type,
+ SubtypeCheckMode.withNullabilities);
+ }
+ }
+ return isSubtype(
+ constant, type, SubtypeCheckMode.ignoringNullabilities);
+ }
}
- return makeBoolConstant(
- isSubtype(constant, evaluateDartType(node, node.type)));
+
+ switch (evaluationMode) {
+ case EvaluationMode.strong:
+ return makeBoolConstant(performIs(constant, strongMode: true));
+ case EvaluationMode.agnostic:
+ bool strongResult = performIs(constant, strongMode: true);
+ Constant weakConstant = _weakener.visitConstant(constant) ?? constant;
+ bool weakResult = performIs(weakConstant, strongMode: false);
+ if (strongResult != weakResult) {
+ return report(node, messageNonAgnosticConstant);
+ }
+ return makeBoolConstant(strongResult);
+ case EvaluationMode.weak:
+ case EvaluationMode.legacy:
+ return makeBoolConstant(performIs(constant, strongMode: false));
+ }
+ throw new UnsupportedError("Unexpected evaluation mode $evaluationMode");
}
@override
@@ -2230,10 +2285,9 @@
BoolConstant makeBoolConstant(bool value) =>
value ? trueConstant : falseConstant;
- bool isSubtype(Constant constant, DartType type) {
+ bool isSubtype(Constant constant, DartType type, SubtypeCheckMode mode) {
DartType constantType = constant.getType(_staticTypeContext);
- bool result = typeEnvironment.isSubtypeOf(
- constantType, type, SubtypeCheckMode.withNullabilities);
+ bool result = typeEnvironment.isSubtypeOf(constantType, type, mode);
if (targetingJavaScript && !result) {
if (constantType is InterfaceType &&
constantType.classNode == typeEnvironment.coreTypes.intClass) {
@@ -2242,22 +2296,43 @@
new InterfaceType(typeEnvironment.coreTypes.doubleClass,
constantType.nullability, const <DartType>[]),
type,
- SubtypeCheckMode.withNullabilities);
+ mode);
} else if (intFolder.isInt(constant)) {
// With JS semantics, an integer valued double is also an int.
result = typeEnvironment.isSubtypeOf(
new InterfaceType(typeEnvironment.coreTypes.intClass,
constantType.nullability, const <DartType>[]),
type,
- SubtypeCheckMode.withNullabilities);
+ mode);
}
}
-
return result;
}
Constant ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
- if (!isSubtype(constant, type)) {
+ bool result;
+ switch (evaluationMode) {
+ case EvaluationMode.strong:
+ result = isSubtype(constant, type, SubtypeCheckMode.withNullabilities);
+ break;
+ case EvaluationMode.agnostic:
+ bool strongResult =
+ isSubtype(constant, type, SubtypeCheckMode.withNullabilities);
+ Constant weakConstant = _weakener.visitConstant(constant) ?? constant;
+ bool weakResult = isSubtype(
+ weakConstant, type, SubtypeCheckMode.ignoringNullabilities);
+ if (strongResult != weakResult) {
+ return report(node, messageNonAgnosticConstant);
+ }
+ result = strongResult;
+ break;
+ case EvaluationMode.weak:
+ case EvaluationMode.legacy:
+ result =
+ isSubtype(constant, type, SubtypeCheckMode.ignoringNullabilities);
+ break;
+ }
+ if (!result) {
return report(
node,
templateConstEvalInvalidType.withArguments(constant, type,
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index d3799f6..77b02bc 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -57,6 +57,11 @@
"withNullability", fieldBuilder.charOffset, fieldBuilder.fileUri);
}
+ @override
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('<implicit-field-type:$fieldBuilder>');
+ }
+
void addOverride(ImplicitFieldType other);
DartType checkInferred(DartType type);
@@ -178,7 +183,4 @@
@override
String toString() => 'ImplicitFieldType(${toStringInternal()})';
-
- @override
- String toStringInternal() => '$fieldBuilder';
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
index 7e51793..065fea3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
@@ -49,12 +49,12 @@
bool equals(Object other, Assumptions assumptions) => this == other;
@override
- String toString() {
- return "ImplicitTypeArgument(${toStringInternal()})";
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('<implicit-type-argument>');
}
@override
- String toStringInternal() {
- return "";
+ String toString() {
+ return "ImplicitTypeArgument(${toStringInternal()})";
}
}
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 06f50c5..f6dc730 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -3424,7 +3424,7 @@
right, const UnknownType(), typeNeeded,
isVoidAllowed: false);
- assert(equalsTarget.isInstanceMember);
+ assert(equalsTarget.isInstanceMember || equalsTarget.isNever);
if (inferrer.instrumentation != null && leftType == const DynamicType()) {
inferrer.instrumentation.record(
inferrer.uriForInstrumentation,
@@ -3453,7 +3453,10 @@
}
inferrer.flowAnalysis.equalityOp_end(equals, right, notEqual: isNot);
return new ExpressionInferenceResult(
- inferrer.coreTypes.boolRawType(inferrer.library.nonNullable), equals);
+ equalsTarget.isNever
+ ? const NeverType(Nullability.nonNullable)
+ : inferrer.coreTypes.boolRawType(inferrer.library.nonNullable),
+ equals);
}
/// Creates a binary expression of the binary operator with [binaryName] using
@@ -5432,7 +5435,10 @@
VariableDeclaration isSetVariable;
if (isPotentiallyNullable(node.type, inferrer.coreTypes.futureOrClass)) {
- isSetVariable = new VariableDeclaration('#${node.name}#isSet',
+ isSetVariable = new VariableDeclaration(
+ '${late_lowering.lateLocalPrefix}'
+ '${node.name}'
+ '${late_lowering.lateIsSetSuffix}',
initializer: new BoolLiteral(false)..fileOffset = fileOffset,
type: inferrer.coreTypes.boolRawType(inferrer.library.nonNullable))
..fileOffset = fileOffset;
@@ -5441,20 +5447,24 @@
Expression createVariableRead({bool needsPromotion: false}) {
if (needsPromotion) {
- return new VariableGet(node, node.type);
+ return new VariableGet(node, node.type)..fileOffset = fileOffset;
} else {
- return new VariableGet(node);
+ return new VariableGet(node)..fileOffset = fileOffset;
}
}
- Expression createIsSetRead() => new VariableGet(isSetVariable);
+ Expression createIsSetRead() =>
+ new VariableGet(isSetVariable)..fileOffset = fileOffset;
Expression createVariableWrite(Expression value) =>
new VariableSet(node, value);
Expression createIsSetWrite(Expression value) =>
new VariableSet(isSetVariable, value);
VariableDeclaration getVariable =
- new VariableDeclaration('#${node.name}#get')..fileOffset = fileOffset;
+ new VariableDeclaration('${late_lowering.lateLocalPrefix}'
+ '${node.name}'
+ '${late_lowering.lateLocalGetterSuffix}')
+ ..fileOffset = fileOffset;
FunctionDeclaration getter = new FunctionDeclaration(
getVariable,
new FunctionNode(
@@ -5488,7 +5498,9 @@
node.isLateFinalWithoutInitializer =
node.isFinal && node.initializer == null;
VariableDeclaration setVariable =
- new VariableDeclaration('#${node.name}#set')
+ new VariableDeclaration('${late_lowering.lateLocalPrefix}'
+ '${node.name}'
+ '${late_lowering.lateLocalSetterSuffix}')
..fileOffset = fileOffset;
VariableDeclaration setterParameter =
new VariableDeclaration(null, type: node.type)
diff --git a/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart b/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
new file mode 100644
index 0000000..7e474a3
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
@@ -0,0 +1,102 @@
+// 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.md file.
+
+import 'package:kernel/ast.dart' hide MapEntry;
+import 'package:kernel/visitor.dart';
+
+import '../type_inference/type_schema.dart';
+
+/// Check if [type] contains [InvalidType] as its part.
+///
+/// The helper function is intended for stopping cascading errors because of
+/// occurrences of [InvalidType]. In most cases it's safe to assume that if an
+/// [InvalidType] was produced, an error was reported as the part of its
+/// creation, so other errors raising, for example, from inability to assign to
+/// a variable of an [InvalidType], could be omitted.
+bool containsInvalidType(DartType type) {
+ return type.accept1(const _InvalidTypeFinder(), <TypedefType>{});
+}
+
+class _InvalidTypeFinder implements DartTypeVisitor1<bool, Set<TypedefType>> {
+ const _InvalidTypeFinder();
+
+ @override
+ bool defaultDartType(DartType node, Set<TypedefType> visitedTypedefs) {
+ if (node is UnknownType) return false;
+ throw new StateError("Unhandled type ${node.runtimeType}.");
+ }
+
+ @override
+ bool visitDynamicType(DynamicType node, Set<TypedefType> visitedTypedefs) =>
+ false;
+
+ @override
+ bool visitVoidType(VoidType node, Set<TypedefType> visitedTypedefs) => false;
+
+ @override
+ bool visitInvalidType(InvalidType node, Set<TypedefType> visitedTypedefs) =>
+ true;
+
+ @override
+ bool visitInterfaceType(
+ InterfaceType node, Set<TypedefType> visitedTypedefs) {
+ for (DartType typeArgument in node.typeArguments) {
+ if (typeArgument.accept1(this, visitedTypedefs)) return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitNeverType(NeverType node, Set<TypedefType> visitedTypedefs) =>
+ false;
+
+ @override
+ bool visitBottomType(BottomType node, Set<TypedefType> visitedTypedefs) =>
+ false;
+
+ @override
+ bool visitFunctionType(FunctionType node, Set<TypedefType> visitedTypedefs) {
+ if (node.returnType.accept1(this, visitedTypedefs)) return true;
+ for (TypeParameter typeParameter in node.typeParameters) {
+ if (typeParameter.bound.accept1(this, visitedTypedefs)) return true;
+ // TODO(dmitryas): Check defaultTypes as well if they cause cascading
+ // errors.
+ }
+ for (DartType parameter in node.positionalParameters) {
+ if (parameter.accept1(this, visitedTypedefs)) return true;
+ }
+ for (NamedType parameter in node.namedParameters) {
+ if (parameter.type.accept1(this, visitedTypedefs)) return true;
+ }
+ if (node.typedefType != null && visitedTypedefs.add(node.typedefType)) {
+ if (node.typedefType.accept1(this, visitedTypedefs)) return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitTypedefType(TypedefType node, Set<TypedefType> visitedTypedefs) {
+ // The unaliased type should be checked, but it's faster to check the type
+ // arguments and the RHS separately than do the unaliasing because it avoids
+ // type substitution.
+ for (DartType typeArgument in node.typeArguments) {
+ if (typeArgument.accept1(this, visitedTypedefs)) return true;
+ }
+ if (node.typedefNode.type.accept1(this, visitedTypedefs)) return true;
+ return false;
+ }
+
+ @override
+ bool visitTypeParameterType(
+ TypeParameterType node, Set<TypedefType> visitedTypedefs) {
+ // node.parameter.bound is not checked because such a bound doesn't
+ // automatically means that the potential errors related to the occurrences
+ // of the type-parameter type itself are reported.
+ if (node.promotedBound != null &&
+ node.promotedBound.accept1(this, visitedTypedefs)) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 2bf846c..ab04eed 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -30,6 +30,7 @@
NullLiteral,
Procedure,
RedirectingInitializer,
+ Reference,
Source,
SuperInitializer,
Supertype,
@@ -397,6 +398,26 @@
Component component = backendTarget.configureComponent(new Component(
nameRoot: nameRoot, libraries: libraries, uriToSource: uriToSource));
+
+ NonNullableByDefaultCompiledMode compiledMode = null;
+ if (enableNonNullable) {
+ switch (loader.nnbdMode) {
+ case NnbdMode.Weak:
+ compiledMode = NonNullableByDefaultCompiledMode.Weak;
+ break;
+ case NnbdMode.Strong:
+ compiledMode = NonNullableByDefaultCompiledMode.Strong;
+ break;
+ case NnbdMode.Agnostic:
+ compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
+ break;
+ }
+ } else {
+ compiledMode = NonNullableByDefaultCompiledMode.Disabled;
+ }
+
+ Reference mainReference;
+
if (loader.first != null) {
// TODO(sigmund): do only for full program
Builder declaration = loader.first.exportScope.lookup("main", -1, null);
@@ -404,32 +425,15 @@
AmbiguousBuilder problem = declaration;
declaration = problem.getFirstDeclaration();
}
- NonNullableByDefaultCompiledMode compiledMode = null;
- if (enableNonNullable) {
- switch (loader.nnbdMode) {
- case NnbdMode.Weak:
- compiledMode = NonNullableByDefaultCompiledMode.Weak;
- break;
- case NnbdMode.Strong:
- compiledMode = NonNullableByDefaultCompiledMode.Strong;
- break;
- case NnbdMode.Agnostic:
- compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
- break;
- }
- } else {
- compiledMode = NonNullableByDefaultCompiledMode.Disabled;
- }
if (declaration is ProcedureBuilder) {
- component.setMainMethodAndMode(
- declaration.actualProcedure?.reference, true, compiledMode);
+ mainReference = declaration.actualProcedure?.reference;
} else if (declaration is DillMemberBuilder) {
if (declaration.member is Procedure) {
- component.setMainMethodAndMode(
- declaration.member?.reference, true, compiledMode);
+ mainReference = declaration.member?.reference;
}
}
}
+ component.setMainMethodAndMode(mainReference, true, compiledMode);
if (metadataCollector != null) {
component.addMetadataRepository(metadataCollector.repository);
@@ -1049,14 +1053,13 @@
Set<String> patchFieldNames = {};
builder.forEachDeclaredField((String name, FieldBuilder fieldBuilder) {
patchFieldNames.add(SourceFieldBuilder.createFieldName(
- fieldBuilder.isClassInstanceMember,
- builder.name,
- false,
- null,
- name,
- fieldBuilder.isLate &&
- !builder.library.loader.target.backendTarget.supportsLateFields,
- FieldNameType.Field));
+ FieldNameType.Field,
+ name,
+ isInstanceMember: fieldBuilder.isClassInstanceMember,
+ className: builder.name,
+ isSynthesized: fieldBuilder.isLate &&
+ !builder.library.loader.target.backendTarget.supportsLateFields,
+ ));
});
builder.forEach((String name, Builder builder) {
if (builder is FieldBuilder) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
index c3f6dec..bc08e07 100644
--- a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
@@ -8,6 +8,12 @@
import '../names.dart';
+const String lateFieldPrefix = '_#';
+const String lateIsSetSuffix = '#isSet';
+const String lateLocalPrefix = '#';
+const String lateLocalGetterSuffix = '#get';
+const String lateLocalSetterSuffix = '#set';
+
/// Creates the body for the synthesized getter used to encode the lowering
/// of a late non-final field with an initializer or a late local with an
/// initializer.
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 477e0c8..22b5225 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
@@ -1915,13 +1915,12 @@
}
if (referencesFrom != null) {
String nameToLookup = SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtension,
- extensionName,
- name,
- fieldIsLateWithLowering,
- FieldNameType.Field);
+ FieldNameType.Field, name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtension,
+ extensionName: extensionName,
+ isSynthesized: fieldIsLateWithLowering);
if (_currentClassReferencesFromIndexed != null) {
referenceFrom =
@@ -1929,62 +1928,53 @@
if (fieldIsLateWithLowering) {
lateIsSetReferenceFrom = _currentClassReferencesFromIndexed
.lookupField(SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtension,
- extensionName,
- name,
- fieldIsLateWithLowering,
- FieldNameType.IsSetField));
- getterReferenceFrom = _currentClassReferencesFromIndexed
- .lookupProcedureNotSetter(SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtension,
- extensionName,
- name,
- fieldIsLateWithLowering,
- FieldNameType.Getter));
- setterReferenceFrom = _currentClassReferencesFromIndexed
- .lookupProcedureSetter(SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtension,
- extensionName,
- name,
- fieldIsLateWithLowering,
- FieldNameType.Setter));
+ FieldNameType.IsSetField, name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtension,
+ extensionName: extensionName,
+ isSynthesized: fieldIsLateWithLowering));
+ getterReferenceFrom =
+ _currentClassReferencesFromIndexed.lookupProcedureNotSetter(
+ SourceFieldBuilder.createFieldName(FieldNameType.Getter, name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtension,
+ extensionName: extensionName,
+ isSynthesized: fieldIsLateWithLowering));
+ setterReferenceFrom =
+ _currentClassReferencesFromIndexed.lookupProcedureSetter(
+ SourceFieldBuilder.createFieldName(FieldNameType.Setter, name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtension,
+ extensionName: extensionName,
+ isSynthesized: fieldIsLateWithLowering));
}
} else {
referenceFrom = referencesFromIndexed.lookupField(nameToLookup);
if (fieldIsLateWithLowering) {
lateIsSetReferenceFrom = referencesFromIndexed.lookupField(
- SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtension,
- extensionName,
- name,
- fieldIsLateWithLowering,
- FieldNameType.IsSetField));
+ SourceFieldBuilder.createFieldName(FieldNameType.IsSetField, name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtension,
+ extensionName: extensionName,
+ isSynthesized: fieldIsLateWithLowering));
getterReferenceFrom = referencesFromIndexed.lookupProcedureNotSetter(
- SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtension,
- extensionName,
- name,
- fieldIsLateWithLowering,
- FieldNameType.Getter));
+ SourceFieldBuilder.createFieldName(FieldNameType.Getter, name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtension,
+ extensionName: extensionName,
+ isSynthesized: fieldIsLateWithLowering));
setterReferenceFrom = referencesFromIndexed.lookupProcedureSetter(
- SourceFieldBuilder.createFieldName(
- isInstanceMember,
- className,
- isExtension,
- extensionName,
- name,
- fieldIsLateWithLowering,
- FieldNameType.Setter));
+ SourceFieldBuilder.createFieldName(FieldNameType.Setter, name,
+ isInstanceMember: isInstanceMember,
+ className: className,
+ isExtensionMethod: isExtension,
+ extensionName: extensionName,
+ isSynthesized: fieldIsLateWithLowering));
}
}
}
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 8b3ce56..b5533c4 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
@@ -50,6 +50,8 @@
import '../kernel/inference_visitor.dart';
+import '../kernel/invalid_type.dart';
+
import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
import '../names.dart';
@@ -415,8 +417,9 @@
returnType = inferrer.typeSchemaEnvironment.unfutureType(returnType);
}
if (inferrer.library.isNonNullableByDefault &&
- isPotentiallyNonNullable(
- returnType, inferrer.coreTypes.futureOrClass) &&
+ (containsInvalidType(returnType) ||
+ isPotentiallyNonNullable(
+ returnType, inferrer.coreTypes.futureOrClass)) &&
inferrer.flowAnalysis.isReachable) {
Statement resultStatement =
inferenceResult.hasChanged ? inferenceResult.statement : body;
@@ -2219,10 +2222,12 @@
inferenceNeeded ||
isOverloadedArithmeticOperator ||
typeChecksNeeded);
+ inferredType = result.inferredType == null || isNonNullableByDefault
+ ? result.inferredType
+ : legacyErasure(coreTypes, result.inferredType);
Expression expression =
- _hoist(result.expression, result.inferredType, hoistedExpressions);
+ _hoist(result.expression, inferredType, hoistedExpressions);
arguments.positional[position] = expression..parent = arguments;
- inferredType = result.inferredType;
}
if (inferenceNeeded || typeChecksNeeded) {
formalTypes.add(formalType);
@@ -2247,10 +2252,13 @@
inferenceNeeded ||
isOverloadedArithmeticOperator ||
typeChecksNeeded);
+ DartType inferredType =
+ result.inferredType == null || isNonNullableByDefault
+ ? result.inferredType
+ : legacyErasure(coreTypes, result.inferredType);
Expression expression =
- _hoist(result.expression, result.inferredType, hoistedExpressions);
+ _hoist(result.expression, inferredType, hoistedExpressions);
namedArgument.value = expression..parent = namedArgument;
- DartType inferredType = result.inferredType;
if (inferenceNeeded || typeChecksNeeded) {
formalTypes.add(formalType);
actualTypes.add(inferredType);
@@ -4321,9 +4329,12 @@
bool get isNullableCallFunction =>
kind == ObjectAccessTargetKind.nullableCallFunction;
- /// Returns `true` if this is an access on a dynamic receiver type.
+ /// Returns `true` if this is an access on a `dynamic` receiver type.
bool get isDynamic => kind == ObjectAccessTargetKind.dynamic;
+ /// Returns `true` if this is an access on a `Never` receiver type.
+ bool get isNever => kind == ObjectAccessTargetKind.never;
+
/// Returns `true` if this is an access on an invalid receiver type.
bool get isInvalid => kind == ObjectAccessTargetKind.invalid;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index 71b9ac1..0fabd3d 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -91,13 +91,13 @@
UnknownType withDeclaredNullability(Nullability nullability) => this;
@override
- String toString() {
- return "UnknownType(${toStringInternal()})";
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('?');
}
@override
- String toStringInternal() {
- return "<unknown-type>";
+ String toString() {
+ return "UnknownType(${toStringInternal()})";
}
}
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index 6f15e0b..1445f31 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -6,7 +6,9 @@
import 'package:_fe_analyzer_shared/src/testing/id.dart'
show ActualData, ClassId, Id, IdKind, IdValue, MemberId, NodeId;
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
+import 'package:front_end/src/base/nnbd_mode.dart';
import 'package:kernel/ast.dart';
+import 'package:kernel/target/targets.dart';
import '../api_prototype/compiler_options.dart'
show CompilerOptions, DiagnosticMessage;
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
@@ -45,11 +47,15 @@
// TODO(johnniwinther): Tailor support to redefine selected platform
// classes/members only.
final bool compileSdk;
+ final TargetFlags targetFlags;
+ final NnbdMode nnbdMode;
const TestConfig(this.marker, this.name,
{this.experimentalFlags = const {},
this.librariesSpecificationUri,
- this.compileSdk: false});
+ this.compileSdk: false,
+ this.targetFlags: const TargetFlags(),
+ this.nnbdMode: NnbdMode.Weak});
void customizeCompilerOptions(CompilerOptions options, TestData testData) {}
}
@@ -290,7 +296,9 @@
if (!succinct) printDiagnosticMessage(message, print);
};
options.debugDump = printCode;
+ options.target = new NoneTarget(config.targetFlags);
options.experimentalFlags.addAll(config.experimentalFlags);
+ options.nnbdMode = config.nnbdMode;
if (config.librariesSpecificationUri != null) {
Set<Uri> testFiles =
testData.memorySourceFiles.keys.map(createUriForFileName).toSet();
diff --git a/pkg/front_end/test/comments_on_certain_arguments_tool.dart b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
new file mode 100644
index 0000000..048c81d
--- /dev/null
+++ b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
@@ -0,0 +1,407 @@
+// 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:convert' show utf8;
+import 'dart:io'
+ show
+ Directory,
+ File,
+ FileSystemEntity,
+ Platform,
+ Process,
+ ProcessResult,
+ exitCode,
+ stdin,
+ stdout;
+
+import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;
+import 'package:_fe_analyzer_shared/src/parser/forwarding_listener.dart'
+ show NullListener;
+import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
+import 'package:_fe_analyzer_shared/src/scanner/token.dart'
+ show CommentToken, Token;
+import 'package:front_end/src/api_prototype/compiler_options.dart' as api;
+import 'package:front_end/src/api_prototype/file_system.dart' as api;
+import 'package:front_end/src/api_unstable/ddc.dart'
+ show CompilerContext, IncrementalCompiler, ProcessedOptions, Severity;
+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/fasta/dill/dill_target.dart' show DillTarget;
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+ show IncrementalCompiler, IncrementalKernelTarget;
+import 'package:front_end/src/fasta/kernel/kernel_target.dart'
+ show KernelTarget;
+import 'package:front_end/src/fasta/source/source_library_builder.dart'
+ show SourceLibraryBuilder;
+import 'package:front_end/src/fasta/source/source_loader.dart'
+ show SourceLoader;
+import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
+import 'package:kernel/kernel.dart';
+import 'package:kernel/target/targets.dart' show TargetFlags;
+import "package:vm/target/vm.dart" show VmTarget;
+
+final Uri repoDir = _computeRepoDir();
+
+Uri _computeRepoDir() {
+ ProcessResult result = Process.runSync(
+ 'git', ['rev-parse', '--show-toplevel'],
+ runInShell: true,
+ workingDirectory: new File.fromUri(Platform.script).parent.path);
+ String dirPath = (result.stdout as String).trim();
+ return new Directory(dirPath).uri;
+}
+
+Set<Uri> libUris = {};
+
+Component component;
+
+Future<void> main(List<String> args) async {
+ api.CompilerOptions compilerOptions = getOptions();
+
+ Uri dotPackagesUri = repoDir.resolve(".packages");
+ if (!new File.fromUri(dotPackagesUri).existsSync()) {
+ throw "Couldn't find .packages";
+ }
+ compilerOptions.packagesFileUri = dotPackagesUri;
+
+ ProcessedOptions options = new ProcessedOptions(options: compilerOptions);
+
+ libUris.add(repoDir.resolve("pkg/_fe_analyzer_shared/lib/src/parser"));
+ libUris.add(repoDir.resolve("pkg/_fe_analyzer_shared/lib/src/scanner"));
+ for (Uri uri in libUris) {
+ List<FileSystemEntity> entities =
+ new Directory.fromUri(uri).listSync(recursive: true);
+ for (FileSystemEntity entity in entities) {
+ if (entity is File && entity.path.endsWith(".dart")) {
+ options.inputs.add(entity.uri);
+ }
+ }
+ }
+ CompilerContext context = new CompilerContext(options);
+ IncrementalCompiler incrementalCompiler =
+ new TestIncrementalCompiler(context);
+ component = await incrementalCompiler.computeDelta();
+
+ for (Library library in component.libraries) {
+ if (library.importUri.scheme == "dart") continue;
+ // This isn't perfect because of parts, but (for now it'll do).
+ for (Uri uri in libUris) {
+ if (library.fileUri.toString().startsWith(uri.toString())) {
+ library.accept(new InvocationVisitor());
+ break;
+ }
+ }
+ }
+
+ if (args.isNotEmpty && args[0] == "--interactive") {
+ List<Uri> editsPerformed = [];
+ for (Uri uri in edits.keys) {
+ print("\n\n\n");
+ if (edits[uri] != null && edits[uri].isNotEmpty) {
+ String update;
+ while (update != "y" &&
+ update != "yes" &&
+ update != "n" &&
+ update != "no") {
+ print("Do you want to update $uri? (y/n)");
+ update = stdin.readLineSync();
+ }
+ if (update != "y" && update != "yes") continue;
+
+ List<Edit> theseEdits = edits[uri];
+ theseEdits.sort((a, b) => a.offset - b.offset);
+ String content = utf8.decode(component.uriToSource[uri].source,
+ allowMalformed: true);
+ StringBuffer sb = new StringBuffer();
+ int latest = 0;
+ for (Edit edit in theseEdits) {
+ sb.write(content.substring(latest, edit.offset));
+ sb.write(edit.insertData);
+ latest = edit.offset;
+ }
+ sb.write(content.substring(latest, content.length));
+ new File.fromUri(uri).writeAsStringSync(sb.toString());
+ editsPerformed.add(uri);
+ }
+ }
+ if (editsPerformed.isNotEmpty) {
+ print("\n\nYou should now probably run something like\n\n");
+ stdout.write(r"tools/sdks/dart-sdk/bin/dartfmt -w");
+ for (Uri uri in editsPerformed) {
+ File f = new File.fromUri(uri);
+ Directory relative = new Directory.fromUri(Uri.base.resolve("."));
+ if (!f.path.startsWith(relative.path)) {
+ throw "${f.path} vs ${relative.path}";
+ }
+ String relativePath = f.path.substring(relative.path.length);
+ stdout.write(" ${relativePath}");
+ }
+ stdout.write("\n\n");
+ }
+ }
+
+ if (edits.isNotEmpty) {
+ exitCode = 1;
+ }
+
+ int totalSuggestedEdits = edits.values
+ .fold(0, (previousValue, element) => previousValue + element.length);
+ print("Done. Suggested ${totalSuggestedEdits} edits "
+ "in ${edits.length} files.");
+}
+
+int errorCount = 0;
+
+api.CompilerOptions getOptions() {
+ // Compile sdk because when this is run from a lint it uses the checked-in sdk
+ // and we might not have a suitable compiled platform.dill file.
+ Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
+ api.CompilerOptions options = new api.CompilerOptions()
+ ..sdkRoot = sdkRoot
+ ..compileSdk = true
+ ..target = new VmTarget(new TargetFlags())
+ ..librariesSpecificationUri = repoDir.resolve("sdk/lib/libraries.json")
+ ..omitPlatform = true
+ ..onDiagnostic = (api.DiagnosticMessage message) {
+ if (message.severity == Severity.error) {
+ print(message.plainTextFormatted.join('\n'));
+ errorCount++;
+ }
+ }
+ ..environmentDefines = const {};
+ return options;
+}
+
+class InvocationVisitor extends RecursiveVisitor<void> {
+ void visitProcedure(Procedure node) {
+ if (node.isNoSuchMethodForwarder) return;
+ super.visitProcedure(node);
+ }
+
+ void visitMethodInvocation(MethodInvocation node) {
+ super.visitMethodInvocation(node);
+ if (node.interfaceTargetReference?.node != null) {
+ note(node.interfaceTargetReference?.node, node.arguments, node);
+ }
+ }
+
+ void visitDirectMethodInvocation(DirectMethodInvocation node) {
+ super.visitDirectMethodInvocation(node);
+ note(node.targetReference.node, node.arguments, node);
+ }
+
+ void visitSuperMethodInvocation(SuperMethodInvocation node) {
+ super.visitSuperMethodInvocation(node);
+ note(node.interfaceTargetReference.node, node.arguments, node);
+ }
+
+ void visitStaticInvocation(StaticInvocation node) {
+ super.visitStaticInvocation(node);
+ note(node.targetReference.node, node.arguments, node);
+ }
+
+ void visitConstructorInvocation(ConstructorInvocation node) {
+ super.visitConstructorInvocation(node);
+ note(node.targetReference.node, node.arguments, node);
+ }
+
+ void note(
+ NamedNode node, Arguments arguments, InvocationExpression invocation) {
+ List<VariableDeclaration> positionalParameters;
+ if (node is Procedure) {
+ positionalParameters = node.function.positionalParameters;
+ } else if (node is Constructor) {
+ positionalParameters = node.function.positionalParameters;
+ } else {
+ throw "Unexpected node: ${node.runtimeType}";
+ }
+
+ for (int i = 0; i < arguments.positional.length; i++) {
+ bool wantComment = false;
+ if (arguments.positional[i] is NullLiteral ||
+ arguments.positional[i] is BoolLiteral ||
+ arguments.positional[i] is IntLiteral) {
+ wantComment = true;
+ } else if (arguments.positional[i] is MapLiteral) {
+ MapLiteral literal = arguments.positional[i];
+ if (literal.entries.isEmpty) wantComment = true;
+ } else if (arguments.positional[i] is ListLiteral) {
+ ListLiteral literal = arguments.positional[i];
+ if (literal.expressions.isEmpty) wantComment = true;
+ } else if (arguments.positional[i] is MethodInvocation) {
+ MethodInvocation methodInvocation = arguments.positional[i];
+ if (methodInvocation.receiver is NullLiteral ||
+ methodInvocation.receiver is IntLiteral ||
+ methodInvocation.receiver is BoolLiteral) {
+ wantComment = true;
+ }
+ }
+ if (wantComment) {
+ check(invocation, i, positionalParameters[i],
+ "/* ${positionalParameters[i].name} = */");
+ }
+ }
+ }
+}
+
+Map<Uri, Token> cache = {};
+
+void check(InvocationExpression invocation, int parameterNumber,
+ VariableDeclaration parameter, String expectedComment) {
+ if (invocation.name.name == "==") return;
+ if (invocation.name.name == "[]=") return;
+ if (invocation.name.name == "[]") return;
+ if (invocation.name.name == "<") return;
+ if (invocation.name.name == "<=") return;
+ if (invocation.name.name == ">") return;
+ if (invocation.name.name == ">=") return;
+ if (invocation.name.name == "+") return;
+ if (invocation.name.name == "-") return;
+ if (invocation.name.name == "*") return;
+ if (invocation.name.name == "/") return;
+ if (invocation.name.name == "<<") return;
+ if (invocation.name.name == "<<<") return;
+ if (invocation.name.name == ">>") return;
+ if (invocation.name.name == "|=") return;
+ if (invocation.name.name == "|") return;
+ if (invocation.name.name == "&") return;
+ if (invocation.name.name == "~/") return;
+ Location location = invocation.location;
+ Token token = cache[location.file];
+ while (token.offset != invocation.fileOffset) {
+ token = token.next;
+ if (token.isEof) {
+ print("Couldn't find token for $invocation...");
+ return;
+ }
+ }
+ if (token.lexeme != invocation.name.name) {
+ bool ignore = false;
+ // Check if the next tokens are ".<what we're looking for>".
+ if (token.next.lexeme == "." &&
+ token.next.next.lexeme == invocation.name.name) {
+ ignore = true;
+ token = token.next.next;
+ } else if (invocation is StaticInvocation) {
+ Procedure p = invocation.targetReference.node;
+ ignore = p.isFactory;
+ }
+ if (invocation is ConstructorInvocation || ignore) {
+ // ignore that... E.g. new Foo() will have name ''.
+ } else {
+ Location calculatedLocation =
+ component.getLocation(location.file, token.offset);
+ throw "Expected to find ${invocation.name.name} but "
+ "found ${token.lexeme} at $calculatedLocation "
+ "(would have checked for comment $expectedComment)";
+ }
+ }
+ token = token.next;
+ while (token.lexeme == ".") {
+ token = token.next.next;
+ }
+ if (token.lexeme == "<") {
+ if (token.endGroup != null) {
+ token = token.endGroup.next;
+ }
+ }
+ while (token.lexeme == ".") {
+ token = token.next.next;
+ }
+ if (token.lexeme != "(") {
+ Location calculatedLocation =
+ component.getLocation(location.file, token.offset);
+ throw "Expected to find ( but found ${token.lexeme} "
+ "at $calculatedLocation"
+ " (would have checked for comment $expectedComment)";
+ }
+ if (parameterNumber > 0) {
+ Parser parser = new Parser(new NullListener());
+ for (int i = 0; i < parameterNumber; i++) {
+ token = parser.parseExpression(token);
+ if (token.next.lexeme != ",") {
+ throw "Expected to find , but found ${token.next.lexeme}";
+ }
+ token = token.next;
+ }
+ }
+ token = token.next;
+ bool foundComment = false;
+ CommentToken commentToken = token.precedingComments;
+ while (commentToken != null) {
+ if (commentToken.lexeme == expectedComment) {
+ // Exact match.
+ foundComment = true;
+ break;
+ }
+ if (commentToken.lexeme.replaceAll(" ", "") ==
+ expectedComment.replaceAll(" ", "")) {
+ // Close enough.
+ foundComment = true;
+ break;
+ }
+ commentToken = commentToken.next;
+ }
+ if (foundComment) {
+ return;
+ }
+ Location calculatedLocation =
+ component.getLocation(location.file, token.offset);
+ print("Please add comment $expectedComment at "
+ "${token.offset} => "
+ "${calculatedLocation}");
+ edits[location.file] ??= [];
+ edits[location.file].add(new Edit(token.offset, expectedComment));
+}
+
+Map<Uri, List<Edit>> edits = {};
+
+class Edit {
+ final int offset;
+ final String insertData;
+ Edit(this.offset, this.insertData);
+}
+
+class TestIncrementalCompiler extends IncrementalCompiler {
+ TestIncrementalCompiler(CompilerContext context) : super(context);
+
+ IncrementalKernelTarget createIncrementalKernelTarget(
+ api.FileSystem fileSystem,
+ bool includeComments,
+ DillTarget dillTarget,
+ UriTranslator uriTranslator) {
+ return new TestIncrementalKernelTarget(
+ fileSystem, /* includeComments = */ true, dillTarget, uriTranslator);
+ }
+}
+
+class TestIncrementalKernelTarget extends IncrementalKernelTarget {
+ TestIncrementalKernelTarget(api.FileSystem fileSystem, bool includeComments,
+ DillTarget dillTarget, UriTranslator uriTranslator)
+ : super(fileSystem, includeComments, dillTarget, uriTranslator);
+
+ SourceLoader createLoader() =>
+ new TestSourceLoader(fileSystem, includeComments, this);
+
+ void runBuildTransformations() {
+ // Don't do any transformations!
+ }
+}
+
+class TestSourceLoader extends SourceLoader {
+ TestSourceLoader(
+ api.FileSystem fileSystem, bool includeComments, KernelTarget target)
+ : super(fileSystem, includeComments, target);
+
+ Future<Token> tokenize(SourceLibraryBuilder library,
+ {bool suppressLexicalErrors: false}) async {
+ Token result = await super
+ .tokenize(library, suppressLexicalErrors: suppressLexicalErrors);
+ cache[library.fileUri] = result;
+ return result;
+ }
+}
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index d1d1102..c6c5b75 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -729,9 +729,11 @@
UriTranslator uriTranslator =
await context.computeUriTranslator(description);
TargetFlags targetFlags = new TargetFlags(
- forceLateLoweringForTesting: testOptions.forceLateLowering,
- forceNoExplicitGetterCallsForTesting:
- testOptions.forceNoExplicitGetterCalls);
+ forceLateLoweringForTesting: testOptions.forceLateLowering,
+ forceNoExplicitGetterCallsForTesting:
+ testOptions.forceNoExplicitGetterCalls,
+ enableNullSafety: !context.weak,
+ );
Target target;
switch (testOptions.target) {
case "vm":
diff --git a/pkg/front_end/test/predicates/data/late.dart b/pkg/front_end/test/predicates/data/late.dart
new file mode 100644
index 0000000..0d28456
--- /dev/null
+++ b/pkg/front_end/test/predicates/data/late.dart
@@ -0,0 +1,110 @@
+// 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.
+
+/*member: _#topLevelNonNullableWithoutInitializer:lateField*/
+/*member: topLevelNonNullableWithoutInitializer:lateFieldGetter*/
+/*member: topLevelNonNullableWithoutInitializer=:lateFieldSetter*/
+late int topLevelNonNullableWithoutInitializer;
+/*member: _#finalTopLevelNonNullableWithoutInitializer:lateField*/
+/*member: finalTopLevelNonNullableWithoutInitializer:lateFieldGetter*/
+/*member: finalTopLevelNonNullableWithoutInitializer=:lateFieldSetter*/
+late final int finalTopLevelNonNullableWithoutInitializer;
+/*member: _#topLevelNullableWithoutInitializer:lateField*/
+/*member: _#topLevelNullableWithoutInitializer#isSet:lateIsSetField*/
+/*member: topLevelNullableWithoutInitializer:lateFieldGetter*/
+/*member: topLevelNullableWithoutInitializer=:lateFieldSetter*/
+late int? topLevelNullableWithoutInitializer;
+/*member: _#finalTopLevelNullableWithoutInitializer:lateField*/
+/*member: _#finalTopLevelNullableWithoutInitializer#isSet:lateIsSetField*/
+/*member: finalTopLevelNullableWithoutInitializer:lateFieldGetter*/
+/*member: finalTopLevelNullableWithoutInitializer=:lateFieldSetter*/
+late final int? finalTopLevelNullableWithoutInitializer;
+/*member: _#topLevelNonNullableWithInitializer:lateField*/
+/*member: topLevelNonNullableWithInitializer:lateFieldGetter*/
+/*member: topLevelNonNullableWithInitializer=:lateFieldSetter*/
+late int topLevelNonNullableWithInitializer = 0;
+/*member: _#finalTopLevelNonNullableWithInitializer:lateField*/
+/*member: finalTopLevelNonNullableWithInitializer:lateFieldGetter*/
+late final int finalTopLevelNonNullableWithInitializer = 0;
+/*member: _#topLevelNullableWithInitializer:lateField*/
+/*member: _#topLevelNullableWithInitializer#isSet:lateIsSetField*/
+/*member: topLevelNullableWithInitializer:lateFieldGetter*/
+/*member: topLevelNullableWithInitializer=:lateFieldSetter*/
+late int? topLevelNullableWithInitializer = 0;
+/*member: _#finalTopLevelNullableWithInitializer:lateField*/
+/*member: _#finalTopLevelNullableWithInitializer#isSet:lateIsSetField*/
+/*member: finalTopLevelNullableWithInitializer:lateFieldGetter*/
+late final int? finalTopLevelNullableWithInitializer = 0;
+
+class Class {
+ /*member: Class._#Class#instanceNonNullableWithoutInitializer:lateField*/
+ /*member: Class.instanceNonNullableWithoutInitializer:lateFieldGetter*/
+ /*member: Class.instanceNonNullableWithoutInitializer=:lateFieldSetter*/
+ late int instanceNonNullableWithoutInitializer;
+ /*member: Class._#Class#finalInstanceNonNullableWithoutInitializer:lateField*/
+ /*member: Class.finalInstanceNonNullableWithoutInitializer:lateFieldGetter*/
+ /*member: Class.finalInstanceNonNullableWithoutInitializer=:lateFieldSetter*/
+ late final int finalInstanceNonNullableWithoutInitializer;
+ /*member: Class._#Class#instanceNullableWithoutInitializer:lateField*/
+ /*member: Class._#Class#instanceNullableWithoutInitializer#isSet:lateIsSetField*/
+ /*member: Class.instanceNullableWithoutInitializer:lateFieldGetter*/
+ /*member: Class.instanceNullableWithoutInitializer=:lateFieldSetter*/
+ late int? instanceNullableWithoutInitializer;
+ /*member: Class._#Class#finalInstanceNullableWithoutInitializer:lateField*/
+ /*member: Class._#Class#finalInstanceNullableWithoutInitializer#isSet:lateIsSetField*/
+ /*member: Class.finalInstanceNullableWithoutInitializer:lateFieldGetter*/
+ /*member: Class.finalInstanceNullableWithoutInitializer=:lateFieldSetter*/
+ late final int? finalInstanceNullableWithoutInitializer;
+ /*member: Class._#Class#instanceNonNullableWithInitializer:lateField*/
+ /*member: Class.instanceNonNullableWithInitializer:lateFieldGetter*/
+ /*member: Class.instanceNonNullableWithInitializer=:lateFieldSetter*/
+ late int instanceNonNullableWithInitializer = 0;
+ /*member: Class._#Class#finalInstanceNonNullableWithInitializer:lateField*/
+ /*member: Class.finalInstanceNonNullableWithInitializer:lateFieldGetter*/
+ late final int finalInstanceNonNullableWithInitializer = 0;
+ /*member: Class._#Class#instanceNullableWithInitializer:lateField*/
+ /*member: Class._#Class#instanceNullableWithInitializer#isSet:lateIsSetField*/
+ /*member: Class.instanceNullableWithInitializer:lateFieldGetter*/
+ /*member: Class.instanceNullableWithInitializer=:lateFieldSetter*/
+ late int? instanceNullableWithInitializer = 0;
+ /*member: Class._#Class#finalInstanceNullableWithInitializer:lateField*/
+ /*member: Class._#Class#finalInstanceNullableWithInitializer#isSet:lateIsSetField*/
+ /*member: Class.finalInstanceNullableWithInitializer:lateFieldGetter*/
+ late final int? finalInstanceNullableWithInitializer = 0;
+
+ /*member: Class._#staticNonNullableWithoutInitializer:lateField*/
+ /*member: Class.staticNonNullableWithoutInitializer:lateFieldGetter*/
+ /*member: Class.staticNonNullableWithoutInitializer=:lateFieldSetter*/
+ static late int staticNonNullableWithoutInitializer;
+ /*member: Class._#finalStaticNonNullableWithoutInitializer:lateField*/
+ /*member: Class.finalStaticNonNullableWithoutInitializer:lateFieldGetter*/
+ /*member: Class.finalStaticNonNullableWithoutInitializer=:lateFieldSetter*/
+ static late final int finalStaticNonNullableWithoutInitializer;
+ /*member: Class._#staticNullableWithoutInitializer:lateField*/
+ /*member: Class._#staticNullableWithoutInitializer#isSet:lateIsSetField*/
+ /*member: Class.staticNullableWithoutInitializer:lateFieldGetter*/
+ /*member: Class.staticNullableWithoutInitializer=:lateFieldSetter*/
+ static late int? staticNullableWithoutInitializer;
+ /*member: Class._#finalStaticNullableWithoutInitializer:lateField*/
+ /*member: Class._#finalStaticNullableWithoutInitializer#isSet:lateIsSetField*/
+ /*member: Class.finalStaticNullableWithoutInitializer:lateFieldGetter*/
+ /*member: Class.finalStaticNullableWithoutInitializer=:lateFieldSetter*/
+ static late final int? finalStaticNullableWithoutInitializer;
+ /*member: Class._#staticNonNullableWithInitializer:lateField*/
+ /*member: Class.staticNonNullableWithInitializer:lateFieldGetter*/
+ /*member: Class.staticNonNullableWithInitializer=:lateFieldSetter*/
+ static late int staticNonNullableWithInitializer = 0;
+ /*member: Class._#finalStaticNonNullableWithInitializer:lateField*/
+ /*member: Class.finalStaticNonNullableWithInitializer:lateFieldGetter*/
+ static late final int finalStaticNonNullableWithInitializer = 0;
+ /*member: Class._#staticNullableWithInitializer:lateField*/
+ /*member: Class._#staticNullableWithInitializer#isSet:lateIsSetField*/
+ /*member: Class.staticNullableWithInitializer:lateFieldGetter*/
+ /*member: Class.staticNullableWithInitializer=:lateFieldSetter*/
+ static late int? staticNullableWithInitializer = 0;
+ /*member: Class._#finalStaticNullableWithInitializer:lateField*/
+ /*member: Class._#finalStaticNullableWithInitializer#isSet:lateIsSetField*/
+ /*member: Class.finalStaticNullableWithInitializer:lateFieldGetter*/
+ static late final int? finalStaticNullableWithInitializer = 0;
+}
diff --git a/pkg/front_end/test/predicates/data/marker.options b/pkg/front_end/test/predicates/data/marker.options
new file mode 100644
index 0000000..afd83e5
--- /dev/null
+++ b/pkg/front_end/test/predicates/data/marker.options
@@ -0,0 +1 @@
+cfe=pkg/front_end/test/predicates/predicate_test.dart
diff --git a/pkg/front_end/test/predicates/predicate_test.dart b/pkg/front_end/test/predicates/predicate_test.dart
new file mode 100644
index 0000000..8320f85
--- /dev/null
+++ b/pkg/front_end/test/predicates/predicate_test.dart
@@ -0,0 +1,107 @@
+// 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:io' show Directory, Platform;
+import 'package:_fe_analyzer_shared/src/testing/id.dart';
+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:_fe_analyzer_shared/src/testing/features.dart';
+import 'package:front_end/src/api_prototype/experimental_flags.dart';
+import 'package:front_end/src/testing/id_testing_helper.dart';
+import 'package:front_end/src/api_prototype/lowering_predicates.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/target/targets.dart';
+
+main(List<String> args) async {
+ Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
+ await runTests<Features>(dataDir,
+ args: args,
+ createUriForFileName: createUriForFileName,
+ onFailure: onFailure,
+ runTest: runTestFor(const PredicateDataComputer(), [
+ const TestConfig(cfeMarker, 'cfe',
+ experimentalFlags: const {ExperimentalFlag.nonNullable: true},
+ targetFlags: const TargetFlags(forceLateLoweringForTesting: true))
+ ]));
+}
+
+class Tags {
+ static const String lateField = 'lateField';
+ static const String lateIsSetField = 'lateIsSetField';
+ static const String lateFieldGetter = 'lateFieldGetter';
+ static const String lateFieldSetter = 'lateFieldSetter';
+
+ static const String lateLocal = 'lateLocal';
+ static const String lateIsSetLocal = 'lateIsSetLocal';
+ static const String lateLocalGetter = 'lateLocalGetter';
+ static const String lateLocalSetter = 'lateLocalSetter';
+}
+
+class PredicateDataComputer extends DataComputer<Features> {
+ const PredicateDataComputer();
+
+ /// Function that computes a data mapping for [library].
+ ///
+ /// Fills [actualMap] with the data.
+ void computeLibraryData(
+ TestConfig config,
+ InternalCompilerResult compilerResult,
+ Library library,
+ Map<Id, ActualData<Features>> actualMap,
+ {bool verbose}) {
+ new PredicateDataExtractor(compilerResult, actualMap)
+ .computeForLibrary(library);
+ }
+
+ @override
+ void computeMemberData(
+ TestConfig config,
+ InternalCompilerResult compilerResult,
+ Member member,
+ Map<Id, ActualData<Features>> actualMap,
+ {bool verbose}) {
+ member.accept(new PredicateDataExtractor(compilerResult, actualMap));
+ }
+
+ @override
+ DataInterpreter<Features> get dataValidator =>
+ const FeaturesDataInterpreter();
+}
+
+class PredicateDataExtractor extends CfeDataExtractor<Features> {
+ PredicateDataExtractor(InternalCompilerResult compilerResult,
+ Map<Id, ActualData<Features>> actualMap)
+ : super(compilerResult, actualMap);
+
+ @override
+ Features computeLibraryValue(Id id, Library node) {
+ return null;
+ }
+
+ @override
+ Features computeMemberValue(Id id, Member node) {
+ if (node is Field) {
+ Features features = new Features();
+ if (isLateLoweredField(node)) {
+ features.add(Tags.lateField);
+ }
+ if (isLateLoweredIsSetField(node)) {
+ features.add(Tags.lateIsSetField);
+ }
+ return features;
+ } else if (node is Procedure) {
+ Features features = new Features();
+ if (isLateLoweredFieldGetter(node)) {
+ features.add(Tags.lateFieldGetter);
+ }
+
+ if (isLateLoweredFieldSetter(node)) {
+ features.add(Tags.lateFieldSetter);
+ }
+ return features;
+ }
+ return null;
+ }
+}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 3d6c0bc..b63f5aad 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -845,6 +845,7 @@
recall
received
recheck
+recognizing
recompiled
recompiling
recompute
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 3437680..25a39e4 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -137,6 +137,7 @@
and
angle
annotatable
+annotatables
annotated
annotating
annotation
@@ -1159,6 +1160,7 @@
finalizing
finally
find
+finder
finding
finds
fine
@@ -1520,6 +1522,7 @@
interaction
intercept
interceptors
+interdependent
interest
interesting
interests
@@ -2306,6 +2309,7 @@
quotes
quoting
raise
+raising
random
range
rare
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 2a38575..7159767 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -120,6 +120,7 @@
daemon
dartanalyzer
dartfile
+dartfmt
dash
dashes
day
@@ -415,6 +416,7 @@
r"
r"\s
r"k
+r"tools
rd
reachability
reality
@@ -485,6 +487,10 @@
subdir
subtool
subtools
+subtyping1a
+subtyping1b
+subtyping2a
+subtyping2b
suite
summarization
summarized
diff --git a/pkg/front_end/test/static_types/data/never.dart b/pkg/front_end/test/static_types/data/never.dart
new file mode 100644
index 0000000..b86d17f
--- /dev/null
+++ b/pkg/front_end/test/static_types/data/never.dart
@@ -0,0 +1,47 @@
+// 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.
+
+/*cfe:nnbd.library: nnbd=true*/
+
+// TODO(johnniwinther): Ensure static type of Never access is Never.
+
+propertyGet(Never never) {
+ var v1 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.dynamic*/ foo;
+ var v2 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.int!*/ hashCode;
+ var v3 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.Type!*/ runtimeType;
+ var v4 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.dynamic*/ toString;
+ var v5 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.dynamic*/ noSuchMethod;
+}
+
+propertySet(Never never) {
+ var v1 = /*cfe:nnbd.Never*/ never
+ . /*cfe:nnbd.update: int!*/ foo = /*cfe:nnbd.int!*/ 42;
+}
+
+methodInvocation(Never never, Invocation invocation) {
+ var v1 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.invoke: dynamic*/ foo();
+ var v2 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.invoke: dynamic*/ hashCode();
+ var v3 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.invoke: dynamic*/ runtimeType();
+ var v4 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.invoke: dynamic*/ toString();
+ var v5 = /*cfe:nnbd.Never*/ never
+ . /*cfe:nnbd.invoke: dynamic*/ toString(foo: /*cfe:nnbd.int!*/ 42);
+ var v6 = /*cfe:nnbd.Never*/ never. /*cfe:nnbd.invoke: dynamic*/ noSuchMethod(
+ /*cfe:nnbd.Invocation!*/ invocation);
+ var v7 = /*cfe:nnbd.Never*/ never
+ . /*cfe:nnbd.invoke: dynamic*/ noSuchMethod(/*cfe:nnbd.int!*/ 42);
+}
+
+equals(Never never) {
+ var v1 = /*cfe:nnbd.Never*/ never /*cfe:nnbd.invoke: bool!*/ == /*cfe:nnbd.Null*/ null;
+ var v2 = /*cfe:nnbd.Never*/ never /*cfe:nnbd.invoke: bool!*/ == /*cfe:nnbd.Never*/ never;
+}
+
+operator(Never never) {
+ var v1 = /*cfe:nnbd.Never*/ never /*cfe:nnbd.invoke: dynamic*/ + /*cfe:nnbd.Never*/ never;
+ var v2 = /*cfe:nnbd.invoke: dynamic*/ - /*cfe:nnbd.Never*/ never;
+ var v3 = /*cfe:nnbd.Never*/ never /*cfe:nnbd.dynamic*/ [
+ /*cfe:nnbd.Never*/ never];
+ var v4 = /*cfe:nnbd.Never*/ never /*cfe:nnbd.update: dynamic*/ [
+ /*cfe:nnbd.Never*/ never] = /*cfe:nnbd.Never*/ never;
+}
diff --git a/pkg/front_end/test/static_types/static_type_test.dart b/pkg/front_end/test/static_types/static_type_test.dart
index 4287b41..d67f465 100644
--- a/pkg/front_end/test/static_types/static_type_test.dart
+++ b/pkg/front_end/test/static_types/static_type_test.dart
@@ -30,6 +30,7 @@
'from_opt_out',
'if_null.dart',
'null_check.dart',
+ 'never.dart',
]
});
}
diff --git a/pkg/front_end/test/text_representation/data/constants.dart b/pkg/front_end/test/text_representation/data/constants.dart
new file mode 100644
index 0000000..4e7ab5b
--- /dev/null
+++ b/pkg/front_end/test/text_representation/data/constants.dart
@@ -0,0 +1,152 @@
+// 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: nnbd=true*/
+
+T id<T>(T /*T%*/ t) => t;
+
+class Class1<T> {
+ const Class1();
+}
+
+class Class2<T> {
+ final T field1;
+
+ const Class2(
+ this.
+ /*normal.Class2.T%*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class2.T%*/
+ field1);
+}
+
+class Class3<T, S> extends Class2<T> {
+ final S field2;
+
+ const Class3(
+ T
+ /*normal.Class3.T%*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class3.T%*/
+ field1,
+ this.
+ /*normal.Class3.S%*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class3.S%*/
+ field2)
+ : super(field1);
+}
+
+class Class4<T, S> extends Class3<T, S> {
+ final S field2;
+
+ const Class4(
+ T
+ /*normal.Class4.T%*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class4.T%*/
+ field1,
+ S
+ /*normal.Class4.S%*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class4.S%*/
+ shadowedField2,
+ this. /*normal.Class4.S%*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class4.S%*/
+ field2)
+ : super(field1, shadowedField2);
+}
+
+const nullConstant = /*null*/ null;
+const trueConstant = /*true*/ true;
+const falseConstant = /*false*/ false;
+const intConstant = /*42*/ 42;
+const doubleConstant = /*3.14*/ 3.14;
+const stringConstant = /*foo*/ "foo";
+const symbolConstant = /*#name*/ #name;
+const privateSymbolConstant =
+ /*normal.#_privateName*/
+ /*verbose.#library org-dartlang-test:///a/b/c/main.dart::_privateName*/
+ #_privateName;
+const listConstant1 = /*<dynamic>[]*/ [];
+const listConstant2 = <int>
+ /*normal.<int>[]*/
+ /*verbose.<dart.core::int>[]*/
+ [];
+const listConstant3 = <int>
+ /*normal.<int>[0]*/
+ /*verbose.<dart.core::int>[0]*/
+ [0];
+const listConstant4 = <int?>
+ /*normal.<int?>[0, 1]*/
+ /*verbose.<dart.core::int?>[0, 1]*/
+ [0, 1];
+const setConstant1 = <int>
+ /*normal.<int>{}*/
+ /*verbose.<dart.core::int>{}*/
+ {};
+const setConstant2 = <int>
+ /*normal.<int>{0}*/
+ /*verbose.<dart.core::int>{0}*/
+ {0};
+const setConstant3 = <int?>
+ /*normal.<int?>{0, 1}*/
+ /*verbose.<dart.core::int?>{0, 1}*/
+ {0, 1};
+const mapConstant1 = /*<dynamic, dynamic>{}*/ {};
+const mapConstant2 = <int, String>
+ /*normal.<int, String>{}*/
+ /*verbose.<dart.core::int, dart.core::String>{}*/
+ {};
+const mapConstant3 = <int, String>
+ /*normal.<int, String>{0: foo}*/
+ /*verbose.<dart.core::int, dart.core::String>{0: foo}*/
+ {0: "foo"};
+const mapConstant4 = <int, String?>
+ /*normal.<int, String?>{0: foo, 1: bar}*/
+ /*verbose.<dart.core::int, dart.core::String?>{0: foo, 1: bar}*/
+ {0: "foo", 1: "bar"};
+const tearOffConstant =
+ /*normal.id*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::id*/
+ id;
+const int Function(int) partialInitializationConstant =
+ /*normal.<int>id*/
+ /*verbose.<dart.core::int>library org-dartlang-test:///a/b/c/main.dart::id*/
+ id;
+const boolHasEnvironmentConstant = const
+ /*unevaluated{FileUriExpression()}*/
+ bool.hasEnvironment("foo");
+const boolFromEnvironmentConstant = const
+ /*unevaluated{FileUriExpression()}*/
+ bool.fromEnvironment("foo", defaultValue: true);
+const intFromEnvironmentConstant = const
+ /*unevaluated{FileUriExpression()}*/
+ int.fromEnvironment("foo", defaultValue: 87);
+const stringFromEnvironmentConstant = const
+ /*unevaluated{FileUriExpression()}*/
+ String.fromEnvironment("foo", defaultValue: "bar");
+const instanceConstant1 = const
+ /*normal.Class1<dynamic>{}*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class1<dynamic>{}*/
+ Class1();
+const instanceConstant2 = const
+ /*normal.Class1<int>{}*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class1<dart.core::int>{}*/
+ Class1<int>();
+const instanceConstant3 = const
+ /*normal.Class1<int>{}*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class1<dart.core::int>{}*/
+ Class1<int>();
+const instanceConstant4 = const
+ /*normal.Class2<int>{Class2.field1: 0}*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class2<dart.core::int>{Class2.field1: 0}*/
+ Class2(0);
+const instanceConstant5 = const
+ /*normal.Class2<num>{Class2.field1: 42}*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class2<dart.core::num>{Class2.field1: 42}*/
+ Class2<num>(42);
+const instanceConstant6 = const
+ /*normal.Class3<int, String>{Class3.field2: foo, Class2.field1: 42}*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class3<dart.core::int, dart.core::String>{Class3.field2: foo, Class2.field1: 42}*/
+ Class3<int, String>(42, "foo");
+const instanceConstant7 = const
+ /*normal.Class4<int, String?>{Class4.field2: baz, Class3.field2: foo, Class2.field1: 42}*/
+ /*verbose.library org-dartlang-test:///a/b/c/main.dart::Class4<dart.core::int, dart.core::String?>{Class4.field2: baz, Class3.field2: foo, Class2.field1: 42}*/
+ Class4<int, String?>(42, "foo", "baz");
diff --git a/pkg/front_end/test/text_representation/data/constants_opt_out.dart b/pkg/front_end/test/text_representation/data/constants_opt_out.dart
new file mode 100644
index 0000000..3f3ce69
--- /dev/null
+++ b/pkg/front_end/test/text_representation/data/constants_opt_out.dart
@@ -0,0 +1,121 @@
+// 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.
+
+// @dart=2.6
+
+/*library: nnbd=false*/
+library test;
+
+T id<T>(T /*T**/ t) => t;
+
+class Class1<T> {
+ const Class1();
+}
+
+class Class2<T> {
+ final T field1;
+
+ const Class2(this. /*normal.Class2.T**/ /*verbose.test::Class2.T**/ field1);
+}
+
+class Class3<T, S> extends Class2<T> {
+ final S field2;
+
+ const Class3(T /*normal.Class3.T**/ /*verbose.test::Class3.T**/ field1,
+ this. /*normal.Class3.S**/ /*verbose.test::Class3.S**/ field2)
+ : super(field1);
+}
+
+class Class4<T, S> extends Class3<T, S> {
+ final S field2;
+
+ const Class4(
+ T /*normal.Class4.T**/ /*verbose.test::Class4.T**/ field1,
+ S /*normal.Class4.S**/ /*verbose.test::Class4.S**/ shadowedField2,
+ this. /*normal.Class4.S**/ /*verbose.test::Class4.S**/ field2)
+ : super(field1, shadowedField2);
+}
+
+const nullConstant = /*null*/ null;
+const trueConstant = /*true*/ true;
+const falseConstant = /*false*/ false;
+const intConstant = /*42*/ 42;
+const doubleConstant = /*3.14*/ 3.14;
+const stringConstant = /*foo*/ "foo";
+const symbolConstant = /*#name*/ #name;
+const privateSymbolConstant =
+/*normal.#_privateName*/
+ /*verbose.#test::_privateName*/
+ #_privateName;
+const listConstant1 = /*<dynamic>[]*/ [];
+const listConstant2 =
+ <int> /*normal.<int*>[]*/ /*verbose.<dart.core::int*>[]*/ [];
+const listConstant3 =
+ <int> /*normal.<int*>[0]*/ /*verbose.<dart.core::int*>[0]*/ [0];
+const listConstant4 =
+ <int> /*normal.<int*>[0, 1]*/ /*verbose.<dart.core::int*>[0, 1]*/ [0, 1];
+const setConstant1 =
+ <int> /*normal.<int*>{}*/ /*verbose.<dart.core::int*>{}*/ {};
+const setConstant2 =
+ <int> /*normal.<int*>{0}*/ /*verbose.<dart.core::int*>{0}*/ {0};
+const setConstant3 =
+ <int> /*normal.<int*>{0, 1}*/ /*verbose.<dart.core::int*>{0, 1}*/ {0, 1};
+const mapConstant1 = /*<dynamic, dynamic>{}*/ {};
+const mapConstant2 = <int, String>
+ /*normal.<int*, String*>{}*/
+ /*verbose.<dart.core::int*, dart.core::String*>{}*/
+ {};
+const mapConstant3 = <int, String>
+ /*normal.<int*, String*>{0: foo}*/
+ /*verbose.<dart.core::int*, dart.core::String*>{0: foo}*/
+ {0: "foo"};
+const mapConstant4 = <int, String>
+ /*normal.<int*, String*>{0: foo, 1: bar}*/
+ /*verbose.<dart.core::int*, dart.core::String*>{0: foo, 1: bar}*/
+ {0: "foo", 1: "bar"};
+const tearOffConstant = /*normal.id*/ /*verbose.test::id*/ id;
+const int Function(int) partialInitializationConstant =
+ /*normal.<int*>id*/
+ /*verbose.<dart.core::int*>test::id*/
+ id;
+const boolHasEnvironmentConstant = const
+ /*unevaluated{FileUriExpression()}*/
+ bool.hasEnvironment("foo");
+const boolFromEnvironmentConstant = const
+ /*unevaluated{FileUriExpression()}*/
+ bool.fromEnvironment("foo", defaultValue: true);
+const intFromEnvironmentConstant = const
+ /*unevaluated{FileUriExpression()}*/
+ int.fromEnvironment("foo", defaultValue: 87);
+const stringFromEnvironmentConstant = const
+ /*unevaluated{FileUriExpression()}*/
+ String.fromEnvironment("foo", defaultValue: "bar");
+const instanceConstant1 = const
+ /*normal.Class1<dynamic>{}*/
+ /*verbose.test::Class1<dynamic>{}*/
+ Class1();
+const instanceConstant2 = const
+ /*normal.Class1<int*>{}*/
+ /*verbose.test::Class1<dart.core::int*>{}*/
+ Class1<int>();
+const instanceConstant3 = const
+ /*normal.Class1<int*>{}*/
+ /*verbose.test::Class1<dart.core::int*>{}*/
+ Class1<int>();
+const instanceConstant4 = const
+ /*normal.Class2<int*>{Class2.field1: 0}*/
+ /*verbose.test::Class2<dart.core::int*>{Class2.field1: 0}*/
+ Class2(0);
+const instanceConstant5 = const
+ /*normal.Class2<num*>{Class2.field1: 42}*/
+ /*verbose.test::Class2<dart.core::num*>{Class2.field1: 42}*/
+ Class2<num>(42);
+const instanceConstant6 = const
+ /*normal.Class3<int*, String*>{Class3.field2: foo, Class2.field1: 42}*/
+ /*verbose.test::Class3<dart.core::int*, dart.core::String*>{Class3.field2: foo, Class2.field1: 42}*/
+ Class3<int, String>(42, "foo");
+const instanceConstant7 = const
+ /*normal.Class4<int*, String*>{Class4.field2: baz, Class3.field2: foo, Class2.field1: 42}*/
+ /*verbose.test::Class4<dart.core::int*, dart.core::String*>{Class4.field2: baz, Class3.field2: foo, Class2.field1: 42}*/
+ Class4<int, String>(42, "foo", "baz");
diff --git a/pkg/front_end/test/text_representation/data/marker.options b/pkg/front_end/test/text_representation/data/marker.options
new file mode 100644
index 0000000..a42cf6d
--- /dev/null
+++ b/pkg/front_end/test/text_representation/data/marker.options
@@ -0,0 +1,2 @@
+normal=pkg/front_end/test/text_representation/text_representation_test.dart
+verbose=pkg/front_end/test/text_representation/text_representation_test.dart
\ No newline at end of file
diff --git a/pkg/front_end/test/text_representation/data/types.dart b/pkg/front_end/test/text_representation/data/types.dart
new file mode 100644
index 0000000..3be8e6b
--- /dev/null
+++ b/pkg/front_end/test/text_representation/data/types.dart
@@ -0,0 +1,215 @@
+// 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: nnbd=true*/
+library test;
+
+typedef void Typedef1();
+typedef void Typedef2<T>(T o);
+typedef Typedef3 = void Function();
+typedef Typedef4<T> = void Function(T);
+typedef Typedef5<T> = void Function<S>(T, S);
+
+boolType(bool /*normal.bool*/ /*verbose.dart.core::bool*/ o1,
+ bool? /*normal.bool?*/ /*verbose.dart.core::bool?*/ o2) {}
+numType(num /*normal.num*/ /*verbose.dart.core::num*/ o1,
+ num? /*normal.num?*/ /*verbose.dart.core::num?*/ o2) {}
+intType(int /*normal.int*/ /*verbose.dart.core::int*/ o1,
+ int? /*normal.int?*/ /*verbose.dart.core::int?*/ o2) {}
+doubleType(double /*normal.double*/ /*verbose.dart.core::double*/ o1,
+ double? /*normal.double?*/ /*verbose.dart.core::double?*/ o2) {}
+stringType(String /*normal.String*/ /*verbose.dart.core::String*/ o1,
+ String? /*normal.String?*/ /*verbose.dart.core::String?*/ o2) {}
+voidType(void /*void*/ o) {}
+dynamicType(dynamic /*dynamic*/ o) {}
+neverType(Never /*Never*/ o1, Never? /*Never?*/ o2) {}
+objectType(Object /*normal.Object*/ /*verbose.dart.core::Object*/ o1,
+ Object? /*normal.Object?*/ /*verbose.dart.core::Object?*/ o2) {}
+genericType1(
+ List<int>
+ /*normal.List<int>*/
+ /*verbose.dart.core::List<dart.core::int>*/
+ o1,
+ List<int>?
+ /*normal.List<int>?*/
+ /*verbose.dart.core::List<dart.core::int>?*/
+ o2,
+ List<int?>
+ /*normal.List<int?>*/
+ /*verbose.dart.core::List<dart.core::int?>*/
+ o3,
+ List<int?>?
+ /*normal.List<int?>?*/
+ /*verbose.dart.core::List<dart.core::int?>?*/
+ o4) {}
+genericType2(
+ Map<int, String>
+ /*normal.Map<int, String>*/
+ /*verbose.dart.core::Map<dart.core::int, dart.core::String>*/
+ o1,
+ Map<int, String?>?
+ /*normal.Map<int, String?>?*/
+ /*verbose.dart.core::Map<dart.core::int, dart.core::String?>?*/
+ o2) {}
+typeVariableType1<T>(T /*T%*/ o1, T? /*T?*/ o2) {}
+typeVariableType2<T extends num>(T /*T*/ o1, T? /*T?*/ o2) {}
+typeVariableType3<T extends S, S>(
+ T /*T%*/ o1, S /*S%*/ p1, T? /*T?*/ o2, S? /*S?*/ p2) {}
+typeVariableType4<T, S extends T>(
+ T /*T%*/ o1, S /*S%*/ p1, T? /*T?*/ o2, S? /*S?*/ p2) {}
+typeVariableType5<T extends Object>(T /*T*/ o1, T? /*T?*/ o2) {}
+typeVariableType6<T extends Object?>(T /*T%*/ o1, T? /*T?*/ o2) {}
+functionType1(void Function() /*void Function()*/ o1,
+ void Function()? /*void Function()?*/ o2) {}
+functionType2(
+ int Function(int)
+ /*normal.int Function(int)*/
+ /*verbose.dart.core::int Function(dart.core::int)*/
+ o1,
+ int? Function(int?)
+ /*normal.int? Function(int?)*/
+ /*verbose.dart.core::int? Function(dart.core::int?)*/
+ o2) {}
+functionType3(
+ int Function(int, String)
+ /*normal.int Function(int, String)*/
+ /*verbose.dart.core::int Function(dart.core::int, dart.core::String)*/
+ o) {}
+functionType4(
+ int Function([int])
+ /*normal.int Function([int])*/
+ /*verbose.dart.core::int Function([dart.core::int])*/
+ o1,
+ int Function([int?])
+ /*normal.int Function([int?])*/
+ /*verbose.dart.core::int Function([dart.core::int?])*/
+ o2) {}
+functionType5(
+ int Function([int, String])
+ /*normal.int Function([int, String])*/
+ /*verbose.dart.core::int Function([dart.core::int, dart.core::String])*/
+ o) {}
+functionType6(
+ int Function({int a})
+ /*normal.int Function({a: int})*/
+ /*verbose.dart.core::int Function({a: int})*/
+ o1,
+ int Function({int? a})
+ /*normal.int Function({a: int?})*/
+ /*verbose.dart.core::int Function({a: int?})*/
+ o2) {}
+functionType7(
+ int Function({int a, String b})
+ /*normal.int Function({a: int, b: String})*/
+ /*verbose.dart.core::int Function({a: int, b: String})*/
+ o) {}
+functionType8(
+ int Function(int, {String b})
+ /*normal.int Function(int, {b: String})*/
+ /*verbose.dart.core::int Function(dart.core::int, {b: String})*/
+ o) {}
+functionType9(
+ int Function({required int a, String b})
+ /*normal.int Function({required a: int, b: String})*/
+ /*verbose.dart.core::int Function({required a: int, b: String})*/
+ o) {}
+functionType10(
+ int Function({int a, required String b})
+ /*normal.int Function({a: int, required b: String})*/
+ /*verbose.dart.core::int Function({a: int, required b: String})*/
+ o) {}
+functionType11(
+ int Function({required int a, required String b})
+ /*normal.int Function({required a: int, required b: String})*/
+ /*verbose.dart.core::int Function({required a: int, required b: String})*/
+ o) {}
+genericFunctionType1(void Function<T>() /*void Function<T>()*/ o) {}
+genericFunctionType2(T Function<T>(T, T?) /*T% Function<T>(T%, T?)*/ o) {}
+genericFunctionType3(
+ T Function<T, S>(T, S, T?, S?) /*T% Function<T, S>(T%, S%, T?, S?)*/ o) {}
+genericFunctionType4(
+ T Function<T extends num>([T, T?])
+ /*normal.T Function<T extends num>([T, T?])*/
+ /*verbose.T Function<T extends dart.core::num>([T, T?])*/
+ o) {}
+// TODO(johnniwinther): Support interdependent function type variables.
+//genericFunctionType5(T Function<T, S extends T>([T, S]) o) {}
+//genericFunctionType6(T Function<T extends S, S>([T, S]) o) {}
+typedefType1(Typedef1 /*normal.Typedef1*/ /*verbose.test::Typedef1*/ o) {}
+typedefType2(
+ Typedef2
+ /*normal.Typedef2<dynamic>*/
+ /*verbose.test::Typedef2<dynamic>*/
+ o) {}
+typedefType3(
+ Typedef2<int>
+ /*normal.Typedef2<int>*/
+ /*verbose.test::Typedef2<dart.core::int>*/
+ o1,
+ Typedef2<int?>
+ /*normal.Typedef2<int?>*/
+ /*verbose.test::Typedef2<dart.core::int?>*/
+ o2) {}
+typedefType4(Typedef3 /*normal.Typedef3*/ /*verbose.test::Typedef3*/ o) {}
+typedefType5(
+ Typedef4
+ /*normal.Typedef4<dynamic>*/
+/*verbose.test::Typedef4<dynamic>*/
+ o) {}
+typedefType7(
+ Typedef4<int>
+ /*normal.Typedef4<int>*/
+ /*verbose.test::Typedef4<dart.core::int>*/
+ o1,
+ Typedef4<int>?
+ /*normal.Typedef4<int>?*/
+ /*verbose.test::Typedef4<dart.core::int>?*/
+ o2) {}
+typedefType8(
+ Typedef5
+ /*normal.Typedef5<dynamic>*/
+ /*verbose.test::Typedef5<dynamic>*/
+ o) {}
+typedefType9(
+ Typedef5<int>
+ /*normal.Typedef5<int>*/
+ /*verbose.test::Typedef5<dart.core::int>*/
+ o1,
+ Typedef5<int?>?
+ /*normal.Typedef5<int?>?*/
+ /*verbose.test::Typedef5<dart.core::int?>?*/
+ o2) {}
+
+method() {
+ var /*dynamic Function<T>(T%, T?)*/ o1 =
+ /*normal.typeVariableType1*/
+ /*verbose.test::typeVariableType1*/
+ typeVariableType1;
+ var /*normal.dynamic Function<T extends num>(T, T?)*/
+ /*verbose.dynamic Function<T extends dart.core::num>(T, T?)*/ o2 =
+ /*normal.typeVariableType2*/
+ /*verbose.test::typeVariableType2*/
+ typeVariableType2;
+ var /*dynamic Function<T extends S%, S>(T%, S%, T?, S?)*/ o3 =
+ /*normal.typeVariableType3*/
+ /*verbose.test::typeVariableType3*/
+ typeVariableType3;
+ var /*dynamic Function<T, S extends T%>(T%, S%, T?, S?)*/ o4 =
+ /*normal.typeVariableType4*/
+ /*verbose.test::typeVariableType4*/
+ typeVariableType4;
+ var /*normal.dynamic Function<T extends Object>(T, T?)*/
+ /*verbose.dynamic Function<T extends dart.core::Object>(T, T?)*/ o5 =
+ /*normal.typeVariableType5*/
+ /*verbose.test::typeVariableType5*/
+ typeVariableType5;
+ var /*normal.dynamic Function<T extends Object?>(T%, T?)*/
+ /*verbose.dynamic Function<T extends dart.core::Object?>(T%, T?)*/ o6 =
+ /*normal.typeVariableType6*/
+ /*verbose.test::typeVariableType6*/
+ typeVariableType6;
+
+ var /*Never*/ bottom1 = throw '';
+ var /*Never Function()*/ bottom2 = () => throw '';
+}
diff --git a/pkg/front_end/test/text_representation/data/types_opt_out.dart b/pkg/front_end/test/text_representation/data/types_opt_out.dart
new file mode 100644
index 0000000..85c5a2c
--- /dev/null
+++ b/pkg/front_end/test/text_representation/data/types_opt_out.dart
@@ -0,0 +1,158 @@
+// 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.
+
+// @dart=2.6
+
+/*library: nnbd=false*/
+library test;
+
+typedef void Typedef1();
+typedef void Typedef2<T>(T o);
+typedef Typedef3 = void Function();
+typedef Typedef4<T> = void Function(T);
+typedef Typedef5<T> = void Function<S>(T, S);
+
+boolType(bool /*normal.bool**/ /*verbose.dart.core::bool**/ o) {}
+numType(num /*normal.num**/ /*verbose.dart.core::num**/ o) {}
+intType(int /*normal.int**/ /*verbose.dart.core::int**/ o) {}
+doubleType(double /*normal.double**/ /*verbose.dart.core::double**/ o) {}
+stringType(String /*normal.String**/ /*verbose.dart.core::String**/ o) {}
+voidType(void /*void*/ o) {}
+dynamicType(dynamic /*dynamic*/ o) {}
+neverType(Never /*Never**/ o) {}
+objectType(Object /*normal.Object**/ /*verbose.dart.core::Object**/ o) {}
+genericType1(
+ List<int>
+ /*normal.List<int*>**/
+ /*verbose.dart.core::List<dart.core::int*>**/
+ o) {}
+genericType2(
+ Map<int, String>
+ /*normal.Map<int*, String*>**/
+ /*verbose.dart.core::Map<dart.core::int*, dart.core::String*>**/
+ o) {}
+typeVariableType1<T>(T /*T**/ o) {}
+typeVariableType2<T extends num>(T /*T**/ o) {}
+typeVariableType3<T extends S, S>(T /*T**/ o, S /*S**/ p) {}
+typeVariableType4<T, S extends T>(T /*T**/ o, S /*S**/ p) {}
+typeVariableType5<T extends Object>(T /*T**/ o) {}
+functionType1(void Function() /*void Function()**/ o) {}
+functionType2(
+ int Function(int)
+ /*normal.int* Function(int*)**/
+ /*verbose.dart.core::int* Function(dart.core::int*)**/
+ o) {}
+functionType3(
+ int Function(int, String)
+ /*normal.int* Function(int*, String*)**/
+ /*verbose.dart.core::int* Function(dart.core::int*, dart.core::String*)**/
+ o) {}
+functionType4(
+ int Function([int])
+ /*normal.int* Function([int*])**/
+ /*verbose.dart.core::int* Function([dart.core::int*])**/
+ o) {}
+functionType5(
+ int Function([int, String])
+ /*normal.int* Function([int*, String*])**/
+ /*verbose.dart.core::int* Function([dart.core::int*, dart.core::String*])**/
+ o) {}
+functionType6(
+ int Function({int a})
+ /*normal.int* Function({a: int*})**/
+ /*verbose.dart.core::int* Function({a: int*})**/
+ o) {}
+functionType7(
+ int Function({int a, String b})
+ /*normal.int* Function({a: int*, b: String*})**/
+ /*verbose.dart.core::int* Function({a: int*, b: String*})**/
+ o) {}
+functionType8(
+ int Function(int, {String b})
+ /*normal.int* Function(int*, {b: String*})**/
+ /*verbose.dart.core::int* Function(dart.core::int*, {b: String*})**/
+ o) {}
+functionType9(
+ int Function({int a, String b})
+ /*normal.int* Function({a: int*, b: String*})**/
+ /*verbose.dart.core::int* Function({a: int*, b: String*})**/
+ o) {}
+genericFunctionType1(void Function<T>() /*void Function<T>()**/ o) {}
+genericFunctionType2(T Function<T>(T) /*T* Function<T>(T*)**/ o) {}
+genericFunctionType3(T Function<T, S>(T, S) /*T* Function<T, S>(T*, S*)**/ o) {}
+genericFunctionType4(
+ T Function<T extends num>([T])
+ /*normal.T* Function<T extends num*>([T*])**/
+ /*verbose.T* Function<T extends dart.core::num*>([T*])**/
+ o) {}
+// TODO(johnniwinther): Support interdependent function type variables.
+//genericFunctionType5(T Function<T, S extends T>([T, S]) o) {}
+//genericFunctionType6(T Function<T extends S, S>([T, S]) o) {}
+typedefType1(Typedef1 /*normal.Typedef1**/ /*verbose.test::Typedef1**/ o) {}
+typedefType2(
+ Typedef2
+ /*normal.Typedef2<dynamic>**/
+ /*verbose.test::Typedef2<dynamic>**/
+ o) {}
+typedefType3(
+ Typedef2<int>
+ /*normal.Typedef2<int*>**/
+ /*verbose.test::Typedef2<dart.core::int*>**/
+ o) {}
+typedefType4(
+ Typedef3
+ /*normal.Typedef3**/
+ /*verbose.test::Typedef3**/
+ o) {}
+typedefType5(
+ Typedef4
+ /*normal.Typedef4<dynamic>**/
+ /*verbose.test::Typedef4<dynamic>**/
+ o) {}
+typedefType7(
+ Typedef4<int>
+ /*normal.Typedef4<int*>**/
+ /*verbose.test::Typedef4<dart.core::int*>**/
+ o) {}
+typedefType8(
+ Typedef5
+ /*normal.Typedef5<dynamic>**/
+ /*verbose.test::Typedef5<dynamic>**/
+ o) {}
+typedefType9(
+ Typedef5<int>
+ /*normal.Typedef5<int*>**/
+ /*verbose.test::Typedef5<dart.core::int*>**/
+ o) {}
+
+method() {
+ var /*dynamic Function<T>(T*)**/ o1 =
+ /*normal.typeVariableType1*/
+ /*verbose.test::typeVariableType1*/
+ typeVariableType1;
+ var /*normal.dynamic Function<T extends num*>(T*)**/
+ /*verbose.dynamic Function<T extends dart.core::num*>(T*)**/ o2 =
+ /*normal.typeVariableType2*/
+ /*verbose.test::typeVariableType2*/
+ typeVariableType2;
+ var /*dynamic Function<T extends S*, S>(T*, S*)**/ o3 =
+ /*normal.typeVariableType3*/
+ /*verbose.test::typeVariableType3*/
+ typeVariableType3;
+ var /*dynamic Function<T, S extends T*>(T*, S*)**/ o4 =
+ /*normal.typeVariableType4*/
+ /*verbose.test::typeVariableType4*/
+ typeVariableType4;
+ var /*normal.dynamic Function<T extends Object*>(T*)**/
+ /*verbose.dynamic Function<T extends dart.core::Object*>(T*)**/ o5 =
+ /*normal.typeVariableType5*/
+ /*verbose.test::typeVariableType5*/
+ typeVariableType5;
+
+ var /*dynamic*/ bottom1 = throw '';
+ var
+ // Comment inserted to ensure whitespace between 'var' and 'bottom2'; the
+ // formatter doesn't preserve the space before the annotation.
+ /*<bottom> Function()**/ bottom2 = () => throw '';
+}
diff --git a/pkg/front_end/test/text_representation/text_representation_test.dart b/pkg/front_end/test/text_representation/text_representation_test.dart
new file mode 100644
index 0000000..376423f
--- /dev/null
+++ b/pkg/front_end/test/text_representation/text_representation_test.dart
@@ -0,0 +1,100 @@
+// 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:io' show Directory, Platform;
+import 'package:_fe_analyzer_shared/src/testing/id.dart';
+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'
+ show ExperimentalFlag;
+import 'package:front_end/src/base/nnbd_mode.dart';
+import 'package:front_end/src/testing/id_testing_helper.dart';
+import 'package:kernel/ast.dart';
+
+const String normalMarker = 'normal';
+const String verboseMarker = 'verbose';
+
+main(List<String> args) async {
+ Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
+ await runTests<String>(dataDir,
+ args: args,
+ createUriForFileName: createUriForFileName,
+ onFailure: onFailure,
+ runTest: runTestFor(const TextRepresentationDataComputer(), [
+ const TextRepresentationConfig(normalMarker, 'normal'),
+ const TextRepresentationConfig(verboseMarker, 'verbose'),
+ ]));
+}
+
+class TextRepresentationConfig extends TestConfig {
+ const TextRepresentationConfig(String marker, String name)
+ : super(marker, name,
+ experimentalFlags: const {ExperimentalFlag.nonNullable: true},
+ nnbdMode: NnbdMode.Strong);
+
+ void customizeCompilerOptions(CompilerOptions options, TestData testData) {
+ if (testData.name.endsWith('_opt_out.dart')) {
+ options.nnbdMode = NnbdMode.Weak;
+ }
+ }
+}
+
+class TextRepresentationDataComputer extends DataComputer<String> {
+ const TextRepresentationDataComputer();
+
+ void computeLibraryData(
+ TestConfig config,
+ InternalCompilerResult compilerResult,
+ Library library,
+ Map<Id, ActualData<String>> actualMap,
+ {bool verbose}) {
+ new TextRepresentationDataExtractor(
+ compilerResult, actualMap, config.marker == verboseMarker)
+ .computeForLibrary(library);
+ }
+
+ @override
+ void computeMemberData(
+ TestConfig config,
+ InternalCompilerResult compilerResult,
+ Member member,
+ Map<Id, ActualData<String>> actualMap,
+ {bool verbose}) {
+ member.accept(new TextRepresentationDataExtractor(
+ compilerResult, actualMap, config.marker == verboseMarker));
+ }
+
+ @override
+ DataInterpreter<String> get dataValidator => const StringDataInterpreter();
+}
+
+class TextRepresentationDataExtractor extends CfeDataExtractor<String> {
+ final bool verbose;
+
+ TextRepresentationDataExtractor(InternalCompilerResult compilerResult,
+ Map<Id, ActualData<String>> actualMap, this.verbose)
+ : super(compilerResult, actualMap);
+
+ @override
+ String computeLibraryValue(Id id, Library node) {
+ return 'nnbd=${node.isNonNullableByDefault}';
+ }
+
+ @override
+ String computeNodeValue(Id id, TreeNode node) {
+ if (node is ConstantExpression) {
+ return node.constant.toConstantText(verbose: verbose);
+ } else if (node is VariableDeclaration) {
+ DartType type = node.type;
+ if (type is FunctionType && type.typedefType != null) {
+ return type.typedefType.toTypeText(verbose: verbose);
+ } else {
+ return type.toTypeText(verbose: verbose);
+ }
+ }
+ return null;
+ }
+}
diff --git a/pkg/front_end/testcases/agnostic/as.dart b/pkg/front_end/testcases/agnostic/as.dart
new file mode 100644
index 0000000..3c26cd7
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/as.dart
@@ -0,0 +1,8 @@
+// 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.
+
+const a = <Null>[] as List<int>;
+const b = <int?>[] as List<int>;
+
+void main() {}
diff --git a/pkg/front_end/testcases/agnostic/as.dart.outline.expect b/pkg/front_end/testcases/agnostic/as.dart.outline.expect
new file mode 100644
index 0000000..46f9ad3
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/as.dart.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::List<core::int> a = const <core::Null?>[] as{ForNonNullableByDefault} core::List<core::int>;
+static const field core::List<core::int> b = const <core::int?>[] as{ForNonNullableByDefault} core::List<core::int>;
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/agnostic/as.dart.strong.expect b/pkg/front_end/testcases/agnostic/as.dart.strong.expect
new file mode 100644
index 0000000..a8f9bcc
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/as.dart.strong.expect
@@ -0,0 +1,30 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/agnostic/as.dart:5:20: Error: Constant evaluation error:
+// const a = <Null>[] as List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/as.dart:5:20: Context: Constant value is not strong/weak mode agnostic.
+// const a = <Null>[] as List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/as.dart:5:7: Context: While analyzing:
+// const a = <Null>[] as List<int>;
+// ^
+//
+// pkg/front_end/testcases/agnostic/as.dart:6:20: Error: Constant evaluation error:
+// const b = <int?>[] as List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/as.dart:6:20: Context: Constant value is not strong/weak mode agnostic.
+// const b = <int?>[] as List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/as.dart:6:7: Context: While analyzing:
+// const b = <int?>[] as List<int>;
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::List<core::int> a = invalid-expression "Constant value is not strong/weak mode agnostic.";
+static const field core::List<core::int> b = invalid-expression "Constant value is not strong/weak mode agnostic.";
+static method main() → void {}
diff --git a/pkg/front_end/testcases/agnostic/as.dart.strong.transformed.expect b/pkg/front_end/testcases/agnostic/as.dart.strong.transformed.expect
new file mode 100644
index 0000000..a8f9bcc
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/as.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/agnostic/as.dart:5:20: Error: Constant evaluation error:
+// const a = <Null>[] as List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/as.dart:5:20: Context: Constant value is not strong/weak mode agnostic.
+// const a = <Null>[] as List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/as.dart:5:7: Context: While analyzing:
+// const a = <Null>[] as List<int>;
+// ^
+//
+// pkg/front_end/testcases/agnostic/as.dart:6:20: Error: Constant evaluation error:
+// const b = <int?>[] as List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/as.dart:6:20: Context: Constant value is not strong/weak mode agnostic.
+// const b = <int?>[] as List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/as.dart:6:7: Context: While analyzing:
+// const b = <int?>[] as List<int>;
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::List<core::int> a = invalid-expression "Constant value is not strong/weak mode agnostic.";
+static const field core::List<core::int> b = invalid-expression "Constant value is not strong/weak mode agnostic.";
+static method main() → void {}
diff --git a/pkg/front_end/testcases/agnostic/as.dart.textual_outline.expect b/pkg/front_end/testcases/agnostic/as.dart.textual_outline.expect
new file mode 100644
index 0000000..8f8ac90
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/as.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+const a = <Null>[] as List<int>;
+const b = <int?>[] as List<int>;
+void main() {}
diff --git a/pkg/front_end/testcases/agnostic/as.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/agnostic/as.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f8ac90
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/as.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+const a = <Null>[] as List<int>;
+const b = <int?>[] as List<int>;
+void main() {}
diff --git a/pkg/front_end/testcases/agnostic/as.dart.weak.expect b/pkg/front_end/testcases/agnostic/as.dart.weak.expect
new file mode 100644
index 0000000..cc4ac88
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/as.dart.weak.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::List<core::int> a = #C1;
+static const field core::List<core::int> b = #C2;
+static method main() → void {}
+
+constants {
+ #C1 = <core::Null?>[]
+ #C2 = <core::int*>[]
+}
diff --git a/pkg/front_end/testcases/agnostic/as.dart.weak.transformed.expect b/pkg/front_end/testcases/agnostic/as.dart.weak.transformed.expect
new file mode 100644
index 0000000..cc4ac88
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/as.dart.weak.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::List<core::int> a = #C1;
+static const field core::List<core::int> b = #C2;
+static method main() → void {}
+
+constants {
+ #C1 = <core::Null?>[]
+ #C2 = <core::int*>[]
+}
diff --git a/pkg/front_end/testcases/agnostic/is.dart b/pkg/front_end/testcases/agnostic/is.dart
new file mode 100644
index 0000000..20aac80
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/is.dart
@@ -0,0 +1,8 @@
+// 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.
+
+const a = <Null>[] is List<int>;
+const b = <int?>[] is List<int>;
+
+void main() {}
diff --git a/pkg/front_end/testcases/agnostic/is.dart.outline.expect b/pkg/front_end/testcases/agnostic/is.dart.outline.expect
new file mode 100644
index 0000000..d8d8870
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/is.dart.outline.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::bool a = const <core::Null?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool b = const <core::int?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/agnostic/is.dart.strong.expect b/pkg/front_end/testcases/agnostic/is.dart.strong.expect
new file mode 100644
index 0000000..4686996
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/is.dart.strong.expect
@@ -0,0 +1,30 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/agnostic/is.dart:5:20: Error: Constant evaluation error:
+// const a = <Null>[] is List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/is.dart:5:20: Context: Constant value is not strong/weak mode agnostic.
+// const a = <Null>[] is List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/is.dart:5:7: Context: While analyzing:
+// const a = <Null>[] is List<int>;
+// ^
+//
+// pkg/front_end/testcases/agnostic/is.dart:6:20: Error: Constant evaluation error:
+// const b = <int?>[] is List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/is.dart:6:20: Context: Constant value is not strong/weak mode agnostic.
+// const b = <int?>[] is List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/is.dart:6:7: Context: While analyzing:
+// const b = <int?>[] is List<int>;
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::bool a = invalid-expression "Constant value is not strong/weak mode agnostic.";
+static const field core::bool b = invalid-expression "Constant value is not strong/weak mode agnostic.";
+static method main() → void {}
diff --git a/pkg/front_end/testcases/agnostic/is.dart.strong.transformed.expect b/pkg/front_end/testcases/agnostic/is.dart.strong.transformed.expect
new file mode 100644
index 0000000..4686996
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/is.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/agnostic/is.dart:5:20: Error: Constant evaluation error:
+// const a = <Null>[] is List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/is.dart:5:20: Context: Constant value is not strong/weak mode agnostic.
+// const a = <Null>[] is List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/is.dart:5:7: Context: While analyzing:
+// const a = <Null>[] is List<int>;
+// ^
+//
+// pkg/front_end/testcases/agnostic/is.dart:6:20: Error: Constant evaluation error:
+// const b = <int?>[] is List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/is.dart:6:20: Context: Constant value is not strong/weak mode agnostic.
+// const b = <int?>[] is List<int>;
+// ^
+// pkg/front_end/testcases/agnostic/is.dart:6:7: Context: While analyzing:
+// const b = <int?>[] is List<int>;
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::bool a = invalid-expression "Constant value is not strong/weak mode agnostic.";
+static const field core::bool b = invalid-expression "Constant value is not strong/weak mode agnostic.";
+static method main() → void {}
diff --git a/pkg/front_end/testcases/agnostic/is.dart.textual_outline.expect b/pkg/front_end/testcases/agnostic/is.dart.textual_outline.expect
new file mode 100644
index 0000000..a06a494
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/is.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+const a = <Null>[] is List<int>;
+const b = <int?>[] is List<int>;
+void main() {}
diff --git a/pkg/front_end/testcases/agnostic/is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/agnostic/is.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a06a494
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/is.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+const a = <Null>[] is List<int>;
+const b = <int?>[] is List<int>;
+void main() {}
diff --git a/pkg/front_end/testcases/agnostic/is.dart.weak.expect b/pkg/front_end/testcases/agnostic/is.dart.weak.expect
new file mode 100644
index 0000000..b52395a
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/is.dart.weak.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::bool a = #C1;
+static const field core::bool b = #C1;
+static method main() → void {}
+
+constants {
+ #C1 = true
+}
diff --git a/pkg/front_end/testcases/agnostic/is.dart.weak.transformed.expect b/pkg/front_end/testcases/agnostic/is.dart.weak.transformed.expect
new file mode 100644
index 0000000..b52395a
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/is.dart.weak.transformed.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static const field core::bool a = #C1;
+static const field core::bool b = #C1;
+static method main() → void {}
+
+constants {
+ #C1 = true
+}
diff --git a/pkg/front_end/testcases/general/bug32414a.dart b/pkg/front_end/testcases/general/bug32414a.dart
index 282c07d..7313a04 100644
--- a/pkg/front_end/testcases/general/bug32414a.dart
+++ b/pkg/front_end/testcases/general/bug32414a.dart
@@ -6,7 +6,7 @@
void test() {
dynamic a = 5;
- var /*@ type=String* */ b = a. /*@target=Object::toString*/ toString();
+ var /*@ type=String* */ b = a. /*@target=Object.toString*/ toString();
b = 42;
}
diff --git a/pkg/front_end/testcases/general/bug32414b.dart b/pkg/front_end/testcases/general/bug32414b.dart
index d1c0f38..b1cff49 100644
--- a/pkg/front_end/testcases/general/bug32414b.dart
+++ b/pkg/front_end/testcases/general/bug32414b.dart
@@ -7,10 +7,10 @@
void test() {
List<dynamic> l = /*@ typeArgs=dynamic */ [1, "hello"];
List<String> l2 = l
- . /*@target=Iterable::map*/ /*@ typeArgs=String* */ map(
+ . /*@target=Iterable.map*/ /*@ typeArgs=String* */ map(
/*@ returnType=String* */ (dynamic element) =>
- element. /*@target=Object::toString*/ toString())
- . /*@target=Iterable::toList*/ toList();
+ element. /*@target=Object.toString*/ toString())
+ . /*@target=Iterable.toList*/ toList();
}
void main() {}
diff --git a/pkg/front_end/testcases/general/casts.dart.strong.transformed.expect b/pkg/front_end/testcases/general/casts.dart.strong.transformed.expect
index bfac5fe..4ea32aa 100644
--- a/pkg/front_end/testcases/general/casts.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/casts.dart.strong.transformed.expect
@@ -3,9 +3,9 @@
import "dart:core" as core;
static method main() → dynamic {
- core::print("" as core::String*);
- core::print(1 as core::int*);
- core::print(1.0 as core::double*);
+ core::print("");
+ core::print(1);
+ core::print(1.0);
core::print("" is core::String*);
core::print("" is core::int*);
core::print("" is core::double*);
diff --git a/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.strong.transformed.expect
index 29ca0a2..fe4b5c9 100644
--- a/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.strong.transformed.expect
@@ -46,7 +46,7 @@
constructor •() → self::C2*
: self::C2::f = invalid-expression "pkg/front_end/testcases/general/constructor_initializer_invalid.dart:6:27: Error: This couldn't be parsed.
class C2 { int f; C2() : f; }
- ^" as{TypeError,ForDynamic} core::int*, super core::Object::•()
+ ^", super core::Object::•()
;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
index 1d1f3af..901cb0b 100644
--- a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
@@ -34,7 +34,7 @@
{
asy::Stream<dynamic>* :stream = invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: This couldn't be parsed.
await for () {}
- ^" as{TypeError,ForDynamic} asy::Stream<dynamic>*;
+ ^";
asy::_asyncStarListenHelper(:stream, :async_op);
asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
try
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.transformed.expect
index 3bb7f2e..c360df17 100644
--- a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.strong.transformed.expect
@@ -11,13 +11,12 @@
// ^
//
import self as self;
-import "dart:core" as core;
static method main() → dynamic {
for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: This couldn't be parsed.
for () {}
^"; invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_for.dart:2:8: Error: This couldn't be parsed.
for () {}
- ^" as{TypeError,ForDynamic} core::bool*; ) {
+ ^"; ) {
}
}
diff --git a/pkg/front_end/testcases/general/invalid_cast.dart.strong.transformed.expect b/pkg/front_end/testcases/general/invalid_cast.dart.strong.transformed.expect
index 56a7924..dd98ed3 100644
--- a/pkg/front_end/testcases/general/invalid_cast.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/invalid_cast.dart.strong.transformed.expect
@@ -123,7 +123,7 @@
int Function(Object) d = (int i) => i;
^" in (core::int* i) → core::int* => i;
self::D* e = self::C::fact() as{TypeError} self::D*;
- self::D* f = new self::D::•() as{TypeError} self::D*;
+ self::D* f = new self::D::•();
self::D* g = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:26:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
- 'C' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
- 'D' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
@@ -159,7 +159,7 @@
core::Map<core::int*, core::String*>* c = <core::int*, core::String*>{};
(core::int*) →* core::int* d = (core::int* i) → core::int* => i;
self::D* e = self::C::fact() as{TypeError} self::D*;
- self::D* f = new self::D::•() as{TypeError} self::D*;
+ self::D* f = new self::D::•();
self::C* g = new self::C::nonFact();
self::C* h = new self::C::nonFact2();
(core::int*) →* void i = #C1;
diff --git a/pkg/front_end/testcases/general/invocations.dart.strong.transformed.expect b/pkg/front_end/testcases/general/invocations.dart.strong.transformed.expect
index 4be4068..ccec25c 100644
--- a/pkg/front_end/testcases/general/invocations.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/invocations.dart.strong.transformed.expect
@@ -59,7 +59,7 @@
print(\"Hello, World!\") +
^" in core::print("Hello, World!")).{core::num::+}(invalid-expression "pkg/front_end/testcases/general/invocations.dart:14:7: Error: Method not found: 'z'.
z(\"Hello, World!\") +
- ^" as{TypeError,ForDynamic} core::num).{core::num::+}(invalid-expression "pkg/front_end/testcases/general/invocations.dart:15:7: Error: Getter not found: 'z'.
+ ^").{core::num::+}(invalid-expression "pkg/front_end/testcases/general/invocations.dart:15:7: Error: Getter not found: 'z'.
z.print(\"Hello, World!\") +
^".print("Hello, World!") as{TypeError,ForDynamic} core::num).{core::num::+}(invalid-expression "pkg/front_end/testcases/general/invocations.dart:16:7: Error: Getter not found: 'y'.
y.z.print(\"Hello, World!\") +
diff --git a/pkg/front_end/testcases/general/missing_toplevel.dart.strong.transformed.expect b/pkg/front_end/testcases/general/missing_toplevel.dart.strong.transformed.expect
index ab8e70e..54a46b2 100644
--- a/pkg/front_end/testcases/general/missing_toplevel.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/missing_toplevel.dart.strong.transformed.expect
@@ -107,7 +107,7 @@
- 'EmptyClass' is from 'pkg/front_end/testcases/general/missing_toplevel.dart'.
Try correcting the operator to an existing operator, or defining a '+' operator.
var missingBinary = classWithProperty.property += 2;
- ^" as{TypeError,ForDynamic} self::EmptyClass*;
+ ^";
static field dynamic missingIndexGet = let final self::ClassWithIndexSet* #t2 = self::classWithIndexSet in let final core::int* #t3 = 0 in let final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/missing_toplevel.dart:28:40: Error: The operator '[]' isn't defined for the class 'ClassWithIndexSet'.
- 'ClassWithIndexSet' is from 'pkg/front_end/testcases/general/missing_toplevel.dart'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
index 8af7971..8f25fea 100644
--- a/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
@@ -147,7 +147,7 @@
{
self::V* V = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:47:7: Error: Can't declare 'V' because it was already used in this scope.
V V;
- ^" as{TypeError,ForDynamic} self::V*;
+ ^";
}
{
<T extends core::Object* = dynamic>() →* core::Null? x = let final dynamic #t3 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:52:13: Error: 'T' is already declared in this scope.
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart.strong.transformed.expect b/pkg/front_end/testcases/general/nested_property_set.dart.strong.transformed.expect
index 7fb3f49..ab06de5 100644
--- a/pkg/front_end/testcases/general/nested_property_set.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/nested_property_set.dart.strong.transformed.expect
@@ -55,7 +55,7 @@
self::IntField* intField2 = new self::IntField::•();
self::NumField* numField = new self::NumField::•();
self::DoubleField* doubleField = new self::DoubleField::•();
- intField1.{self::IntField::field} = (intField2.{self::IntField::field} = numField.{self::NumField::field} as{TypeError} core::int*) as{TypeError} core::int*;
+ intField1.{self::IntField::field} = intField2.{self::IntField::field} = numField.{self::NumField::field} as{TypeError} core::int*;
intField1.{self::IntField::field} = numField.{self::NumField::field} = intField2.{self::IntField::field};
try {
numField.{self::NumField::field} = 0.5;
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.strong.transformed.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.strong.transformed.expect
index 7e193c1..18a252a 100644
--- a/pkg/front_end/testcases/general/nested_variable_set.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
core::int* intLocal2;
core::num* numLocal;
core::double* doubleLocal;
- intLocal1 = (intLocal2 = numLocal as{TypeError} core::int*) as{TypeError} core::int*;
+ intLocal1 = intLocal2 = numLocal as{TypeError} core::int*;
intLocal1 = numLocal = intLocal2;
numLocal = 0.5;
try {
diff --git a/pkg/front_end/testcases/general/super_call.dart.strong.transformed.expect b/pkg/front_end/testcases/general/super_call.dart.strong.transformed.expect
index 19f23ea..da9924e 100644
--- a/pkg/front_end/testcases/general/super_call.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/super_call.dart.strong.transformed.expect
@@ -37,7 +37,7 @@
return invalid-expression "pkg/front_end/testcases/general/super_call.dart:14:12: Error: Can't use 'super' as an expression.
To delegate a constructor to a super constructor, put the super call as an initializer.
return super(5);
- ^" as{TypeError,ForDynamic} core::int*;
+ ^";
}
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/link.options b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/link.options
new file mode 100644
index 0000000..f153ea0
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/link.options
@@ -0,0 +1 @@
+mixin_from_dill_lib1.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart
new file mode 100644
index 0000000..9f8234d
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart
@@ -0,0 +1,17 @@
+// 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 "mixin_from_dill_lib1.dart" as lib1;
+import "mixin_from_dill_lib2.dart" as lib2;
+
+main() {
+ lib1.Foo foo1 = new lib1.Foo();
+ if (foo1 == null) throw "what?";
+ if (!(foo1 == foo1)) throw "what?";
+ foo1.x();
+ lib2.Foo foo2 = new lib2.Foo();
+ if (foo2 == null) throw "what?";
+ if (!(foo2 == foo2)) throw "what?";
+ foo2.x();
+}
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..9887e21
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "mixin_from_dill_lib1.dart" as lib1;
+import "mixin_from_dill_lib2.dart" as lib2;
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9887e21
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "mixin_from_dill_lib1.dart" as lib1;
+import "mixin_from_dill_lib2.dart" as lib2;
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart
new file mode 100644
index 0000000..38ee449
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart
@@ -0,0 +1,25 @@
+// 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.
+
+class Foo extends B with D {}
+abstract class B implements C {
+ bool operator==(dynamic) {
+ print("B.==");
+ return true;
+ }
+ void x() {
+ print("B.x");
+ }
+}
+abstract class C {}
+abstract class D implements C {
+ bool operator==(dynamic) {
+ print("D.==");
+ return true;
+ }
+
+ void x() {
+ print("D.x");
+ }
+}
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.outline.expect b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.outline.expect
new file mode 100644
index 0000000..5fecce1
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.outline.expect
@@ -0,0 +1,132 @@
+library;
+import self as self;
+
+import "org-dartlang-testcase:///mixin_from_dill_lib1.dart" as lib1;
+import "org-dartlang-testcase:///mixin_from_dill_lib2.dart" as lib2;
+
+static method main() → dynamic
+ ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+abstract class _Foo&B&D = self2::B with self2::D /*isAnonymousMixin*/ {
+ synthetic constructor •() → self2::_Foo&B&D*
+ : super self2::B::•()
+ ;
+}
+class Foo extends self2::_Foo&B&D {
+ synthetic constructor •() → self2::Foo*
+ ;
+}
+abstract class B extends core::Object implements self2::C {
+ synthetic constructor •() → self2::B*
+ ;
+ operator ==(dynamic dynamic) → core::bool*
+ ;
+ method x() → void
+ ;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class C extends core::Object {
+ synthetic constructor •() → self2::C*
+ ;
+ abstract member-signature operator ==(dynamic other) → core::bool*;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class D extends core::Object implements self2::C {
+ synthetic constructor •() → self2::D*
+ ;
+ operator ==(dynamic dynamic) → core::bool*
+ ;
+ method x() → void
+ ;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+abstract class _Foo&B&D = self3::B with self3::D /*isAnonymousMixin*/ {
+ synthetic constructor •() → self3::_Foo&B&D*
+ : super self3::B::•()
+ ;
+}
+class Foo extends self3::_Foo&B&D {
+ synthetic constructor •() → self3::Foo*
+ ;
+}
+abstract class B extends core::Object implements self3::C {
+ synthetic constructor •() → self3::B*
+ ;
+ operator ==(dynamic dynamic) → core::bool*
+ ;
+ method x() → void
+ ;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class C extends core::Object {
+ synthetic constructor •() → self3::C*
+ ;
+ abstract member-signature operator ==(dynamic other) → core::bool*;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class D extends core::Object implements self3::C {
+ synthetic constructor •() → self3::D*
+ ;
+ operator ==(dynamic dynamic) → core::bool*
+ ;
+ method x() → void
+ ;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.strong.expect b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.strong.expect
new file mode 100644
index 0000000..b8e0c04
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.strong.expect
@@ -0,0 +1,166 @@
+library;
+import self as self;
+import "mixin_from_dill_lib1.dart" as mix;
+import "mixin_from_dill_lib2.dart" as mix2;
+
+import "org-dartlang-testcase:///mixin_from_dill_lib1.dart" as lib1;
+import "org-dartlang-testcase:///mixin_from_dill_lib2.dart" as lib2;
+
+static method main() → dynamic {
+ mix::Foo* foo1 = new mix::Foo::•();
+ if(foo1.{mix::D::==}(null))
+ throw "what?";
+ if(!foo1.{mix::D::==}(foo1))
+ throw "what?";
+ foo1.{mix::D::x}();
+ mix2::Foo* foo2 = new mix2::Foo::•();
+ if(foo2.{mix2::D::==}(null))
+ throw "what?";
+ if(!foo2.{mix2::D::==}(foo2))
+ throw "what?";
+ foo2.{mix2::D::x}();
+}
+
+library;
+import self as mix2;
+import "dart:core" as core;
+
+abstract class _Foo&B&D = mix2::B with mix2::D /*isAnonymousMixin*/ {
+ synthetic constructor •() → mix2::_Foo&B&D*
+ : super mix2::B::•()
+ ;
+}
+class Foo extends mix2::_Foo&B&D {
+ synthetic constructor •() → mix2::Foo*
+ : super mix2::_Foo&B&D::•()
+ ;
+}
+abstract class B extends core::Object implements mix2::C {
+ synthetic constructor •() → mix2::B*
+ : super core::Object::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("B.==");
+ return true;
+ }
+ method x() → void {
+ core::print("B.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class C extends core::Object {
+ synthetic constructor •() → mix2::C*
+ : super core::Object::•()
+ ;
+ abstract member-signature operator ==(dynamic other) → core::bool*;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class D extends core::Object implements mix2::C {
+ synthetic constructor •() → mix2::D*
+ : super core::Object::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("D.==");
+ return true;
+ }
+ method x() → void {
+ core::print("D.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+
+library;
+import self as mix;
+import "dart:core" as core;
+
+abstract class _Foo&B&D = mix::B with mix::D /*isAnonymousMixin*/ {
+ synthetic constructor •() → mix::_Foo&B&D*
+ : super mix::B::•()
+ ;
+}
+class Foo extends mix::_Foo&B&D {
+ synthetic constructor •() → mix::Foo*
+ : super mix::_Foo&B&D::•()
+ ;
+}
+abstract class B extends core::Object implements mix::C {
+ synthetic constructor •() → mix::B*
+ : super core::Object::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("B.==");
+ return true;
+ }
+ method x() → void {
+ core::print("B.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class C extends core::Object {
+ synthetic constructor •() → mix::C*
+ : super core::Object::•()
+ ;
+ abstract member-signature operator ==(dynamic other) → core::bool*;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class D extends core::Object implements mix::C {
+ synthetic constructor •() → mix::D*
+ : super core::Object::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("D.==");
+ return true;
+ }
+ method x() → void {
+ core::print("D.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.strong.transformed.expect b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.strong.transformed.expect
new file mode 100644
index 0000000..15b0ec5
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib1.dart.strong.transformed.expect
@@ -0,0 +1,182 @@
+library;
+import self as self;
+import "mixin_from_dill_lib1.dart" as mix;
+import "mixin_from_dill_lib2.dart" as mix2;
+
+import "org-dartlang-testcase:///mixin_from_dill_lib1.dart" as lib1;
+import "org-dartlang-testcase:///mixin_from_dill_lib2.dart" as lib2;
+
+static method main() → dynamic {
+ mix::Foo* foo1 = new mix::Foo::•();
+ if(foo1.{mix::D::==}(null))
+ throw "what?";
+ if(!foo1.{mix::D::==}(foo1))
+ throw "what?";
+ foo1.{mix::D::x}();
+ mix2::Foo* foo2 = new mix2::Foo::•();
+ if(foo2.{mix2::D::==}(null))
+ throw "what?";
+ if(!foo2.{mix2::D::==}(foo2))
+ throw "what?";
+ foo2.{mix2::D::x}();
+}
+
+library;
+import self as mix2;
+import "dart:core" as core;
+
+abstract class _Foo&B&D extends mix2::B implements mix2::D /*isAnonymousMixin,isEliminatedMixin*/ {
+ synthetic constructor •() → mix2::_Foo&B&D*
+ : super mix2::B::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("D.==");
+ return true;
+ }
+ method x() → void {
+ core::print("D.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+class Foo extends mix2::_Foo&B&D {
+ synthetic constructor •() → mix2::Foo*
+ : super mix2::_Foo&B&D::•()
+ ;
+}
+abstract class B extends core::Object implements mix2::C {
+ synthetic constructor •() → mix2::B*
+ : super core::Object::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("B.==");
+ return true;
+ }
+ method x() → void {
+ core::print("B.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class C extends core::Object {
+ synthetic constructor •() → mix2::C*
+ : super core::Object::•()
+ ;
+ abstract member-signature operator ==(dynamic other) → core::bool*;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class D extends core::Object implements mix2::C {
+ synthetic constructor •() → mix2::D*
+ : super core::Object::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("D.==");
+ return true;
+ }
+ method x() → void {
+ core::print("D.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+
+library;
+import self as mix;
+import "dart:core" as core;
+
+abstract class _Foo&B&D = mix::B with mix::D /*isAnonymousMixin*/ {
+ synthetic constructor •() → mix::_Foo&B&D*
+ : super mix::B::•()
+ ;
+}
+class Foo extends mix::_Foo&B&D {
+ synthetic constructor •() → mix::Foo*
+ : super mix::_Foo&B&D::•()
+ ;
+}
+abstract class B extends core::Object implements mix::C {
+ synthetic constructor •() → mix::B*
+ : super core::Object::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("B.==");
+ return true;
+ }
+ method x() → void {
+ core::print("B.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class C extends core::Object {
+ synthetic constructor •() → mix::C*
+ : super core::Object::•()
+ ;
+ abstract member-signature operator ==(dynamic other) → core::bool*;
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
+abstract class D extends core::Object implements mix::C {
+ synthetic constructor •() → mix::D*
+ : super core::Object::•()
+ ;
+ operator ==(dynamic dynamic) → core::bool* {
+ core::print("D.==");
+ return true;
+ }
+ method x() → void {
+ core::print("D.x");
+ }
+ abstract member-signature get _identityHashCode() → core::int*;
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+ abstract member-signature get hashCode() → core::int*;
+ abstract member-signature method toString() → core::String*;
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+ abstract member-signature get runtimeType() → core::Type*;
+}
diff --git a/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib2.dart b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib2.dart
new file mode 100644
index 0000000..38ee449
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/mixin_from_dill/mixin_from_dill_lib2.dart
@@ -0,0 +1,25 @@
+// 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.
+
+class Foo extends B with D {}
+abstract class B implements C {
+ bool operator==(dynamic) {
+ print("B.==");
+ return true;
+ }
+ void x() {
+ print("B.x");
+ }
+}
+abstract class C {}
+abstract class D implements C {
+ bool operator==(dynamic) {
+ print("D.==");
+ return true;
+ }
+
+ void x() {
+ print("D.x");
+ }
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart
index 36c8676..7eda380 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart
@@ -8,7 +8,7 @@
void test() {
dynamic a = 5;
- var /*@ type=String* */ b = a. /*@target=Object::toString*/ toString();
+ var /*@ type=String* */ b = a. /*@target=Object.toString*/ toString();
b = 42;
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart
index ad7ba7d..bee2cb3 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart
@@ -9,10 +9,10 @@
void test() {
List<dynamic> l = /*@ typeArgs=dynamic */ [1, "hello"];
List<String> l2 = l
- . /*@target=Iterable::map*/ /*@ typeArgs=String* */ map(
+ . /*@target=Iterable.map*/ /*@ typeArgs=String* */ map(
/*@ returnType=String* */ (dynamic element) =>
- element. /*@target=Object::toString*/ toString())
- . /*@target=Iterable::toList*/ toList();
+ element. /*@target=Object.toString*/ toString())
+ . /*@target=Iterable.toList*/ toList();
}
void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.strong.transformed.expect
index bfac5fe..4ea32aa 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.strong.transformed.expect
@@ -3,9 +3,9 @@
import "dart:core" as core;
static method main() → dynamic {
- core::print("" as core::String*);
- core::print(1 as core::int*);
- core::print(1.0 as core::double*);
+ core::print("");
+ core::print(1);
+ core::print(1.0);
core::print("" is core::String*);
core::print("" is core::int*);
core::print("" is core::double*);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.weak.transformed.expect
index bfac5fe..4ea32aa 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.weak.transformed.expect
@@ -3,9 +3,9 @@
import "dart:core" as core;
static method main() → dynamic {
- core::print("" as core::String*);
- core::print(1 as core::int*);
- core::print(1.0 as core::double*);
+ core::print("");
+ core::print(1);
+ core::print(1.0);
core::print("" is core::String*);
core::print("" is core::int*);
core::print("" is core::double*);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.strong.transformed.expect
index 2b933e4..9c83963 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.strong.transformed.expect
@@ -46,7 +46,7 @@
constructor •() → self::C2*
: self::C2::f = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart:8:27: Error: This couldn't be parsed.
class C2 { int f; C2() : f; }
- ^" as{TypeError,ForDynamic} core::int*, super core::Object::•()
+ ^", super core::Object::•()
;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.weak.transformed.expect
index 2b933e4..9c83963 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.weak.transformed.expect
@@ -46,7 +46,7 @@
constructor •() → self::C2*
: self::C2::f = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart:8:27: Error: This couldn't be parsed.
class C2 { int f; C2() : f; }
- ^" as{TypeError,ForDynamic} core::int*, super core::Object::•()
+ ^", super core::Object::•()
;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.strong.transformed.expect
index f38cde5..58ca16f 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.strong.transformed.expect
@@ -123,7 +123,7 @@
int Function(Object) d = (int i) => i;
^" in (core::int* i) → core::int* => i;
self::D* e = self::C::fact() as{TypeError} self::D*;
- self::D* f = new self::D::•() as{TypeError} self::D*;
+ self::D* f = new self::D::•();
self::D* g = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart:28:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
- 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart'.
- 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart'.
@@ -159,7 +159,7 @@
core::Map<core::int*, core::String*>* c = <core::int*, core::String*>{};
(core::int*) →* core::int* d = (core::int* i) → core::int* => i;
self::D* e = self::C::fact() as{TypeError} self::D*;
- self::D* f = new self::D::•() as{TypeError} self::D*;
+ self::D* f = new self::D::•();
self::C* g = new self::C::nonFact();
self::C* h = new self::C::nonFact2();
(core::int*) →* void i = #C1;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.weak.transformed.expect
index f38cde5..58ca16f 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.weak.transformed.expect
@@ -123,7 +123,7 @@
int Function(Object) d = (int i) => i;
^" in (core::int* i) → core::int* => i;
self::D* e = self::C::fact() as{TypeError} self::D*;
- self::D* f = new self::D::•() as{TypeError} self::D*;
+ self::D* f = new self::D::•();
self::D* g = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart:28:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
- 'C' is from 'pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart'.
- 'D' is from 'pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart'.
@@ -159,7 +159,7 @@
core::Map<core::int*, core::String*>* c = <core::int*, core::String*>{};
(core::int*) →* core::int* d = (core::int* i) → core::int* => i;
self::D* e = self::C::fact() as{TypeError} self::D*;
- self::D* f = new self::D::•() as{TypeError} self::D*;
+ self::D* f = new self::D::•();
self::C* g = new self::C::nonFact();
self::C* h = new self::C::nonFact2();
(core::int*) →* void i = #C1;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.strong.transformed.expect
index 3566c3d..93219c5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.strong.transformed.expect
@@ -59,11 +59,11 @@
print(\"Hello, World!\") +
^" in core::print("Hello, World!")).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:16:7: Error: Method not found: 'z'.
z(\"Hello, World!\") +
- ^" as{TypeError,ForDynamic} core::num).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:17:7: Error: Getter not found: 'z'.
+ ^").{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:17:7: Error: Getter not found: 'z'.
z.print(\"Hello, World!\") +
- ^".print("Hello, World!") as{TypeError,ForDynamic} core::num).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:18:7: Error: Getter not found: 'y'.
+ ^".print("Hello, World!") as{TypeError,ForDynamic} core::num*).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:18:7: Error: Getter not found: 'y'.
y.z.print(\"Hello, World!\") +
- ^".z.print("Hello, World!") as{TypeError,ForDynamic} core::num).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:19:7: Error: Getter not found: 'x'.
+ ^".z.print("Hello, World!") as{TypeError,ForDynamic} core::num*).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:19:7: Error: Getter not found: 'x'.
x.y.z.print(\"Hello, World!\");
- ^".y.z.print("Hello, World!") as{TypeError,ForDynamic} core::num);
+ ^".y.z.print("Hello, World!") as{TypeError,ForDynamic} core::num*);
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.weak.transformed.expect
index 3566c3d..6643440 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.weak.transformed.expect
@@ -59,7 +59,7 @@
print(\"Hello, World!\") +
^" in core::print("Hello, World!")).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:16:7: Error: Method not found: 'z'.
z(\"Hello, World!\") +
- ^" as{TypeError,ForDynamic} core::num).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:17:7: Error: Getter not found: 'z'.
+ ^").{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:17:7: Error: Getter not found: 'z'.
z.print(\"Hello, World!\") +
^".print("Hello, World!") as{TypeError,ForDynamic} core::num).{core::num::+}(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart:18:7: Error: Getter not found: 'y'.
y.z.print(\"Hello, World!\") +
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.strong.transformed.expect
index 1bb64ab..60d18f0 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.strong.transformed.expect
@@ -107,7 +107,7 @@
- 'EmptyClass' is from 'pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart'.
Try correcting the operator to an existing operator, or defining a '+' operator.
var missingBinary = classWithProperty.property += 2;
- ^" as{TypeError,ForDynamic} self::EmptyClass*;
+ ^";
static field dynamic missingIndexGet = let final self::ClassWithIndexSet* #t2 = self::classWithIndexSet in let final core::int* #t3 = 0 in let final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart:30:40: Error: The operator '[]' isn't defined for the class 'ClassWithIndexSet'.
- 'ClassWithIndexSet' is from 'pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.weak.transformed.expect
index 1bb64ab..60d18f0 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.weak.transformed.expect
@@ -107,7 +107,7 @@
- 'EmptyClass' is from 'pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart'.
Try correcting the operator to an existing operator, or defining a '+' operator.
var missingBinary = classWithProperty.property += 2;
- ^" as{TypeError,ForDynamic} self::EmptyClass*;
+ ^";
static field dynamic missingIndexGet = let final self::ClassWithIndexSet* #t2 = self::classWithIndexSet in let final core::int* #t3 = 0 in let final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart:30:40: Error: The operator '[]' isn't defined for the class 'ClassWithIndexSet'.
- 'ClassWithIndexSet' is from 'pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.strong.transformed.expect
index 153f961..969df35 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.strong.transformed.expect
@@ -147,7 +147,7 @@
{
self::V* V = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart:49:7: Error: Can't declare 'V' because it was already used in this scope.
V V;
- ^" as{TypeError,ForDynamic} self::V*;
+ ^";
}
{
<T extends core::Object* = dynamic>() →* core::Null? x = let final dynamic #t3 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart:54:13: Error: 'T' is already declared in this scope.
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.weak.transformed.expect
index 153f961..969df35 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.weak.transformed.expect
@@ -147,7 +147,7 @@
{
self::V* V = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart:49:7: Error: Can't declare 'V' because it was already used in this scope.
V V;
- ^" as{TypeError,ForDynamic} self::V*;
+ ^";
}
{
<T extends core::Object* = dynamic>() →* core::Null? x = let final dynamic #t3 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart:54:13: Error: 'T' is already declared in this scope.
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.strong.transformed.expect
index 7fb3f49..ab06de5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.strong.transformed.expect
@@ -55,7 +55,7 @@
self::IntField* intField2 = new self::IntField::•();
self::NumField* numField = new self::NumField::•();
self::DoubleField* doubleField = new self::DoubleField::•();
- intField1.{self::IntField::field} = (intField2.{self::IntField::field} = numField.{self::NumField::field} as{TypeError} core::int*) as{TypeError} core::int*;
+ intField1.{self::IntField::field} = intField2.{self::IntField::field} = numField.{self::NumField::field} as{TypeError} core::int*;
intField1.{self::IntField::field} = numField.{self::NumField::field} = intField2.{self::IntField::field};
try {
numField.{self::NumField::field} = 0.5;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.weak.transformed.expect
index 7fb3f49..ab06de5 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.weak.transformed.expect
@@ -55,7 +55,7 @@
self::IntField* intField2 = new self::IntField::•();
self::NumField* numField = new self::NumField::•();
self::DoubleField* doubleField = new self::DoubleField::•();
- intField1.{self::IntField::field} = (intField2.{self::IntField::field} = numField.{self::NumField::field} as{TypeError} core::int*) as{TypeError} core::int*;
+ intField1.{self::IntField::field} = intField2.{self::IntField::field} = numField.{self::NumField::field} as{TypeError} core::int*;
intField1.{self::IntField::field} = numField.{self::NumField::field} = intField2.{self::IntField::field};
try {
numField.{self::NumField::field} = 0.5;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.strong.transformed.expect
index 7e193c1..18a252a 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
core::int* intLocal2;
core::num* numLocal;
core::double* doubleLocal;
- intLocal1 = (intLocal2 = numLocal as{TypeError} core::int*) as{TypeError} core::int*;
+ intLocal1 = intLocal2 = numLocal as{TypeError} core::int*;
intLocal1 = numLocal = intLocal2;
numLocal = 0.5;
try {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.weak.transformed.expect
index 7e193c1..18a252a 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
core::int* intLocal2;
core::num* numLocal;
core::double* doubleLocal;
- intLocal1 = (intLocal2 = numLocal as{TypeError} core::int*) as{TypeError} core::int*;
+ intLocal1 = intLocal2 = numLocal as{TypeError} core::int*;
intLocal1 = numLocal = intLocal2;
numLocal = 0.5;
try {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.strong.transformed.expect
index f0e8e8a..65de3a8 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.strong.transformed.expect
@@ -37,7 +37,7 @@
return invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart:17:12: Error: Can't use 'super' as an expression.
To delegate a constructor to a super constructor, put the super call as an initializer.
return super(5);
- ^" as{TypeError,ForDynamic} core::int*;
+ ^";
}
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.weak.transformed.expect
index f0e8e8a..65de3a8 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.weak.transformed.expect
@@ -37,7 +37,7 @@
return invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart:17:12: Error: Can't use 'super' as an expression.
To delegate a constructor to a super constructor, put the super call as an initializer.
return super(5);
- ^" as{TypeError,ForDynamic} core::int*;
+ ^";
}
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
index 664d638..2e0067b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
@@ -294,7 +294,7 @@
}
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
- dart.core::int* value = fill as{ForNonNullableByDefault} dart.core::int*;
+ dart.core::int* value = let dart.core::int? #t7 = fill in #t7.==(null) ?{dart.core::int*} #t7 : #t7{dart.core::int*};
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) {
this.{dart.core::List::[]=}(i, value);
@@ -473,7 +473,7 @@
for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
{
- this.{dart.core::List::[]=}(let final dart.core::int #t7 = index in let final dart.core::int #t8 = index = #t7.{dart.core::num::+}(1) in #t7, element);
+ this.{dart.core::List::[]=}(let final dart.core::int #t8 = index in let final dart.core::int #t9 = index = #t8.{dart.core::num::+}(1) in #t8, element);
}
}
}
@@ -521,7 +521,7 @@
return this.{dart.core::List::[]}(0);
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void {
- this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element);
+ this.{dart.core::List::[]=}(let final dart.core::int #t10 = this.{dart.core::List::length} in let final dart.core::int #t11 = this.{dart.core::List::length} = #t10.{dart.core::num::+}(1) in #t10, element);
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ clear() → void {
this.{dart.core::List::length} = 0;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
index 664d638..2e0067b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
@@ -294,7 +294,7 @@
}
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
- dart.core::int* value = fill as{ForNonNullableByDefault} dart.core::int*;
+ dart.core::int* value = let dart.core::int? #t7 = fill in #t7.==(null) ?{dart.core::int*} #t7 : #t7{dart.core::int*};
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) {
this.{dart.core::List::[]=}(i, value);
@@ -473,7 +473,7 @@
for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
{
- this.{dart.core::List::[]=}(let final dart.core::int #t7 = index in let final dart.core::int #t8 = index = #t7.{dart.core::num::+}(1) in #t7, element);
+ this.{dart.core::List::[]=}(let final dart.core::int #t8 = index in let final dart.core::int #t9 = index = #t8.{dart.core::num::+}(1) in #t8, element);
}
}
}
@@ -521,7 +521,7 @@
return this.{dart.core::List::[]}(0);
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void {
- this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element);
+ this.{dart.core::List::[]=}(let final dart.core::int #t10 = this.{dart.core::List::length} in let final dart.core::int #t11 = this.{dart.core::List::length} = #t10.{dart.core::num::+}(1) in #t10, element);
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ clear() → void {
this.{dart.core::List::length} = 0;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart
index 1aad6da0..a8a66ce 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart
@@ -10,7 +10,7 @@
test() {
var /*@ type=() ->* Future<num*>* */ f = /*@ returnType=Future<num*>* */ () async {
- if (new Random(). /*@target=dart.math::Random::nextBool*/ nextBool()) {
+ if (new Random(). /*@target=dart.math::Random.nextBool*/ nextBool()) {
return new Future<int>.value(1);
} else {
return new Future<double>.value(2.0);
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart
index 3eeabdd..ed0f1a5 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart
@@ -10,7 +10,7 @@
test() {
var /*@ type=() ->* Future<num*>* */ f = /*@ returnType=Future<num*>* */ () async {
- if (new Random(). /*@target=dart.math::Random::nextBool*/ nextBool()) {
+ if (new Random(). /*@target=dart.math::Random.nextBool*/ nextBool()) {
return 1;
} else {
return 2.0;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart
index a438f6b..833afb7 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart
@@ -10,7 +10,7 @@
test() {
var /*@ type=() ->* Future<num*>* */ f = /*@ returnType=Future<num*>* */ () async {
- if (new Random(). /*@target=dart.math::Random::nextBool*/ nextBool()) {
+ if (new Random(). /*@target=dart.math::Random.nextBool*/ nextBool()) {
return new Future<int>.value(1);
} else {
return 2.0;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart
index 9951e54..820a997 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart
@@ -8,9 +8,9 @@
test1() {
List<int> o;
var /*@ type=Iterable<int*>* */ y =
- o. /*@ typeArgs=int* */ /*@target=Iterable::map*/ map(
+ o. /*@ typeArgs=int* */ /*@target=Iterable.map*/ map(
/*@ returnType=int* */ (/*@ type=int* */ x) {
- return x /*@target=num::+*/ + 1;
+ return x /*@target=num.+*/ + 1;
});
Iterable<int> z = y;
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart
index beaf236..044b2f3 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart
@@ -7,8 +7,8 @@
f() {
List<int> o;
- o. /*@target=Iterable::where*/ where(/*@ returnType=bool* */ (/*@ type=int* */ i) {
- return i /*@target=num::==*/ == 0;
+ o. /*@target=Iterable.where*/ where(/*@ returnType=bool* */ (/*@ type=int* */ i) {
+ return i /*@target=num.==*/ == 0;
});
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart
index 9b6202f..1eabccf 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart
@@ -13,5 +13,5 @@
};
Stream y = f();
Stream<String> z = f();
- String s = await f(). /*@target=Stream::first*/ first;
+ String s = await f(). /*@target=Stream.first*/ first;
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart
index abfa763..6d0a4af 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart
@@ -11,5 +11,5 @@
};
Iterable y = f();
Iterable<String> z = f();
- String s = f(). /*@target=Iterable::first*/ first;
+ String s = f(). /*@target=Iterable.first*/ first;
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart
index 3907949..2df406d 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart
@@ -10,12 +10,12 @@
test2() {
List<num> o;
var /*@ type=Iterable<num*>* */ y =
- o. /*@ typeArgs=num* */ /*@target=Iterable::map*/ map(
+ o. /*@ typeArgs=num* */ /*@target=Iterable.map*/ map(
/*@ returnType=num* */ (/*@ type=num* */ x) {
- if (new Random(). /*@target=dart.math::Random::nextBool*/ nextBool()) {
- return x. /*@target=num::toInt*/ toInt() /*@target=num::+*/ + 1;
+ if (new Random(). /*@target=dart.math::Random.nextBool*/ nextBool()) {
+ return x. /*@target=num.toInt*/ toInt() /*@target=num.+*/ + 1;
} else {
- return x. /*@target=num::toDouble*/ toDouble();
+ return x. /*@target=num.toDouble*/ toDouble();
}
});
Iterable<num> w = y;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart
index eaabb5f..4c3f9f8 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart
@@ -8,7 +8,7 @@
main() {
var /*@ type=() ->* (int*) ->* double* */ f = /*@ returnType=(int*) ->* double* */ () {
return /*@ returnType=double* */ (int x) {
- return 2.0 /*@target=double::**/ * x;
+ return 2.0 /*@target=double.**/ * x;
};
};
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart
index 4ca0960..0c6ada5 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart
@@ -8,7 +8,7 @@
test1() {
List<int> o;
var /*@ type=Iterable<Null?>* */ y =
- o. /*@ typeArgs=Null? */ /*@target=Iterable::map*/ map(
+ o. /*@ typeArgs=Null? */ /*@target=Iterable.map*/ map(
/*@ returnType=Null? */ (/*@ type=int* */ x) {});
Iterable<int> z = y;
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart
index b8e341d..6df81fa 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart
@@ -7,9 +7,9 @@
f() {
List<int> o;
- o. /*@target=Iterable::forEach*/ forEach(
+ o. /*@target=Iterable.forEach*/ forEach(
/*@ returnType=int* */ (/*@ type=int* */ i) {
- return i /*@target=num::+*/ + 1;
+ return i /*@target=num.+*/ + 1;
});
}
diff --git a/pkg/front_end/testcases/inference/bug30251.dart b/pkg/front_end/testcases/inference/bug30251.dart
index b16ade8..7c8da73 100644
--- a/pkg/front_end/testcases/inference/bug30251.dart
+++ b/pkg/front_end/testcases/inference/bug30251.dart
@@ -9,7 +9,7 @@
class C {
final x;
- C(int p) : x = /*@ typeArgs=int* */ f(1 /*@target=num::+*/ + p);
+ C(int p) : x = /*@ typeArgs=int* */ f(1 /*@target=num.+*/ + p);
}
main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620.dart b/pkg/front_end/testcases/inference/bug30620.dart
index f00e34f..80b762b 100644
--- a/pkg/front_end/testcases/inference/bug30620.dart
+++ b/pkg/front_end/testcases/inference/bug30620.dart
@@ -12,10 +12,10 @@
bool operator ==(Object other) =>
other is A && /*@ promotedType=A* */ other
- . /*@target=A::foo*/ foo /*@target=String::==*/ ==
- this. /*@target=A::foo*/ foo;
+ . /*@target=A.foo*/ foo /*@target=String.==*/ ==
+ this. /*@target=A.foo*/ foo;
}
main() {
- print(new A("hello") /*@target=A::==*/ == new A("hello"));
+ print(new A("hello") /*@target=A.==*/ == new A("hello"));
}
diff --git a/pkg/front_end/testcases/inference/bug30620_b.dart b/pkg/front_end/testcases/inference/bug30620_b.dart
index 1ac1495..40cb662 100644
--- a/pkg/front_end/testcases/inference/bug30620_b.dart
+++ b/pkg/front_end/testcases/inference/bug30620_b.dart
@@ -12,12 +12,12 @@
bool operator ==(Object other) =>
other is A && /*@ promotedType=A* */ other
- . /*@target=A::foo*/ foo /*@target=String::==*/ ==
- this. /*@target=A::foo*/ foo && /*@ promotedType=A* */ other
- . /*@target=A::foo*/ foo /*@target=String::==*/ ==
- this. /*@target=A::foo*/ foo;
+ . /*@target=A.foo*/ foo /*@target=String.==*/ ==
+ this. /*@target=A.foo*/ foo && /*@ promotedType=A* */ other
+ . /*@target=A.foo*/ foo /*@target=String.==*/ ==
+ this. /*@target=A.foo*/ foo;
}
main() {
- print(new A("hello") /*@target=A::==*/ == new A("hello"));
+ print(new A("hello") /*@target=A.==*/ == new A("hello"));
}
diff --git a/pkg/front_end/testcases/inference/bug30620_c.dart b/pkg/front_end/testcases/inference/bug30620_c.dart
index 4cc804f..4986277 100644
--- a/pkg/front_end/testcases/inference/bug30620_c.dart
+++ b/pkg/front_end/testcases/inference/bug30620_c.dart
@@ -12,16 +12,16 @@
bool operator ==(Object other) {
if (other is A && /*@ promotedType=A* */ other
- . /*@target=A::foo*/ foo /*@target=String::==*/ ==
- this. /*@target=A::foo*/ foo) {
+ . /*@target=A.foo*/ foo /*@target=String.==*/ ==
+ this. /*@target=A.foo*/ foo) {
if (/*@ promotedType=A* */ other
- . /*@target=A::foo*/ foo /*@target=String::==*/ ==
- this. /*@target=A::foo*/ foo) {}
+ . /*@target=A.foo*/ foo /*@target=String.==*/ ==
+ this. /*@target=A.foo*/ foo) {}
}
return true;
}
}
main() {
- print(new A("hello") /*@target=A::==*/ == new A("hello"));
+ print(new A("hello") /*@target=A.==*/ == new A("hello"));
}
diff --git a/pkg/front_end/testcases/inference/bug30620_d.dart b/pkg/front_end/testcases/inference/bug30620_d.dart
index 2d25273..9688fb0 100644
--- a/pkg/front_end/testcases/inference/bug30620_d.dart
+++ b/pkg/front_end/testcases/inference/bug30620_d.dart
@@ -7,7 +7,7 @@
String foo(obj) => obj is String
? /*@ promotedType=String* */ obj
- . /*@target=String::toUpperCase*/ toUpperCase()
+ . /*@target=String.toUpperCase*/ toUpperCase()
: null;
main() {}
diff --git a/pkg/front_end/testcases/inference/bug30624.dart b/pkg/front_end/testcases/inference/bug30624.dart
index 58f7c33..6167b32d 100644
--- a/pkg/front_end/testcases/inference/bug30624.dart
+++ b/pkg/front_end/testcases/inference/bug30624.dart
@@ -9,35 +9,35 @@
class C<E> {
void barA([int cmp(E a, E b)]) {
- /*@ typeArgs=C::E* */ foo(this, cmp /*@ target=Object::== */ ?? _default);
+ /*@ typeArgs=C::E* */ foo(this, cmp /*@target=Object.==*/ ?? _default);
}
void barB([int cmp(E a, E b)]) {
/*@ typeArgs=C::E* */ foo(
- this, cmp /*@ target=Object::== */ ?? (_default as int Function(E, E)));
+ this, cmp /*@target=Object.==*/ ?? (_default as int Function(E, E)));
}
void barC([int cmp(E a, E b)]) {
int Function(E, E) v = _default;
- /*@ typeArgs=C::E* */ foo(this, cmp /*@ target=Object::== */ ?? v);
+ /*@ typeArgs=C::E* */ foo(this, cmp /*@target=Object.==*/ ?? v);
}
void barD([int cmp(E a, E b)]) {
- foo<E>(this, cmp /*@ target=Object::== */ ?? _default);
+ foo<E>(this, cmp /*@target=Object.==*/ ?? _default);
}
void barE([int cmp(E a, E b)]) {
/*@ typeArgs=C::E* */ foo(
- this, cmp /*@target=Object::==*/ == null ? _default : cmp);
+ this, cmp /*@target=Object.==*/ == null ? _default : cmp);
}
void barF([int cmp(E a, E b)]) {
/*@ typeArgs=C::E* */ foo(
- this, cmp /*@target=Object::==*/ != null ? cmp : _default);
+ this, cmp /*@target=Object.==*/ != null ? cmp : _default);
}
static int _default(a, b) {
- return /*@target=int::unary-*/ -1;
+ return /*@target=int.unary-*/ -1;
}
}
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect
index 680cb24..3fd8197 100644
--- a/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect
@@ -10,7 +10,7 @@
self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = cmp in #t1.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
}
method barB([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t2 = cmp in #t2.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} (#C2) as (self::C::E*, self::C::E*) →* core::int* : #t2);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t2 = cmp in #t2.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t2);
}
method barC([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
(self::C::E*, self::C::E*) →* core::int* v = #C2;
diff --git a/pkg/front_end/testcases/inference/bug31132.dart b/pkg/front_end/testcases/inference/bug31132.dart
index d9953e6..656f40a 100644
--- a/pkg/front_end/testcases/inference/bug31132.dart
+++ b/pkg/front_end/testcases/inference/bug31132.dart
@@ -13,7 +13,7 @@
void test(B x) {
var /*@ type=C* */ y = x is C ? /*@ promotedType=C* */ x : new C();
- print(y. /*@target=C::z*/ z);
+ print(y. /*@target=C.z*/ z);
}
main() {}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart b/pkg/front_end/testcases/inference/bug31133.dart
index b5ff4bf..9f72fb9 100644
--- a/pkg/front_end/testcases/inference/bug31133.dart
+++ b/pkg/front_end/testcases/inference/bug31133.dart
@@ -7,18 +7,18 @@
void test() {
var /*@ type=int* */ i = 0;
- for (i /*@ target=num::+ */ ++;
- i /*@target=num::<*/ < 10;
- i /*@ target=num::+ */ ++) {}
- for (/*@ target=num::+ */ ++i;
- i /*@target=num::<*/ < 10;
- i /*@ target=num::+ */ ++) {}
- for (i /*@ target=num::- */ --;
- i /*@target=num::>=*/ >= 0;
- i /*@ target=num::- */ --) {}
- for (/*@ target=num::- */ --i;
- i /*@target=num::>=*/ >= 0;
- i /*@ target=num::- */ --) {}
+ for (i /*@target=num.+*/ ++;
+ i /*@target=num.<*/ < 10;
+ i /*@target=num.+*/ ++) {}
+ for (/*@target=num.+*/ ++i;
+ i /*@target=num.<*/ < 10;
+ i /*@target=num.+*/ ++) {}
+ for (i /*@target=num.-*/ --;
+ i /*@target=num.>=*/ >= 0;
+ i /*@target=num.-*/ --) {}
+ for (/*@target=num.-*/ --i;
+ i /*@target=num.>=*/ >= 0;
+ i /*@target=num.-*/ --) {}
}
main() {}
diff --git a/pkg/front_end/testcases/inference/bug31436.dart b/pkg/front_end/testcases/inference/bug31436.dart
index 4669e5e..36a7396 100644
--- a/pkg/front_end/testcases/inference/bug31436.dart
+++ b/pkg/front_end/testcases/inference/bug31436.dart
@@ -12,7 +12,7 @@
};
assert(g is List<Object> Function());
assert(g is! List<int> Function());
- g(). /*@target=List::add*/ add("hello"); // No runtime error
+ g(). /*@target=List.add*/ add("hello"); // No runtime error
List<int> l = /*@ typeArgs=int* */ [3];
g = /*@ returnType=List<int*>* */ () {
return l;
@@ -20,7 +20,7 @@
assert(g is List<Object> Function());
assert(g is List<int> Function());
try {
- g(). /*@target=List::add*/ add("hello"); // runtime error
+ g(). /*@target=List.add*/ add("hello"); // runtime error
throw 'expected a runtime error';
} on TypeError {}
Object o = l;
@@ -43,13 +43,13 @@
g = /*@ returnType=List<Object*>* */ () => /*@ typeArgs=Object* */ [3];
assert(g is List<Object> Function());
assert(g is! List<int> Function());
- g(). /*@target=List::add*/ add("hello"); // No runtime error
+ g(). /*@target=List.add*/ add("hello"); // No runtime error
List<int> l = /*@ typeArgs=int* */ [3];
g = /*@ returnType=List<int*>* */ () => l;
assert(g is List<Object> Function());
assert(g is List<int> Function());
try {
- g(). /*@target=List::add*/ add("hello"); // runtime error
+ g(). /*@target=List.add*/ add("hello"); // runtime error
throw 'expected a runtime error';
} on TypeError {}
Object o = l;
diff --git a/pkg/front_end/testcases/inference/bug32291.dart b/pkg/front_end/testcases/inference/bug32291.dart
index 08ea27f..c2449b0 100644
--- a/pkg/front_end/testcases/inference/bug32291.dart
+++ b/pkg/front_end/testcases/inference/bug32291.dart
@@ -10,12 +10,12 @@
/*@ typeArgs=String* */ ["hi", "world"]
];
var /*@ type=Iterable<List<String*>*>* */ i1 =
- l. /*@target=Iterable::map*/ /*@ typeArgs=List<String*>* */ map(
+ l. /*@target=Iterable.map*/ /*@ typeArgs=List<String*>* */ map(
/*@ returnType=List<String*>* */ (/*@ type=List<String*>* */ ll) =>
- ll /*@ target=List::== */ ?? /*@ typeArgs=String* */ []);
+ ll /*@target=List.==*/ ?? /*@ typeArgs=String* */ []);
var /*@ type=Iterable<int*>* */ i2 =
- i1. /*@target=Iterable::map*/ /*@ typeArgs=int* */ map(
+ i1. /*@target=Iterable.map*/ /*@ typeArgs=int* */ map(
/*@ returnType=int* */ (List<String> l) =>
- l. /*@target=List::length*/ length);
+ l. /*@target=List.length*/ length);
print(i2);
}
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart b/pkg/front_end/testcases/inference/call_corner_cases.dart
index 42ed206..eef8a9c 100644
--- a/pkg/front_end/testcases/inference/call_corner_cases.dart
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart
@@ -21,15 +21,15 @@
}
test() {
- var /*@ type=int* */ callA = new A() /*@target=A::call*/ ();
+ var /*@ type=int* */ callA = new A() /*@target=A.call*/ ();
var /*@ type=int* */ callFieldA =
- new D(). /*@target=D::fieldA*/ fieldA /*@target=A::call*/ ();
+ new D(). /*@target=D.fieldA*/ fieldA /*@target=A.call*/ ();
var /*@ type=int* */ callGetA =
- new D(). /*@target=D::getA*/ getA /*@target=A::call*/ ();
+ new D(). /*@target=D.getA*/ getA /*@target=A.call*/ ();
var /*@type=int**/ callFieldB = new D()
- . /*@target=D::fieldB*/ fieldB /*@target=B::call*/ /*@target=A::call*/ ();
- var /*@type=int**/ callGetB = new D()
- . /*@target=D::getB*/ getB /*@target=B::call*/ /*@target=A::call*/ ();
+ . /*@target=D.fieldB*/ fieldB /*@target=B.call*/ /*@target=A.call*/ ();
+ var /*@type=int**/ callGetB =
+ new D(). /*@target=D.getB*/ getB /*@target=B.call*/ /*@target=A.call*/ ();
}
main() {}
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart b/pkg/front_end/testcases/inference/callable_generic_class.dart
index fd64d35..13e4b87 100644
--- a/pkg/front_end/testcases/inference/callable_generic_class.dart
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart
@@ -17,12 +17,12 @@
void main() {
new FooActions()
- . /*@target=FooActions::foo*/ foo /*@target=ActionDispatcher::call*/ (
+ . /*@target=FooActions.foo*/ foo /*@target=ActionDispatcher.call*/ (
new Bar());
new FooActions()
- . /*@target=FooActions::foo*/ foo
- . /*@target=ActionDispatcher::call*/ call(new Bar());
+ . /*@target=FooActions.foo*/ foo
+ . /*@target=ActionDispatcher.call*/ call(new Bar());
(new FooActions()
- . /*@target=FooActions::foo*/ foo) /*@target=ActionDispatcher::call*/ (
+ . /*@target=FooActions.foo*/ foo) /*@target=ActionDispatcher.call*/ (
new Bar());
}
diff --git a/pkg/front_end/testcases/inference/complex_predecrement.dart b/pkg/front_end/testcases/inference/complex_predecrement.dart
index 02b6f5a..37c4acd 100644
--- a/pkg/front_end/testcases/inference/complex_predecrement.dart
+++ b/pkg/front_end/testcases/inference/complex_predecrement.dart
@@ -7,6 +7,5 @@
main() {
var /*@ type=List<int*>* */ foo = /*@ typeArgs=int* */ [1, 2, 3];
- print(/*@ target=num::- */ --foo /*@target=List::[]*/ /*@target=List::[]=*/ [
- 0]);
+ print(/*@target=num.-*/ --foo /*@target=List.[]*/ /*@target=List.[]=*/ [0]);
}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart
index 6f09c73..a98646b 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart
@@ -19,11 +19,11 @@
// These hints are not reported because we resolve with a null error listener.
C<num> c_num = new /*@ typeArgs=num* */ C(123);
- C<num> c_num2 = (new /*@ typeArgs=num* */ C(456)).. /*@target=C::t*/ t = 1.0;
+ C<num> c_num2 = (new /*@ typeArgs=num* */ C(456)).. /*@target=C.t*/ t = 1.0;
// Don't infer from explicit dynamic.
var /*@ type=C<dynamic>* */ c_dynamic = new C<dynamic>(42);
- x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+ x. /*@target=C.t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
}
main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
index 5a48902..66440f82 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
-// ^
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:55: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// x. /*@target=C.t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+// ^
//
import self as self;
import "dart:core" as core;
@@ -32,8 +32,8 @@
self::C<core::num*>* c_num = new self::C::•<core::num*>(123);
self::C<core::num*>* c_num2 = let final self::C<core::num*>* #t1 = new self::C::•<core::num*>(456) in let final void #t2 = #t1.{self::C::t} = 1.0 in #t1;
self::C<dynamic>* c_dynamic = new self::C::•<dynamic>(42);
- x.{self::C::t} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
- ^" in "hello" as{TypeError} core::int*;
+ x.{self::C::t} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:55: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ x. /*@target=C.t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+ ^" in "hello" as{TypeError} core::int*;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
index 5a48902..66440f82 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
-// ^
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:55: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// x. /*@target=C.t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+// ^
//
import self as self;
import "dart:core" as core;
@@ -32,8 +32,8 @@
self::C<core::num*>* c_num = new self::C::•<core::num*>(123);
self::C<core::num*>* c_num2 = let final self::C<core::num*>* #t1 = new self::C::•<core::num*>(456) in let final void #t2 = #t1.{self::C::t} = 1.0 in #t1;
self::C<dynamic>* c_dynamic = new self::C::•<dynamic>(42);
- x.{self::C::t} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
- ^" in "hello" as{TypeError} core::int*;
+ x.{self::C::t} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:55: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ x. /*@target=C.t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+ ^" in "hello" as{TypeError} core::int*;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart
index 585784f..24d22ed 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart
@@ -12,14 +12,14 @@
factory C(T t) {
var /*@ type=C<C::•::T*>* */ x = new C<T>._();
- x. /*@target=C::t*/ t = t;
+ t = t;
return x;
}
}
test() {
var /*@ type=C<int*>* */ x = new /*@ typeArgs=int* */ C(42);
- x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
}
main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
index c830c70..4fc4ae3 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
-// ^
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:3: Error: Setter not found: 't'.
+// t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+// ^
//
import self as self;
import "dart:core" as core;
@@ -16,7 +16,7 @@
;
static factory •<T extends core::Object* = dynamic>(self::C::•::T* t) → self::C<self::C::•::T*>* {
self::C<self::C::•::T*>* x = new self::C::_<self::C::•::T*>();
- x.{self::C::t} = t;
+ t = t;
return x;
}
abstract member-signature get _identityHashCode() → core::int*;
@@ -32,8 +32,8 @@
}
static method test() → dynamic {
self::C<core::int*>* x = self::C::•<core::int*>(42);
- x.{self::C::t} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
- ^" in "hello" as{TypeError} core::int*;
+ invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:3: Error: Setter not found: 't'.
+ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+ ^";
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
index c830c70..4fc4ae3 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
-// ^
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:3: Error: Setter not found: 't'.
+// t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+// ^
//
import self as self;
import "dart:core" as core;
@@ -16,7 +16,7 @@
;
static factory •<T extends core::Object* = dynamic>(self::C::•::T* t) → self::C<self::C::•::T*>* {
self::C<self::C::•::T*>* x = new self::C::_<self::C::•::T*>();
- x.{self::C::t} = t;
+ t = t;
return x;
}
abstract member-signature get _identityHashCode() → core::int*;
@@ -32,8 +32,8 @@
}
static method test() → dynamic {
self::C<core::int*>* x = self::C::•<core::int*>(42);
- x.{self::C::t} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
- ^" in "hello" as{TypeError} core::int*;
+ invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:3: Error: Setter not found: 't'.
+ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+ ^";
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart
index 9796dff..c366014 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart
@@ -11,7 +11,7 @@
factory C.named(T t) {
var /*@ type=C<C::named::T*>* */ x = new C<T>();
- x. /*@target=C::t*/ t = t;
+ x. /*@target=C.t*/ t = t;
return x;
}
}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart
index f414e9b..3a5cb18 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart
@@ -8,7 +8,7 @@
class C<T> {
T t;
C(this.t);
- C.named(List<T> t) : this(t /*@target=List::[]*/ [0]);
+ C.named(List<T> t) : this(t /*@target=List.[]*/ [0]);
}
main() {
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart
index 5cedc1b..12c528d 100644
--- a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart
@@ -13,8 +13,8 @@
Pair(this.t, this.u);
Pair._();
Pair<U, T> get reversed => new /*@ typeArgs=Pair::U*, Pair::T* */ Pair(
- /*@target=Pair::u*/ u,
- /*@target=Pair::t*/ t);
+ /*@target=Pair.u*/ u,
+ /*@target=Pair.t*/ t);
}
main() {
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart
index 01b6c5e..aeab0af 100644
--- a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart
@@ -10,8 +10,8 @@
U u;
Pair(this.t, this.u);
Pair<U, T> get reversed => new /*@ typeArgs=Pair::U*, Pair::T* */ Pair(
- /*@target=Pair::u*/ u,
- /*@target=Pair::t*/ t);
+ /*@target=Pair.u*/ u,
+ /*@target=Pair.t*/ t);
}
main() {}
diff --git a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart
index 6e05a83..fa6454f 100644
--- a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart
+++ b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart
@@ -14,8 +14,8 @@
}
foo() {
- String y = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
- int z = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
+ String y = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
+ int z = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
}
main() {
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart
index 4481a40..7c1133c 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart
@@ -12,8 +12,8 @@
void test() {
for (@Foo(/*@ typeArgs=String* */ const [])
int i = 0;
- i /*@target=num::<*/ < 1;
- i /*@ target=num::+ */ ++) {}
+ i /*@target=num.<*/ < 1;
+ i /*@target=num.+*/ ++) {}
for (@Foo(/*@ typeArgs=String* */ const [])
int i in /*@ typeArgs=int* */ [0]) {}
}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart
index ef5f40e..40a7805 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart
@@ -13,7 +13,7 @@
B(T x);
}
-var t1 = new A().. /*@target=A::b*/ b = new /*@ typeArgs=int* */ B(1);
+var t1 = new A().. /*@target=A.b*/ b = new /*@ typeArgs=int* */ B(1);
var t2 = <B<int>>[new /*@ typeArgs=int* */ B(2)];
main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart
index c8bea76..2085ac4 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart
@@ -54,7 +54,7 @@
{
Function2<int, int> l0 = /*@ returnType=int* */ (/*@ type=int* */ x) => x;
Function2<int, int> l1 = /*@ returnType=int* */ (/*@ type=int* */ x) =>
- x /*@target=num::+*/ + 1;
+ x /*@target=num.+*/ + 1;
Function2<int, String>
l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (/*@ type=int* */ x) =>
x;
@@ -63,7 +63,7 @@
.substring(3);
Function2<String, String>
l4 = /*@ returnType=String* */ (/*@ type=String* */ x) =>
- x. /*@target=String::substring*/ substring(3);
+ x. /*@target=String.substring*/ substring(3);
}
}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
index 55385e0..46f24ee 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
@@ -110,7 +110,7 @@
(core::int*) →* core::String* l3 = (core::int* x) → core::String* => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'int'.
Try correcting the name to the name of an existing method, or defining a method named 'substring'.
.substring(3);
- ^^^^^^^^^" as{TypeError,ForDynamic} core::String*;
+ ^^^^^^^^^";
(core::String*) →* core::String* l4 = (core::String* x) → core::String* => x.{core::String::substring}(3);
}
}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart
index bd01ae5..557c38e 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart
@@ -57,7 +57,7 @@
String string2String<T>(String x) => null;
var /*@ type=<S extends Object* = dynamic>(int*) ->* int* */ x = int2int;
x = <T> /*@ returnType=int* */ (/*@ type=int* */ x) => x;
- x = <T> /*@ returnType=int* */ (/*@ type=int* */ x) => x /*@target=num::+*/ + 1;
+ x = <T> /*@ returnType=int* */ (/*@ type=int* */ x) => x /*@target=num.+*/ + 1;
var /*@ type=<T extends Object* = dynamic>(int*) ->* String* */ y = int2String;
y = /*info:INFERRED_TYPE_CLOSURE, error:INVALID_ASSIGNMENT*/ <
T> /*@ returnType=String* */ (/*@ type=int* */ x) =>
@@ -67,7 +67,7 @@
var /*@ type=<T extends Object* = dynamic>(String*) ->* String* */ z =
string2String;
z = <T> /*@ returnType=String* */ (/*@ type=String* */ x) =>
- x. /*@target=String::substring*/ substring(3);
+ x. /*@target=String.substring*/ substring(3);
}
}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
index ee90542..dfcc1ab 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
@@ -126,7 +126,7 @@
y = <T extends core::Object* = dynamic>(core::int* x) → core::String* => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'int'.
Try correcting the name to the name of an existing method, or defining a method named 'substring'.
.substring(3);
- ^^^^^^^^^" as{TypeError,ForDynamic} core::String*;
+ ^^^^^^^^^";
<T extends core::Object* = dynamic>(core::String*) →* core::String* z = string2String;
z = <T extends core::Object* = dynamic>(core::String* x) → core::String* => x.{core::String::substring}(3);
}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart
index 9e70b2c..18113c6 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart
@@ -22,13 +22,13 @@
AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {
- /*@target=C::assertAOf*/ assertAOf(
+ /*@target=C.assertAOf*/ assertAOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
assertBOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
assertCOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
- /*@target=C::assertDOf*/ assertDOf(
+ /*@target=C.assertDOf*/ assertDOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
assertEOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
@@ -40,11 +40,11 @@
AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {
- /*@target=G::assertAOf*/ assertAOf(
+ /*@target=G.assertAOf*/ assertAOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
- this. /*@target=G::assertAOf*/ assertAOf(
+ this. /*@target=G.assertAOf*/ assertAOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
- this. /*@target=G::assertDOf*/ assertDOf(
+ this. /*@target=G.assertDOf*/ assertDOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
assertEOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
@@ -68,15 +68,15 @@
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
C c;
- c. /*@target=C::assertAOf*/ assertAOf(
+ c. /*@target=C.assertAOf*/ assertAOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
- c. /*@target=C::assertDOf*/ assertDOf(
+ c. /*@target=C.assertDOf*/ assertDOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
G<int> g;
- g. /*@target=G::assertAOf*/ assertAOf(
+ g. /*@target=G.assertAOf*/ assertAOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
- g. /*@target=G::assertDOf*/ assertDOf(
+ g. /*@target=G.assertDOf*/ assertDOf(
/*@ typeArgs=(DartType*) ->* void */ [_isInt, _isString]);
}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart b/pkg/front_end/testcases/inference/dynamic_methods.dart
index 4f338f1..bc11827 100644
--- a/pkg/front_end/testcases/inference/dynamic_methods.dart
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart
@@ -11,25 +11,25 @@
test() {
dynamic d = new Foo();
- var /*@ type=int* */ get_hashCode = d. /*@target=Object::hashCode*/ hashCode;
+ var /*@ type=int* */ get_hashCode = d. /*@target=Object.hashCode*/ hashCode;
var /*@ type=dynamic */ call_hashCode =
- d. /*@target=Object::hashCode*/ hashCode();
+ d. /*@target=Object.hashCode*/ hashCode();
var /*@ type=String* */ call_toString =
- d. /*@target=Object::toString*/ toString();
+ d. /*@target=Object.toString*/ toString();
var /*@ type=dynamic */ call_toStringArg = d.toString(color: "pink");
var /*@ type=dynamic */ call_foo0 = d.foo();
var /*@ type=dynamic */ call_foo1 = d.foo(1);
var /*@ type=dynamic */ call_foo2 = d.foo(1, 2);
var /*@ type=dynamic */ call_nsm0 = d.noSuchMethod();
var /*@ type=dynamic */ call_nsm1 =
- d. /*@target=Object::noSuchMethod*/ noSuchMethod(null);
+ d. /*@target=Object.noSuchMethod*/ noSuchMethod(null);
var /*@ type=dynamic */ call_nsm2 = d.noSuchMethod(null, null);
- var /*@ type=bool* */ equals_self = d /*@target=Object::==*/ == d;
- var /*@ type=bool* */ equals_null = d /*@target=Object::==*/ == null;
- var /*@ type=bool* */ null_equals = null /*@target=Object::==*/ == d;
- var /*@ type=bool* */ not_equals_self = d /*@target=Object::==*/ != d;
- var /*@ type=bool* */ not_equals_null = d /*@target=Object::==*/ != null;
- var /*@ type=bool* */ null_not_equals = null /*@target=Object::==*/ != d;
+ var /*@ type=bool* */ equals_self = d /*@target=Object.==*/ == d;
+ var /*@ type=bool* */ equals_null = d /*@target=Object.==*/ == null;
+ var /*@ type=bool* */ null_equals = null /*@target=Object.==*/ == d;
+ var /*@ type=bool* */ not_equals_self = d /*@target=Object.==*/ != d;
+ var /*@ type=bool* */ not_equals_null = d /*@target=Object.==*/ != null;
+ var /*@ type=bool* */ null_not_equals = null /*@target=Object.==*/ != d;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
index 18d5c33..9e18c7e 100644
--- a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/dynamic_methods.dart:16:47: Error: 'hashCode' isn't a function or method and can't be invoked.
-// d. /*@target=Object::hashCode*/ hashCode();
-// ^^^^...
+// pkg/front_end/testcases/inference/dynamic_methods.dart:16:46: Error: 'hashCode' isn't a function or method and can't be invoked.
+// d. /*@target=Object.hashCode*/ hashCode();
+// ^^^^...
//
import self as self;
import "dart:core" as core;
@@ -29,9 +29,9 @@
static method test() → dynamic {
dynamic d = new self::Foo::•();
core::int* get_hashCode = d.{core::Object::hashCode};
- dynamic call_hashCode = invalid-expression "pkg/front_end/testcases/inference/dynamic_methods.dart:16:47: Error: 'hashCode' isn't a function or method and can't be invoked.
- d. /*@target=Object::hashCode*/ hashCode();
- ^^^^...";
+ dynamic call_hashCode = invalid-expression "pkg/front_end/testcases/inference/dynamic_methods.dart:16:46: Error: 'hashCode' isn't a function or method and can't be invoked.
+ d. /*@target=Object.hashCode*/ hashCode();
+ ^^^^...";
core::String* call_toString = d.{core::Object::toString}();
dynamic call_toStringArg = d.toString(color: "pink");
dynamic call_foo0 = d.foo();
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
index 18d5c33..9e18c7e 100644
--- a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/dynamic_methods.dart:16:47: Error: 'hashCode' isn't a function or method and can't be invoked.
-// d. /*@target=Object::hashCode*/ hashCode();
-// ^^^^...
+// pkg/front_end/testcases/inference/dynamic_methods.dart:16:46: Error: 'hashCode' isn't a function or method and can't be invoked.
+// d. /*@target=Object.hashCode*/ hashCode();
+// ^^^^...
//
import self as self;
import "dart:core" as core;
@@ -29,9 +29,9 @@
static method test() → dynamic {
dynamic d = new self::Foo::•();
core::int* get_hashCode = d.{core::Object::hashCode};
- dynamic call_hashCode = invalid-expression "pkg/front_end/testcases/inference/dynamic_methods.dart:16:47: Error: 'hashCode' isn't a function or method and can't be invoked.
- d. /*@target=Object::hashCode*/ hashCode();
- ^^^^...";
+ dynamic call_hashCode = invalid-expression "pkg/front_end/testcases/inference/dynamic_methods.dart:16:46: Error: 'hashCode' isn't a function or method and can't be invoked.
+ d. /*@target=Object.hashCode*/ hashCode();
+ ^^^^...";
core::String* call_toString = d.{core::Object::toString}();
dynamic call_toStringArg = d.toString(color: "pink");
dynamic call_foo0 = d.foo();
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart
index 95f321e..1ab15ed 100644
--- a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart
@@ -6,8 +6,8 @@
library test;
void test() {
- for (num x = 0;; x /*@ target=num::+ */ ++) {
- if (x /*@target=num::>=*/ >= 10) break;
+ for (num x = 0;; x /*@target=num.+*/ ++) {
+ if (x /*@target=num.>=*/ >= 10) break;
if (x is int) {
var /*@ type=int* */ y = /*@ promotedType=int* */ x;
}
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart
index 28684ac..2d548ae 100644
--- a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart
@@ -7,7 +7,7 @@
void test() {
num x;
- for (x = 0; x /*@target=num::<*/ < 10; x /*@ target=num::+ */ ++) {
+ for (x = 0; x /*@target=num.<*/ < 10; x /*@target=num.+*/ ++) {
if (x is int) {
var /*@ type=int* */ y = /*@ promotedType=int* */ x;
}
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart b/pkg/front_end/testcases/inference/for_loop_promotion.dart
index e134425..d9e8e8e 100644
--- a/pkg/front_end/testcases/inference/for_loop_promotion.dart
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart
@@ -6,7 +6,7 @@
library test;
void test() {
- for (num x = 0; x /*@target=num::<*/ < 10; x /*@ target=num::+ */ ++) {
+ for (num x = 0; x /*@target=num.<*/ < 10; x /*@target=num.+*/ ++) {
if (x is int) {
var /*@ type=int* */ y = /*@ promotedType=int* */ x;
}
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart b/pkg/front_end/testcases/inference/future_or_subtyping.dart
index b177e5e..6cfda1a 100644
--- a/pkg/front_end/testcases/inference/future_or_subtyping.dart
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart
@@ -12,9 +12,9 @@
test() {
Future<int> f;
var /*@ type=Future<void>* */ a =
- f. /*@ typeArgs=void */ /*@target=Future::then*/ then(add);
+ f. /*@ typeArgs=void */ /*@target=Future.then*/ then(add);
var /*@ type=Future<dynamic>* */ b =
- f. /*@ typeArgs=dynamic */ /*@target=Future::then*/ then(add2);
+ f. /*@ typeArgs=dynamic */ /*@target=Future.then*/ then(add2);
}
main() {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart b/pkg/front_end/testcases/inference/future_then.dart
index 67e1333..b2a826f 100644
--- a/pkg/front_end/testcases/inference/future_then.dart
+++ b/pkg/front_end/testcases/inference/future_then.dart
@@ -16,30 +16,30 @@
void test() {
MyFuture f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
await new Future<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return await new Future<int>.value(3);
});
- Future<int> t3 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t3 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async => 3);
- Future<int> t4 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t4 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return 3;
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) =>
new Future<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) {
return new Future<int>.value(3);
});
- Future<int> t7 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t7 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
new Future<int>.value(3));
- Future<int> t8 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t8 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return new Future<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart b/pkg/front_end/testcases/inference/future_then_2.dart
index d500909..d04a8dd 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart
+++ b/pkg/front_end/testcases/inference/future_then_2.dart
@@ -16,30 +16,30 @@
void test() {
MyFuture f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
await new MyFuture<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return await new MyFuture<int>.value(3);
});
- Future<int> t3 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t3 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async => 3);
- Future<int> t4 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t4 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return 3;
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=MyFuture<int*>* */ (/*@ type=dynamic */ _) =>
new MyFuture<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=MyFuture<int*>* */ (/*@ type=dynamic */ _) {
return new MyFuture<int>.value(3);
});
- Future<int> t7 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t7 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
new MyFuture<int>.value(3));
- Future<int> t8 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t8 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return new MyFuture<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart b/pkg/front_end/testcases/inference/future_then_3.dart
index b3d62b9..5774099 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart
+++ b/pkg/front_end/testcases/inference/future_then_3.dart
@@ -16,30 +16,30 @@
void test() {
MyFuture f;
- MyFuture<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
await new Future<int>.value(3));
- MyFuture<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return await new Future<int>.value(3);
});
- MyFuture<int> t3 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t3 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async => 3);
- MyFuture<int> t4 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t4 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return 3;
});
- MyFuture<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) =>
new Future<int>.value(3));
- MyFuture<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) {
return new Future<int>.value(3);
});
- MyFuture<int> t7 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t7 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
new Future<int>.value(3));
- MyFuture<int> t8 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t8 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return new Future<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart b/pkg/front_end/testcases/inference/future_then_4.dart
index 9670dc5..0a0dbad 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart
+++ b/pkg/front_end/testcases/inference/future_then_4.dart
@@ -16,30 +16,30 @@
void test() {
MyFuture f;
- MyFuture<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
await new MyFuture<int>.value(3));
- MyFuture<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return await new MyFuture<int>.value(3);
});
- MyFuture<int> t3 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t3 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async => 3);
- MyFuture<int> t4 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t4 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return 3;
});
- MyFuture<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=MyFuture<int*>* */ (/*@ type=dynamic */ _) =>
new MyFuture<int>.value(3));
- MyFuture<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=MyFuture<int*>* */ (/*@ type=dynamic */ _) {
return new MyFuture<int>.value(3);
});
- MyFuture<int> t7 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t7 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
new MyFuture<int>.value(3));
- MyFuture<int> t8 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t8 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return new MyFuture<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart b/pkg/front_end/testcases/inference/future_then_5.dart
index f32247b..150327d 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart
+++ b/pkg/front_end/testcases/inference/future_then_5.dart
@@ -16,30 +16,30 @@
void test() {
Future f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
await new MyFuture<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return await new MyFuture<int>.value(3);
});
- Future<int> t3 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t3 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async => 3);
- Future<int> t4 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t4 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return 3;
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=MyFuture<int*>* */ (/*@ type=dynamic */ _) =>
new MyFuture<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=MyFuture<int*>* */ (/*@ type=dynamic */ _) {
return new MyFuture<int>.value(3);
});
- Future<int> t7 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t7 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
new MyFuture<int>.value(3));
- Future<int> t8 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t8 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return new MyFuture<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart b/pkg/front_end/testcases/inference/future_then_6.dart
index b790f4d..34fe924 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart
+++ b/pkg/front_end/testcases/inference/future_then_6.dart
@@ -16,30 +16,30 @@
void test() {
Future f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
await new Future<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return await new Future<int>.value(3);
});
- Future<int> t3 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t3 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async => 3);
- Future<int> t4 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t4 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return 3;
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) =>
new Future<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) {
return new Future<int>.value(3);
});
- Future<int> t7 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t7 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async =>
new Future<int>.value(3));
- Future<int> t8 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t8 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) async {
return new Future<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart b/pkg/front_end/testcases/inference/future_then_conditional.dart
index 07a48f6..b9c870e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart
@@ -16,18 +16,18 @@
void test() {
MyFuture<bool> f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async =>
x ? 2 : await new Future<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async {
return /*info:DOWN_CAST_COMPOSITE*/ await x ? 2 : new Future<int>.value(3);
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*error:INVALID_CAST_FUNCTION_EXPR*/
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) =>
x ? 2 : new Future<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) {
return /*info:DOWN_CAST_COMPOSITE*/ x ? 2 : new Future<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart b/pkg/front_end/testcases/inference/future_then_conditional_2.dart
index b984016..e492066 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart
@@ -16,20 +16,20 @@
void test() {
MyFuture<bool> f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async =>
x ? 2 : await new MyFuture<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async {
return /*info:DOWN_CAST_COMPOSITE*/ await x
? 2
: new MyFuture<int>.value(3);
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*info:INFERRED_TYPE_CLOSURE,error:INVALID_CAST_FUNCTION_EXPR*/
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) =>
x ? 2 : new MyFuture<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) {
return /*info:DOWN_CAST_COMPOSITE*/ x ? 2 : new MyFuture<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart b/pkg/front_end/testcases/inference/future_then_conditional_3.dart
index 28e52e8..bb97825 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart
@@ -16,18 +16,18 @@
void test() {
MyFuture<bool> f;
- MyFuture<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async =>
x ? 2 : await new Future<int>.value(3));
- MyFuture<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async {
return /*info:DOWN_CAST_COMPOSITE*/ await x ? 2 : new Future<int>.value(3);
});
- MyFuture<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*info:INFERRED_TYPE_CLOSURE,error:INVALID_CAST_FUNCTION_EXPR*/
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) =>
x ? 2 : new Future<int>.value(3));
- MyFuture<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) {
return /*info:DOWN_CAST_COMPOSITE*/ x ? 2 : new Future<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart b/pkg/front_end/testcases/inference/future_then_conditional_4.dart
index 6166276..900063b 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart
@@ -16,20 +16,20 @@
void test() {
MyFuture<bool> f;
- MyFuture<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async =>
x ? 2 : await new MyFuture<int>.value(3));
- MyFuture<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async {
return /*info:DOWN_CAST_COMPOSITE*/ await x
? 2
: new MyFuture<int>.value(3);
});
- MyFuture<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*info:INFERRED_TYPE_CLOSURE,error:INVALID_CAST_FUNCTION_EXPR*/
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) =>
x ? 2 : new MyFuture<int>.value(3));
- MyFuture<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ MyFuture<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) {
return /*info:DOWN_CAST_COMPOSITE*/ x ? 2 : new MyFuture<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart b/pkg/front_end/testcases/inference/future_then_conditional_5.dart
index 53938d2c..2816ab3 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart
@@ -16,20 +16,20 @@
void test() {
Future<bool> f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async =>
x ? 2 : await new MyFuture<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async {
return /*info:DOWN_CAST_COMPOSITE*/ await x
? 2
: new MyFuture<int>.value(3);
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*info:INFERRED_TYPE_CLOSURE,error:INVALID_CAST_FUNCTION_EXPR*/
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) =>
x ? 2 : new MyFuture<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) {
return /*info:DOWN_CAST_COMPOSITE*/ x ? 2 : new MyFuture<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart b/pkg/front_end/testcases/inference/future_then_conditional_6.dart
index 721c2ca..7d2572e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart
@@ -16,18 +16,18 @@
void test() {
Future<bool> f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async =>
x ? 2 : await new Future<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=bool* */ x) async {
return /*info:DOWN_CAST_COMPOSITE*/ await x ? 2 : new Future<int>.value(3);
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*info:INFERRED_TYPE_CLOSURE,error:INVALID_CAST_FUNCTION_EXPR*/
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) =>
x ? 2 : new Future<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=FutureOr<int*>* */ (/*@ type=bool* */ x) {
return /*info:DOWN_CAST_COMPOSITE*/ x ? 2 : new Future<int>.value(3);
});
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart
index 0477b7b..ecf97aa 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart
@@ -10,11 +10,11 @@
test() {
Future<int> f;
Future<List<int>> b = /*info:ASSIGNMENT_CAST should be pass*/ f
- . /*@ typeArgs=List<dynamic>* */ /*@target=Future::then*/ then(
+ . /*@ typeArgs=List<dynamic>* */ /*@target=Future.then*/ then(
/*@ returnType=List<dynamic>* */ (/*@ type=int* */ x) => /*@ typeArgs=dynamic */ [])
- . /*@target=Future::whenComplete*/ whenComplete(
+ . /*@target=Future.whenComplete*/ whenComplete(
/*@ returnType=Null? */ () {});
- b = f. /*@ typeArgs=List<int*>* */ /*@target=Future::then*/ then(
+ b = f. /*@ typeArgs=List<int*>* */ /*@target=Future.then*/ then(
/*@ returnType=List<int*>* */ (/*@ type=int* */ x) => /*@ typeArgs=int* */ []);
}
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart b/pkg/front_end/testcases/inference/future_then_explicit_future.dart
index 96f37e4..c14e152 100644
--- a/pkg/front_end/testcases/inference/future_then_explicit_future.dart
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart
@@ -9,7 +9,7 @@
m1() {
Future<int> f;
- var /*@type=Future<Future<List<int*>*>*>**/ x = f. /*@target=Future::then*/ then<
+ var /*@type=Future<Future<List<int*>*>*>**/ x = f. /*@target=Future.then*/ then<
Future<List<int>>>(
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/
/*@returnType=FutureOr<Future<List<int*>*>*>**/ (/*@type=int**/ x) => /*@typeArgs=dynamic*/ []);
@@ -18,7 +18,7 @@
m2() {
Future<int> f;
- var /*@type=Future<List<int*>*>**/ x = f. /*@target=Future::then*/ then<
+ var /*@type=Future<List<int*>*>**/ x = f. /*@target=Future.then*/ then<
List<int>>(
/*@returnType=List<int*>**/ (/*@type=int**/ x) => /*@typeArgs=int**/ []);
Future<List<int>> y = x;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart b/pkg/front_end/testcases/inference/future_then_ifNull.dart
index d84927f..06b9f65 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart
@@ -16,21 +16,21 @@
void test() {
MyFuture<int> f;
- Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=int* */ x) async =>
- x /*@ target=num::== */ ?? await new Future<int>.value(3));
- Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ x /*@target=num.==*/ ?? await new Future<int>.value(3));
+ Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=int* */ x) async {
- return /*info:DOWN_CAST_COMPOSITE*/ await x /*@ target=num::== */ ??
+ return /*info:DOWN_CAST_COMPOSITE*/ await x /*@target=num.==*/ ??
new Future<int>.value(3);
});
- Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*error:INVALID_CAST_FUNCTION_EXPR*/
/*@ returnType=FutureOr<int*>* */ (/*@ type=int* */ x) =>
- x /*@ target=num::== */ ?? new Future<int>.value(3));
- Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+ x /*@target=num.==*/ ?? new Future<int>.value(3));
+ Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=FutureOr<int*>* */ (/*@ type=int* */ x) {
- return /*info:DOWN_CAST_COMPOSITE*/ x /*@ target=num::== */ ??
+ return /*info:DOWN_CAST_COMPOSITE*/ x /*@target=num.==*/ ??
new Future<int>.value(3);
});
}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart b/pkg/front_end/testcases/inference/future_then_upwards.dart
index a54d337..9489362 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart
@@ -16,14 +16,14 @@
void main() {
var /*@ type=MyFuture<double*>* */ f =
- foo(). /*@ typeArgs=double* */ /*@target=MyFuture::then*/ then(
+ foo(). /*@ typeArgs=double* */ /*@target=MyFuture.then*/ then(
/*@ returnType=double* */ (/*@ type=dynamic */ _) => 2.3);
Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
// The unnecessary cast is to illustrate that we inferred <double> for
// the generic type args, even though we had a return type context.
Future<num> f3 = /*info:UNNECESSARY_CAST*/ foo()
- . /*@ typeArgs=double* */ /*@target=MyFuture::then*/ then(
+ . /*@ typeArgs=double* */ /*@target=MyFuture.then*/ then(
/*@ returnType=double* */ (/*@ type=dynamic */ _) => 2.3)
as Future<double>;
}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
index 60fb617..1b093f5 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
@@ -48,7 +48,7 @@
- 'Future' is from 'dart:async'.
Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
^" in f as{TypeError} asy::Future<core::int*>*;
- asy::Future<core::num*>* f3 = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3) as asy::Future<core::double*>*;
+ asy::Future<core::num*>* f3 = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3);
}
static method foo() → self::MyFuture<dynamic>*
return new self::MyFuture::value<core::int*>(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart b/pkg/front_end/testcases/inference/future_then_upwards_2.dart
index 86bd56d..18c0e38 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart
@@ -16,14 +16,14 @@
void main() {
var /*@ type=MyFuture<double*>* */ f =
- foo(). /*@ typeArgs=double* */ /*@target=MyFuture::then*/ then(
+ foo(). /*@ typeArgs=double* */ /*@target=MyFuture.then*/ then(
/*@ returnType=double* */ (/*@ type=dynamic */ _) => 2.3);
MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
// The unnecessary cast is to illustrate that we inferred <double> for
// the generic type args, even though we had a return type context.
MyFuture<num> f3 = /*info:UNNECESSARY_CAST*/ foo()
- . /*@ typeArgs=double* */ /*@target=MyFuture::then*/ then(
+ . /*@ typeArgs=double* */ /*@target=MyFuture.then*/ then(
/*@ returnType=double* */ (/*@ type=dynamic */ _) => 2.3)
as MyFuture<double>;
}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
index 5851a4f..bf7c9dd 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
@@ -46,7 +46,7 @@
- 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards_2.dart'.
MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
^" in f as{TypeError} self::MyFuture<core::int*>*;
- self::MyFuture<core::num*>* f3 = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3) as self::MyFuture<core::double*>*;
+ self::MyFuture<core::num*>* f3 = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3);
}
static method foo() → self::MyFuture<dynamic>*
return new self::MyFuture::value<core::int*>(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart b/pkg/front_end/testcases/inference/future_then_upwards_3.dart
index f88050b..0e3a514 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart
@@ -16,14 +16,14 @@
void test() {
var /*@ type=Future<double*>* */ f =
- foo(). /*@ typeArgs=double* */ /*@target=Future::then*/ then(
+ foo(). /*@ typeArgs=double* */ /*@target=Future.then*/ then(
/*@ returnType=double* */ (/*@ type=dynamic */ _) => 2.3);
Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
// The unnecessary cast is to illustrate that we inferred <double> for
// the generic type args, even though we had a return type context.
Future<num> f3 = /*info:UNNECESSARY_CAST*/ foo()
- . /*@ typeArgs=double* */ /*@target=Future::then*/ then(
+ . /*@ typeArgs=double* */ /*@target=Future.then*/ then(
/*@ returnType=double* */ (/*@ type=dynamic */ _) => 2.3)
as Future<double>;
}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
index 84101e4..44f84be 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
@@ -46,7 +46,7 @@
- 'Future' is from 'dart:async'.
Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
^" in f as{TypeError} asy::Future<core::int*>*;
- asy::Future<core::num*>* f3 = self::foo().{asy::Future::then}<core::double*>((dynamic _) → core::double* => 2.3) as asy::Future<core::double*>*;
+ asy::Future<core::num*>* f3 = self::foo().{asy::Future::then}<core::double*>((dynamic _) → core::double* => 2.3);
}
static method foo() → asy::Future<dynamic>*
return asy::Future::value<core::int*>(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart
index ebb2f1a..9d5ee4a 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart
@@ -10,13 +10,13 @@
test() {
Future<int> base;
var /*@ type=Future<bool*>* */ f =
- base. /*@ typeArgs=bool* */ /*@target=Future::then*/ then(
+ base. /*@ typeArgs=bool* */ /*@target=Future.then*/ then(
/*@ returnType=bool* */ (/*@ type=int* */ x) {
- return x /*@target=num::==*/ == 0;
+ return x /*@target=num.==*/ == 0;
});
var /*@ type=Future<bool*>* */ g =
- base. /*@ typeArgs=bool* */ /*@target=Future::then*/ then(
- /*@ returnType=bool* */ (/*@ type=int* */ x) => x /*@target=num::==*/ == 0);
+ base. /*@ typeArgs=bool* */ /*@target=Future.then*/ then(
+ /*@ returnType=bool* */ (/*@ type=int* */ x) => x /*@target=num.==*/ == 0);
Future<bool> b = f;
b = g;
}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart b/pkg/front_end/testcases/inference/future_union_downwards.dart
index 2516414..a4a8088 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart
@@ -16,13 +16,13 @@
MyFuture f;
// Instantiates Future<int>
-Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) =>
new /*@ typeArgs=int* */ Future.value('hi'));
// Instantiates List<int>
Future<List<int>> t2 =
- f. /*@ typeArgs=List<int*>* */ /*@target=MyFuture::then*/ then(
+ f. /*@ typeArgs=List<int*>* */ /*@target=MyFuture.then*/ then(
/*@ returnType=List<int*>* */ (/*@ type=dynamic */ _) => /*@ typeArgs=int* */ [
3
]);
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart b/pkg/front_end/testcases/inference/future_union_downwards_2.dart
index fbf1963..d771ba3 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart
@@ -16,13 +16,13 @@
MyFuture f;
// Instantiates Future<int>
-Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
+Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture.then*/ then(
/*@ returnType=MyFuture<int*>* */ (/*@ type=dynamic */ _) =>
new /*@ typeArgs=int* */ MyFuture.value('hi'));
// Instantiates List<int>
Future<List<int>> t2 =
- f. /*@ typeArgs=List<int*>* */ /*@target=MyFuture::then*/ then(
+ f. /*@ typeArgs=List<int*>* */ /*@target=MyFuture.then*/ then(
/*@ returnType=List<int*>* */ (/*@ type=dynamic */ _) => /*@ typeArgs=int* */ [
3
]);
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart b/pkg/front_end/testcases/inference/future_union_downwards_3.dart
index 321b82d..653e936 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart
@@ -16,12 +16,12 @@
Future f;
// Instantiates Future<int>
-Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=dynamic */ _) =>
new /*@ typeArgs=int* */ Future.value('hi'));
// Instantiates List<int>
-Future<List<int>> t2 = f. /*@ typeArgs=List<int*>* */ /*@target=Future::then*/ then(
+Future<List<int>> t2 = f. /*@ typeArgs=List<int*>* */ /*@target=Future.then*/ then(
/*@ returnType=List<int*>* */ (/*@ type=dynamic */ _) => /*@ typeArgs=int* */ [3]);
Future<List<int>> g2() async {
return /*@ typeArgs=int* */ [3];
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart b/pkg/front_end/testcases/inference/future_union_downwards_4.dart
index 36a693a..e650795 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart
@@ -16,12 +16,12 @@
Future f;
// Instantiates Future<int>
-Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future::then*/ then(
+Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=Future.then*/ then(
/*@ returnType=MyFuture<int*>* */ (/*@ type=dynamic */ _) =>
new /*@ typeArgs=int* */ MyFuture.value('hi'));
// Instantiates List<int>
-Future<List<int>> t2 = f. /*@ typeArgs=List<int*>* */ /*@target=Future::then*/ then(
+Future<List<int>> t2 = f. /*@ typeArgs=List<int*>* */ /*@target=Future.then*/ then(
/*@ returnType=List<int*>* */ (/*@ type=dynamic */ _) => /*@ typeArgs=int* */ [3]);
Future<List<int>> g2() async {
return /*@ typeArgs=int* */ [3];
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart
index cba01a4..9ff51a2 100644
--- a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart
@@ -23,6 +23,6 @@
*/
new Foo<String>()
- . /*error:COULD_NOT_INFER*/ /*@ typeArgs=int* */ /*@target=Foo::method*/ method(
+ . /*error:COULD_NOT_INFER*/ /*@ typeArgs=int* */ /*@target=Foo.method*/ method(
42);
}
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
index 44273dd..a356982 100644
--- a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
@@ -2,11 +2,11 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart:26:80: Error: Inferred type argument 'int' doesn't conform to the bound 'String' of the type variable 'U' on 'Foo<String>.method'.
+// pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart:26:79: Error: Inferred type argument 'int' doesn't conform to the bound 'String' of the type variable 'U' on 'Foo<String>.method'.
// - 'Foo' is from 'pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart'.
// Try specifying type arguments explicitly so that they conform to the bounds.
-// . /*error:COULD_NOT_INFER*/ /*@ typeArgs=int* */ /*@target=Foo::method*/ method(
-// ^
+// . /*error:COULD_NOT_INFER*/ /*@ typeArgs=int* */ /*@target=Foo.method*/ method(
+// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart
index fc87629..8bb231c 100644
--- a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart
@@ -15,7 +15,7 @@
main() {
int y = /*info:DYNAMIC_CAST*/ new D()
- . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D::m*/ m<int>(
+ . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D.m*/ m<int>(
42);
print(y);
}
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.strong.expect
index 27cdc82..8c1bab7 100644
--- a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.strong.expect
@@ -17,9 +17,9 @@
// T m<T>(T x) => x;
// ^
//
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:18:74: Error: Expected 0 type arguments.
-// . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D::m*/ m<int>(
-// ^
+// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:18:73: Error: Expected 0 type arguments.
+// . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D.m*/ m<int>(
+// ^
//
import self as self;
import "dart:core" as core;
@@ -49,8 +49,8 @@
return x;
}
static method main() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:18:74: Error: Expected 0 type arguments.
- . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D::m*/ m<int>(
- ^" in new self::D::•().{self::D::m}<core::int*>(42);
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:18:73: Error: Expected 0 type arguments.
+ . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D.m*/ m<int>(
+ ^" in new self::D::•().{self::D::m}<core::int*>(42);
core::print(y);
}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart
index 96ad3cb..a5a2441 100644
--- a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart
@@ -7,13 +7,13 @@
void test() {
List<int> o;
- int y = o. /*@ typeArgs=int* */ /*@target=Iterable::fold*/ fold(
+ int y = o. /*@ typeArgs=int* */ /*@target=Iterable.fold*/ fold(
0,
/*@ returnType=int* */ (/*@ type=int* */ x,
/*@ type=int* */ y) =>
- x /*@target=num::+*/ + y);
+ x /*@target=num.+*/ + y);
var /*@ type=dynamic */ z =
- o. /*@ typeArgs=dynamic */ /*@target=Iterable::fold*/ fold(
+ o. /*@ typeArgs=dynamic */ /*@target=Iterable.fold*/ fold(
0,
/*@ returnType=dynamic */ (/*@ type=dynamic */ x,
/*@ type=int* */ y) => /*info:DYNAMIC_INVOKE*/ x + y);
@@ -22,13 +22,13 @@
void functionExpressionInvocation() {
List<int> o;
- int y = (o. /*@target=Iterable::fold*/ fold) /*@ typeArgs=int* */ (
+ int y = (o. /*@target=Iterable.fold*/ fold) /*@ typeArgs=int* */ (
0,
/*@ returnType=int* */ (/*@ type=int* */ x,
/*@ type=int* */ y) =>
- x /*@target=num::+*/ + y);
+ x /*@target=num.+*/ + y);
var /*@ type=dynamic */ z =
- (o. /*@target=Iterable::fold*/ fold) /*@ typeArgs=dynamic */ (
+ (o. /*@target=Iterable.fold*/ fold) /*@ typeArgs=dynamic */ (
0,
/*@ returnType=dynamic */ (/*@ type=dynamic */ x,
/*@ type=int* */ y) => /*info:DYNAMIC_INVOKE*/ x + y);
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart
index 5d9fa15..48404eb 100644
--- a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart
@@ -17,6 +17,6 @@
main() {
int y = /*info:DYNAMIC_CAST*/ (/*info:UNNECESSARY_CAST*/ new D() as C)
- . /*@target=C::m*/ m(42);
+ . /*@target=C.m*/ m(42);
print(y);
}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart
index 686d323..478b8f6 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart
@@ -49,15 +49,15 @@
takeOOO(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/ min);
// Also PropertyAccess
- takeIII(new C(). /*@target=C::m*/ m);
- takeDDD(new C(). /*@target=C::m*/ m);
- takeNNN(new C(). /*@target=C::m*/ m);
- takeIDN(new C(). /*@target=C::m*/ m);
- takeDIN(new C(). /*@target=C::m*/ m);
- takeIIN(new C(). /*@target=C::m*/ m);
- takeDDN(new C(). /*@target=C::m*/ m);
- takeIIO(new C(). /*@target=C::m*/ m);
- takeDDO(new C(). /*@target=C::m*/ m);
+ takeIII(new C(). /*@target=C.m*/ m);
+ takeDDD(new C(). /*@target=C.m*/ m);
+ takeNNN(new C(). /*@target=C.m*/ m);
+ takeIDN(new C(). /*@target=C.m*/ m);
+ takeDIN(new C(). /*@target=C.m*/ m);
+ takeIIN(new C(). /*@target=C.m*/ m);
+ takeDDN(new C(). /*@target=C.m*/ m);
+ takeIIO(new C(). /*@target=C.m*/ m);
+ takeDDO(new C(). /*@target=C.m*/ m);
// Note: this is a warning because a downcast of a method tear-off could work
// (derived method can be a subtype):
@@ -70,23 +70,23 @@
//
// We do issue the inference error though, similar to generic function calls.
takeOON(/*error:COULD_NOT_INFER,info:DOWN_CAST_COMPOSITE*/ new C()
- . /*@target=C::m*/ m);
+ . /*@target=C.m*/ m);
takeOOO(/*error:COULD_NOT_INFER,info:DOWN_CAST_COMPOSITE*/ new C()
- . /*@target=C::m*/ m);
+ . /*@target=C.m*/ m);
// Note: this is a warning because a downcast of a method tear-off could work
// in "normal" Dart, due to bivariance.
//
// We do issue the inference error though, similar to generic function calls.
takeOOI(/*error:COULD_NOT_INFER,info:DOWN_CAST_COMPOSITE*/ new C()
- . /*@target=C::m*/ m);
+ . /*@target=C.m*/ m);
takeIDI(
/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ new C()
- . /*@target=C::m*/ m);
+ . /*@target=C.m*/ m);
takeDID(
/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ new C()
- . /*@target=C::m*/ m);
+ . /*@target=C.m*/ m);
}
void takeIII(int fn(int a, int b)) {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
index aaae63a..af1436d 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
@@ -18,13 +18,13 @@
// takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
// ^
//
-// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-// . /*@target=C::m*/ m);
-// ^
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:29: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
+// . /*@target=C.m*/ m);
+// ^
//
-// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-// . /*@target=C::m*/ m);
-// ^
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:29: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
+// . /*@target=C.m*/ m);
+// ^
//
import self as self;
import "dart:core" as core;
@@ -98,12 +98,12 @@
self::takeOON((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
self::takeOOO((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
self::takeOOI((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::int*);
- self::takeIDI(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
- . /*@target=C::m*/ m);
- ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
- self::takeDID(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
- . /*@target=C::m*/ m);
- ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
+ self::takeIDI(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:29: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
+ . /*@target=C.m*/ m);
+ ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
+ self::takeDID(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:29: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
+ . /*@target=C.m*/ m);
+ ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
}
static method takeIII((core::int*, core::int*) →* core::int* fn) → void {}
static method takeDDD((core::double*, core::double*) →* core::double* fn) → void {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
index aaae63a..af1436d 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
@@ -18,13 +18,13 @@
// takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
// ^
//
-// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-// . /*@target=C::m*/ m);
-// ^
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:29: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
+// . /*@target=C.m*/ m);
+// ^
//
-// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-// . /*@target=C::m*/ m);
-// ^
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:29: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
+// . /*@target=C.m*/ m);
+// ^
//
import self as self;
import "dart:core" as core;
@@ -98,12 +98,12 @@
self::takeOON((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
self::takeOOO((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
self::takeOOI((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::int*);
- self::takeIDI(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
- . /*@target=C::m*/ m);
- ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
- self::takeDID(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
- . /*@target=C::m*/ m);
- ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
+ self::takeIDI(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:29: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
+ . /*@target=C.m*/ m);
+ ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
+ self::takeDID(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:29: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
+ . /*@target=C.m*/ m);
+ ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
}
static method takeIII((core::int*, core::int*) →* core::int* fn) → void {}
static method takeDDD((core::double*, core::double*) →* core::double* fn) → void {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart
index db2f883..79ae9b53 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart
@@ -14,6 +14,6 @@
}
main() {
- int y = new D(). /*@target=D::m*/ m<int>(42);
+ int y = new D(). /*@target=D.m*/ m<int>(42);
print(y);
}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.strong.transformed.expect
index 7b69eef..6e03570 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.strong.transformed.expect
@@ -22,7 +22,7 @@
static method test() → dynamic {
core::String* x = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:12:14: Error: Method not found: 'JS'.
String x = JS('int', '42'); // error
- ^^" as{TypeError,ForDynamic} core::String*;
+ ^^";
dynamic y = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:13:29: Error: Method not found: 'JS'.
var /*@type=dynamic*/ y = JS<String>('String', '\"hello\"');
^^";
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart
index 2a539d9..dbb0ffc 100644
--- a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart
@@ -7,7 +7,7 @@
void f() {
List<String> y;
- Iterable<String> x = y. /*@ typeArgs=String* */ /*@target=Iterable::map*/ map(
+ Iterable<String> x = y. /*@ typeArgs=String* */ /*@target=Iterable.map*/ map(
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@ returnType=String* */ (String
z) =>
1.0);
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart
index cc0946b..f8b311c 100644
--- a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart
@@ -12,37 +12,37 @@
test() {
Iterable<Future<int>> list = <int>[1, 2, 3]
- . /*@ typeArgs=Future<int*>* */ /*@target=Iterable::map*/ map(make);
+ . /*@ typeArgs=Future<int*>* */ /*@target=Iterable.map*/ map(make);
Future<List<int>> results = Future. /*@ typeArgs=int* */ wait(list);
Future<String> results2 =
- results. /*@ typeArgs=String* */ /*@target=Future::then*/ then(
+ results. /*@ typeArgs=String* */ /*@target=Future.then*/ then(
/*@ returnType=FutureOr<String*>* */ (List<int> list) => list
- . /*@ typeArgs=FutureOr<String*>* */ /*@target=Iterable::fold*/ fold(
+ . /*@ typeArgs=FutureOr<String*>* */ /*@target=Iterable.fold*/ fold(
'',
/*@ returnType=FutureOr<String*>* */ (/*@ type=FutureOr<String*>* */ x,
/*@ type=int* */ y) => /*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/ x /*error:UNDEFINED_OPERATOR*/ +
- y. /*@target=int::toString*/ toString()));
+ y. /*@target=int.toString*/ toString()));
Future<String> results3 =
- results. /*@ typeArgs=String* */ /*@target=Future::then*/ then(
+ results. /*@ typeArgs=String* */ /*@target=Future.then*/ then(
/*@ returnType=FutureOr<String*>* */ (List<int> list) => list
- . /*@ typeArgs=FutureOr<String*>* */ /*@target=Iterable::fold*/ fold(
+ . /*@ typeArgs=FutureOr<String*>* */ /*@target=Iterable.fold*/ fold(
'',
/*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@ returnType=String* */ (String
x,
/*@ type=int* */ y) =>
- x /*@target=String::+*/ +
- y. /*@target=int::toString*/ toString()));
+ x /*@target=String.+*/ +
+ y. /*@target=int.toString*/ toString()));
Future<String> results4 =
- results. /*@ typeArgs=String* */ /*@target=Future::then*/ then(
+ results. /*@ typeArgs=String* */ /*@target=Future.then*/ then(
/*@ returnType=String* */ (List<int> list) =>
- list. /*@target=Iterable::fold*/ fold<String>(
+ list. /*@target=Iterable.fold*/ fold<String>(
'',
/*@ returnType=String* */ (/*@ type=String* */ x,
/*@ type=int* */ y) =>
- x /*@target=String::+*/ +
- y. /*@target=int::toString*/ toString()));
+ x /*@target=String.+*/ +
+ y. /*@target=int.toString*/ toString()));
}
main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
index cdd5f42..e4d612d 100644
--- a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
@@ -28,7 +28,7 @@
- 'FutureOr' is from 'dart:async'.
Try correcting the operator to an existing operator, or defining a '+' operator.
/*@ type=int* */ y) => /*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/ x /*error:UNDEFINED_OPERATOR*/ +
- ^" as{TypeError,ForDynamic} asy::FutureOr<core::String*>*));
+ ^"));
asy::Future<core::String*>* results3 = results.{asy::Future::then}<core::String*>((core::List<core::int*>* list) → asy::FutureOr<core::String*>* => list.{core::Iterable::fold}<asy::FutureOr<core::String*>*>("", let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:111: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
- 'FutureOr' is from 'dart:async'.
/*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@ returnType=String* */ (String
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart
index 647867b..6d75b60 100644
--- a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart
@@ -18,13 +18,13 @@
main() {
List<Trace> traces = /*@ typeArgs=Trace* */ [];
var /*@ type=int* */ longest =
- traces. /*@ typeArgs=int* */ /*@target=Iterable::map*/ map(
+ traces. /*@ typeArgs=int* */ /*@target=Iterable.map*/ map(
/*@ returnType=int* */ (/*@ type=Trace* */ trace) {
- return trace. /*@target=Trace::frames*/ frames
- . /*@ typeArgs=int* */ /*@target=Iterable::map*/ map(
+ return trace. /*@target=Trace.frames*/ frames
+ . /*@ typeArgs=int* */ /*@target=Iterable.map*/ map(
/*@ returnType=int* */ (/*@ type=Frame* */ frame) => frame
- . /*@target=Frame::location*/ location
- . /*@target=String::length*/ length)
- . /*@ typeArgs=int* */ /*@target=Iterable::fold*/ fold(0, math.max);
- }). /*@ typeArgs=int* */ /*@target=Iterable::fold*/ fold(0, math.max);
+ . /*@target=Frame.location*/ location
+ . /*@target=String.length*/ length)
+ . /*@ typeArgs=int* */ /*@target=Iterable.fold*/ fold(0, math.max);
+ }). /*@ typeArgs=int* */ /*@target=Iterable.fold*/ fold(0, math.max);
}
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart
index 6d7ebaa..9d30b4d 100644
--- a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart
@@ -8,7 +8,7 @@
abstract class C<E> {
void sort([int compare(E a, E b)]) {
/*@ typeArgs=C::E* */ sort2(
- this, compare /*@ target=Object::== */ ?? _compareAny);
+ this, compare /*@target=Object.==*/ ?? _compareAny);
}
static int _compareAny(a, b) {
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
index b08798f..5c6cbefc 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
@@ -22,50 +22,50 @@
B member;
void test() {
- /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ /*@target=Test.member*/ member = /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ -- /*@target=Test::member*/ /*@target=Test::member*/
+ /*@target=B.-*/ -- /*@target=Test.member*/ /*@target=Test.member*/
member;
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::- */ --;
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.-*/ --;
- var /*@ type=B* */ v1 = /*@target=Test::member*/ member =
+ var /*@ type=B* */ v1 = /*@target=Test.member*/ member =
/*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = /*@target=Test::member*/ /*@target=Test::member*/
- member /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ var /*@ type=B* */ v2 = /*@target=Test.member*/ /*@target=Test.member*/
+ member /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = /*@target=Test::member*/ /*@target=Test::member*/
- member /*@ target=B::+ */ +=
+ var /*@ type=A* */ v3 = /*@target=Test.member*/ /*@target=Test.member*/
+ member /*@target=B.+*/ +=
/*@ typeArgs=C* */ f();
- var /*@ type=B* */ v4 = /*@target=Test::member*/ /*@target=Test::member*/
- member /*@ target=B::* */ *=
+ var /*@ type=B* */ v4 = /*@target=Test.member*/ /*@target=Test.member*/
+ member /*@target=B.**/ *=
/*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = /*@target=Test::member*/ /*@target=Test::member*/
- member /*@ target=B::& */ &=
+ var /*@ type=C* */ v5 = /*@target=Test.member*/ /*@target=Test.member*/
+ member /*@target=B.&*/ &=
/*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --
- /*@target=Test::member*/ /*@target=Test::member*/ member;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --
+ /*@target=Test.member*/ /*@target=Test.member*/ member;
var /*@ type=B* */ v7 =
- /*@ type=B* */ /*@target=Test::member*/ /*@target=Test::member*/
- /*@ type=B* */ member /*@ target=B::- */ --;
+ /*@ type=B* */ /*@target=Test.member*/ /*@target=Test.member*/
+ /*@ type=B* */ member /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
index 20d5671..0e92c67 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
@@ -13,20 +13,20 @@
int t;
void test() {
- var /*@ type=int* */ v1 = /*@target=Test1::t*/ t = getInt();
+ var /*@ type=int* */ v1 = /*@target=Test1.t*/ t = getInt();
- var /*@ type=int* */ v4 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
- /*@ target=num::== */ ??= getInt();
+ var /*@ type=int* */ v4 = /*@target=Test1.t*/ /*@target=Test1.t*/ t
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=int* */ v7 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
- /*@ target=num::+ */ += getInt();
+ var /*@ type=int* */ v7 = /*@target=Test1.t*/ /*@target=Test1.t*/ t
+ /*@target=num.+*/ += getInt();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++
- /*@target=Test1::t*/ /*@target=Test1::t*/ t;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++
+ /*@target=Test1.t*/ /*@target=Test1.t*/ t;
var /*@ type=int* */ v11 =
- /*@ type=int* */ /*@target=Test1::t*/ /*@target=Test1::t*/
- /*@ type=int* */ t /*@ target=num::+ */ ++;
+ /*@ type=int* */ /*@target=Test1.t*/ /*@target=Test1.t*/
+ /*@ type=int* */ t /*@target=num.+*/ ++;
}
}
@@ -34,36 +34,36 @@
num t;
void test() {
- var /*@ type=int* */ v1 = /*@target=Test2::t*/ t = getInt();
+ var /*@ type=int* */ v1 = /*@target=Test2.t*/ t = getInt();
- var /*@ type=num* */ v2 = /*@target=Test2::t*/ t = getNum();
+ var /*@ type=num* */ v2 = /*@target=Test2.t*/ t = getNum();
- var /*@ type=double* */ v3 = /*@target=Test2::t*/ t = getDouble();
+ var /*@ type=double* */ v3 = /*@target=Test2.t*/ t = getDouble();
- var /*@ type=num* */ v4 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::== */ ??= getInt();
+ var /*@ type=num* */ v4 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::== */ ??= getDouble();
+ var /*@ type=num* */ v6 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.==*/ ??= getDouble();
- var /*@ type=num* */ v7 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v7 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v9 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v9 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++
- /*@target=Test2::t*/ /*@target=Test2::t*/ t;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++
+ /*@target=Test2.t*/ /*@target=Test2.t*/ t;
var /*@ type=num* */ v11 =
- /*@ type=num* */ /*@target=Test2::t*/ /*@target=Test2::t*/
- /*@ type=num* */ t /*@ target=num::+ */ ++;
+ /*@ type=num* */ /*@target=Test2.t*/ /*@target=Test2.t*/
+ /*@ type=num* */ t /*@target=num.+*/ ++;
}
}
@@ -71,26 +71,26 @@
double t;
void test3() {
- var /*@ type=double* */ v3 = /*@target=Test3::t*/ t = getDouble();
+ var /*@ type=double* */ v3 = /*@target=Test3.t*/ t = getDouble();
- var /*@ type=double* */ v6 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=num::== */ ??= getDouble();
+ var /*@ type=double* */ v6 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=double.+*/ += getInt();
- var /*@ type=double* */ v8 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=double.+*/ += getNum();
- var /*@ type=double* */ v9 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=double::+ */ += getDouble();
+ var /*@ type=double* */ v9 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++
- /*@target=Test3::t*/ /*@target=Test3::t*/ t;
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++
+ /*@target=Test3.t*/ /*@target=Test3.t*/ t;
var /*@ type=double* */ v11 =
- /*@ type=double* */ /*@target=Test3::t*/ /*@target=Test3::t*/
- /*@ type=double* */ t /*@ target=double::+ */ ++;
+ /*@ type=double* */ /*@target=Test3.t*/ /*@target=Test3.t*/
+ /*@ type=double* */ t /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
index 8fe0a03..fd28327 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
@@ -27,54 +27,54 @@
void test() {
Test t = /*@ typeArgs=Test* */ f();
- t /*@target=Test::[]=*/ [
+ t /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- t /*@target=Test::[]*/ /*@ target=Test::[]= */ [/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=A.==*/
??= /*@ typeArgs=B* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()];
+ t /*@target=Test.[]*/ [/*@ typeArgs=Index* */ f()];
- /*@ target=B::- */ --t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@target=B.-*/ --t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()];
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
- var /*@ type=B* */ v1 = t /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v1 = t /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = t /*@target=Test::[]*/ /*@ target=Test::[]= */ [
+ var /*@ type=B* */ v2 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/
+ /*@target=A.==*/
??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v4 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=C* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()];
+ var /*@ type=B* */ v6 = t /*@target=Test.[]*/ [/*@ typeArgs=Index* */ f()];
var /*@ type=B* */ v7 =
- /*@ target=B::- */ --t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@target=B.-*/ --t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()];
- var /*@ type=B* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ var /*@ type=B* */ v8 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart
index c7ed576..6d17c33 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart
@@ -27,57 +27,57 @@
class Test extends Base {
void test() {
- super /*@target=Base::[]=*/ [
+ super /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@target=A::==*/
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=A.==*/
??= /*@ typeArgs=B* */ f();
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ /*@target=B.-*/ --super /*@target=Base.[]*/ /*@target=Base.[]=*/
[/*@ typeArgs=Index* */ f()];
- super /*@target=Base::[]*/ /*@target=Base::[]=*/
- [/*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
- var /*@ type=B* */ v1 = super /*@target=Base::[]=*/ [
+ var /*@ type=B* */ v1 = super /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@target=A::==*/
+ var /*@ type=B* */ v2 = super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=A.==*/
??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ var /*@ type=A* */ v3 = super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- var /*@ type=B* */ v4 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ var /*@ type=B* */ v4 = super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ var /*@ type=C* */ v5 = super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()];
var /*@ type=B* */ v7 = super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart
index b69e68e..d90f78d 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart
@@ -25,56 +25,56 @@
void operator []=(Index i, B v) {}
void test() {
- this /*@target=Test::[]=*/ [
+ this /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@target=A::==*/
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=A.==*/
??= /*@ typeArgs=B* */ f();
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::+ */
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.+*/
+= /*@ typeArgs=C* */ f();
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::* */
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.**/
*= /*@ typeArgs=B* */ f();
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::& */
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.&*/
&= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@target=B.-*/ --this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()];
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
- var /*@ type=B* */ v1 = this /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v1 = this /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@target=A::==*/
+ var /*@ type=B* */ v2 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=A.==*/
??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v4 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::+ */
+ var /*@ type=A* */ v4 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.+*/
+= /*@ typeArgs=C* */ f();
- var /*@ type=B* */ v3 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::* */
+ var /*@ type=B* */ v3 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.**/
*= /*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::& */
+ var /*@ type=C* */ v5 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.&*/
&= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --this
- /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --this
+ /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()];
- var /*@ type=B* */ v7 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ var /*@ type=B* */ v7 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart b/pkg/front_end/testcases/inference/infer_assign_to_local.dart
index 3fbf8b0..b649a92 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart
@@ -22,33 +22,33 @@
B local;
local = /*@ typeArgs=B* */ f();
- local /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ local /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ local /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ local /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ local /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --local;
+ /*@target=B.-*/ --local;
- local /*@ target=B::- */ --;
+ local /*@target=B.-*/ --;
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- local /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ local /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ var /*@ type=A* */ v3 = local /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- var /*@ type=B* */ v4 = local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ var /*@ type=B* */ v4 = local /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ var /*@ type=C* */ v5 = local /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --local;
var /*@ type=B* */ v7 = /*@ type=B* */ local
- /*@ type=B* */ /*@ target=B::- */ --;
+ /*@ type=B* */ /*@target=B.-*/ --;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
index 8619d3b..8e72109 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
@@ -12,14 +12,14 @@
void test1(int t) {
var /*@ type=int* */ v1 = t = getInt();
- var /*@ type=int* */ v4 = t /*@target=num::==*/ ??= getInt();
+ var /*@ type=int* */ v4 = t /*@target=num.==*/ ??= getInt();
- var /*@ type=int* */ v7 = t /*@target=num::+*/ += getInt();
+ var /*@ type=int* */ v7 = t /*@target=num.+*/ += getInt();
- var /*@ type=int* */ v10 = /*@target=num::+*/ ++t;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++t;
var /*@ type=int* */ v11 = /*@ type=int* */ t
- /*@ type=int* */ /*@target=num::+*/ ++;
+ /*@ type=int* */ /*@target=num.+*/ ++;
}
void test2(num t) {
@@ -29,39 +29,39 @@
var /*@ type=double* */ v3 = t = getDouble();
- var /*@ type=num* */ v4 = t /*@target=num::==*/ ??= getInt();
+ var /*@ type=num* */ v4 = t /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=num::==*/ ??= getDouble();
+ var /*@ type=num* */ v6 = t /*@target=num.==*/ ??= getDouble();
- var /*@ type=num* */ v7 = t /*@target=num::+*/ += getInt();
+ var /*@ type=num* */ v7 = t /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = t /*@target=num::+*/ += getNum();
+ var /*@ type=num* */ v8 = t /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v9 = t /*@target=num::+*/ += getDouble();
+ var /*@ type=num* */ v9 = t /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@target=num::+*/ ++t;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++t;
var /*@ type=num* */ v11 = /*@ type=num* */ t
- /*@ type=num* */ /*@target=num::+*/ ++;
+ /*@ type=num* */ /*@target=num.+*/ ++;
}
void test3(double t) {
var /*@ type=double* */ v3 = t = getDouble();
- var /*@ type=double* */ v6 = t /*@target=num::==*/ ??= getDouble();
+ var /*@ type=double* */ v6 = t /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 = t /*@target=double::+*/ += getInt();
+ var /*@ type=double* */ v7 = t /*@target=double.+*/ += getInt();
- var /*@ type=double* */ v8 = t /*@target=double::+*/ += getNum();
+ var /*@ type=double* */ v8 = t /*@target=double.+*/ += getNum();
- var /*@ type=double* */ v9 = t /*@target=double::+*/ += getDouble();
+ var /*@ type=double* */ v9 = t /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@target=double::+*/ ++t;
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++t;
var /*@ type=double* */ v11 = /*@ type=double* */ t
- /*@ type=double* */ /*@target=double::+*/ ++;
+ /*@ type=double* */ /*@target=double.+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart
index f94a25c..06d6032 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart
@@ -22,47 +22,42 @@
B member;
static void test(Test t) {
- t. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ -- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member;
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::- */ --;
+ t. /*@target=Test.member*/ member = /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
+ /*@target=B.-*/ -- /*@ type=Test* */ t
+ . /*@target=Test.member*/ /*@target=Test.member*/ member;
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.-*/ --;
var /*@ type=B* */ v1 =
- t. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ t. /*@target=Test.member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
/*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ . /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
/*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ . /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
/*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ . /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
/*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ -- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member;
+ . /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
+ var /*@ type=B* */ v6 = /*@target=B.-*/ -- /*@ type=Test* */ t
+ . /*@target=Test.member*/ /*@target=Test.member*/ member;
var /*@ type=B* */ v7 = /*@ type=Test* */ t
- . /*@ type=B* */ /*@target=Test::member*/ /*@target=Test::member*/
- /*@ type=B* */ member /*@ target=B::- */ --;
+ . /*@ type=B* */ /*@target=Test.member*/ /*@target=Test.member*/
+ /*@ type=B* */ member /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
index 51e7492..a0f5106 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
@@ -22,64 +22,64 @@
B member;
static void test(Test t) {
- /*@ type=Test* */ /*@target=Test::==*/ t?. /*@target=Test::member*/
+ /*@ type=Test* */ /*@target=Test.==*/ t?. /*@target=Test.member*/
member = /*@ typeArgs=B* */ f();
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ -- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member;
+ /*@target=B.-*/ -- /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member;
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::- */ --;
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.-*/ --;
var /*@ type=B* */ v1 =
- /*@ type=Test* */ /*@target=Test::==*/ t?. /*@target=Test::member*/
+ /*@ type=Test* */ /*@target=Test.==*/ t?. /*@target=Test.member*/
member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
var /*@ type=B* */ v6 =
- /*@ target=B::- */ -- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member;
+ /*@target=B.-*/ -- /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member;
var /*@ type=B* */ v7 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::- */ --;
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
index 7532de9..5e22e5e0 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
@@ -13,26 +13,26 @@
int prop;
static void test(Test1 t) {
- var /*@ type=int* */ v1 = /*@ type=Test1* */ /*@target=Test1::==*/ t
- ?. /*@target=Test1::prop*/ prop = getInt();
+ var /*@ type=int* */ v1 = /*@ type=Test1* */ /*@target=Test1.==*/ t
+ ?. /*@target=Test1.prop*/ prop = getInt();
var /*@ type=int* */ v4 =
- /*@target=Test1::==*/ t
- ?. /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@target=num::==*/ ??= getInt();
+ /*@target=Test1.==*/ t
+ ?. /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.==*/ ??= getInt();
var /*@ type=int* */ v7 =
- /*@target=Test1::==*/ t
- ?. /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@target=num::+*/ += getInt();
+ /*@target=Test1.==*/ t
+ ?. /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.+*/ += getInt();
- var /*@ type=int* */ v10 = /*@target=num::+*/ ++ /*@target=Test1::==*/ t
- ?. /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++ /*@target=Test1.==*/ t
+ ?. /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop;
var /*@ type=int* */ v11 =
- /*@target=Test1::==*/ t
- ?. /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@target=num::+*/ ++;
+ /*@target=Test1.==*/ t
+ ?. /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.+*/ ++;
}
}
@@ -40,51 +40,51 @@
num prop;
static void test(Test2 t) {
- var /*@ type=int* */ v1 = /*@ type=Test2* */ /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ prop = getInt();
+ var /*@ type=int* */ v1 = /*@ type=Test2* */ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ prop = getInt();
- var /*@ type=num* */ v2 = /*@ type=Test2* */ /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ prop = getNum();
+ var /*@ type=num* */ v2 = /*@ type=Test2* */ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ prop = getNum();
- var /*@ type=double* */ v3 = /*@ type=Test2* */ /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ prop = getDouble();
+ var /*@ type=double* */ v3 = /*@ type=Test2* */ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ prop = getDouble();
var /*@ type=num* */ v4 =
- /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getInt();
+ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getDouble();
+ var /*@ type=num* */ v6 = /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 =
- /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::+*/ += getInt();
+ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::+*/ += getNum();
+ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 =
- /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::+*/ += getDouble();
+ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@target=num::+*/ ++ /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop;
var /*@ type=num* */ v11 =
- /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::+*/ ++;
+ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ ++;
}
}
@@ -93,37 +93,37 @@
static void test3(Test3 t) {
var /*@ type=double* */ v3 =
- /*@ type=Test3* */ /*@target=Test3::==*/ t
- ?. /*@target=Test3::prop*/ prop = getDouble();
+ /*@ type=Test3* */ /*@target=Test3.==*/ t
+ ?. /*@target=Test3.prop*/ prop = getDouble();
var /*@ type=double* */ v6 =
- /*@target=Test3::==*/ t?.
- /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@target=num::==*/ ??= getDouble();
+ /*@target=Test3.==*/ t?.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 =
- /*@target=Test3::==*/ t
- ?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@target=double::+*/ += getInt();
+ /*@target=Test3.==*/ t
+ ?. /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 =
- /*@target=Test3::==*/ t
- ?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@target=double::+*/ += getNum();
+ /*@target=Test3.==*/ t
+ ?. /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 =
- /*@target=Test3::==*/ t?.
- /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@target=double::+*/ += getDouble();
+ /*@target=Test3.==*/ t?.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@target=double::+*/ ++
- /*@target=Test3::==*/ t
- ?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop;
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++
+ /*@target=Test3.==*/ t
+ ?. /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop;
var /*@ type=double* */ v11 =
- /*@target=Test3::==*/ t
- ?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@target=double::+*/ ++;
+ /*@target=Test3.==*/ t
+ ?. /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart
index 8e7eeb3..d316140 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart
@@ -24,52 +24,52 @@
class Test extends Base {
void test() {
- super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ member = /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --super
- . /*@target=Base::member*/ /*@target=Base::member*/ member;
+ /*@target=B.-*/ --super
+ . /*@target=Base.member*/ /*@target=Base.member*/ member;
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::- */ --;
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.-*/ --;
var /*@ type=B* */ v1 =
- super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
var /*@ type=B* */ v6 =
- /*@ target=B::- */ --super
- . /*@target=Base::member*/ /*@target=Base::member*/ member;
+ /*@target=B.-*/ --super
+ . /*@target=Base.member*/ /*@target=Base.member*/ member;
var /*@ type=B* */ v7 = super
- . /*@ type=B* */ /*@target=Base::member*/ /*@target=Base::member*/
- /*@ type=B* */ member /*@ target=B::- */ --;
+ . /*@ type=B* */ /*@target=Base.member*/ /*@target=Base.member*/
+ /*@ type=B* */ member /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart
index 9bda9ca..b4877f3 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart
@@ -18,98 +18,98 @@
class Test1 extends Base {
void test() {
var /*@ type=int* */ v1 =
- super. /*@target=Base::intProp*/ intProp = getInt();
+ super. /*@target=Base.intProp*/ intProp = getInt();
var /*@ type=int* */ v4 =
- super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
- /*@ target=num::==*/ ??= getInt();
+ super. /*@target=Base.intProp*/ /*@target=Base.intProp*/ intProp
+ /*@target=num.==*/ ??= getInt();
var /*@ type=int* */ v7 =
- super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
- /*@ target=num::+ */ += getInt();
+ super. /*@target=Base.intProp*/ /*@target=Base.intProp*/ intProp
+ /*@target=num.+*/ += getInt();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
- . /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++super
+ . /*@target=Base.intProp*/ /*@target=Base.intProp*/ intProp;
var /*@ type=int* */ v11 = super
- . /*@ type=int* */ /*@target=Base::intProp*/ /*@target=Base::intProp*/
- /*@ type=int* */ intProp /*@ target=num::+ */ ++;
+ . /*@ type=int* */ /*@target=Base.intProp*/ /*@target=Base.intProp*/
+ /*@ type=int* */ intProp /*@target=num.+*/ ++;
}
}
class Test2 extends Base {
void test() {
var /*@ type=int* */ v1 =
- super. /*@target=Base::numProp*/ numProp = getInt();
+ super. /*@target=Base.numProp*/ numProp = getInt();
var /*@ type=num* */ v2 =
- super. /*@target=Base::numProp*/ numProp = getNum();
+ super. /*@target=Base.numProp*/ numProp = getNum();
var /*@ type=double* */ v3 =
- super. /*@target=Base::numProp*/ numProp = getDouble();
+ super. /*@target=Base.numProp*/ numProp = getDouble();
var /*@ type=num* */ v4 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::==*/ ??= getInt();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::==*/ ??= getNum();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::==*/ ??= getDouble();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::+ */ += getInt();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::+ */ += getNum();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 = super
.
- /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::+ */ += getDouble();
+ /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
- . /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++super
+ . /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp;
var /*@ type=num* */ v11 = super
.
- /*@ type=num* */ /*@target=Base::numProp*/ /*@target=Base::numProp*/
- /*@ type=num* */ numProp /*@ target=num::+ */ ++;
+ /*@ type=num* */ /*@target=Base.numProp*/ /*@target=Base.numProp*/
+ /*@ type=num* */ numProp /*@target=num.+*/ ++;
}
}
class Test3 extends Base {
void test3() {
var /*@ type=double* */ v3 =
- super. /*@target=Base::doubleProp*/ doubleProp = getDouble();
+ super. /*@target=Base.doubleProp*/ doubleProp = getDouble();
var /*@ type=double* */ v6 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
- /*@ target=num::==*/ ??= getDouble();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/ doubleProp
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
- /*@ target=double::+ */ += getInt();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/ doubleProp
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
- /*@ target=double::+ */ += getNum();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/ doubleProp
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
- /*@ target=double::+ */ += getDouble();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/ doubleProp
+ /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp;
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++super
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/ doubleProp;
var /*@ type=double* */ v11 = super
- . /*@ type=double* */ /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
- /*@ type=double* */ doubleProp /*@ target=double::+ */ ++;
+ . /*@ type=double* */ /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/
+ /*@ type=double* */ doubleProp /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart
index 3928be0..46fbc47 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart
@@ -13,19 +13,18 @@
int prop;
static void test(Test1 t) {
- var /*@ type=int* */ v1 = t. /*@target=Test1::prop*/ prop = getInt();
+ var /*@ type=int* */ v1 = t. /*@target=Test1.prop*/ prop = getInt();
var /*@ type=int* */ v4 = /*@ type=Test1* */ t
- . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@target=num::==*/ ??= getInt();
+ . /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.==*/ ??= getInt();
var /*@ type=int* */ v7 =
- /*@ type=Test1* */ t
- . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@ target=num::+ */ += getInt();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++ /*@ type=Test1* */ t
- . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop;
+ /*@ type=Test1* */ t. /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.+*/ += getInt();
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++ /*@ type=Test1* */ t
+ . /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop;
var /*@ type=int* */ v11 = /*@ type=Test1* */ t
- . /*@ type=int* */ /*@target=Test1::prop*/ /*@target=Test1::prop*/
- /*@ type=int* */ prop /*@ target=num::+ */ ++;
+ . /*@ type=int* */ /*@target=Test1.prop*/ /*@target=Test1.prop*/
+ /*@ type=int* */ prop /*@target=num.+*/ ++;
}
}
@@ -33,35 +32,32 @@
num prop;
static void test(Test2 t) {
- var /*@ type=int* */ v1 = t. /*@target=Test2::prop*/ prop = getInt();
- var /*@ type=num* */ v2 = t. /*@target=Test2::prop*/ prop = getNum();
- var /*@ type=double* */ v3 = t. /*@target=Test2::prop*/ prop = getDouble();
+ var /*@ type=int* */ v1 = t. /*@target=Test2.prop*/ prop = getInt();
+ var /*@ type=num* */ v2 = t. /*@target=Test2.prop*/ prop = getNum();
+ var /*@ type=double* */ v3 = t. /*@target=Test2.prop*/ prop = getDouble();
var /*@ type=num* */ v4 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getInt();
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getNum();
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getDouble();
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 =
- /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ += getInt();
+ /*@ type=Test2* */ t. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ += getNum();
+ /*@ type=Test2* */ t. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 =
- /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++ /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop;
+ /*@ type=Test2* */ t. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getDouble();
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++ /*@ type=Test2* */ t
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop;
var /*@ type=num* */ v11 = /*@ type=Test2* */ t
- . /*@ type=num* */ /*@target=Test2::prop*/ /*@target=Test2::prop*/
- /*@ type=num* */ prop /*@ target=num::+ */ ++;
+ . /*@ type=num* */ /*@target=Test2.prop*/ /*@target=Test2.prop*/
+ /*@ type=num* */ prop /*@target=num.+*/ ++;
}
}
@@ -69,29 +65,25 @@
double prop;
static void test3(Test3 t) {
- var /*@ type=double* */ v3 = t. /*@target=Test3::prop*/ prop = getDouble();
+ var /*@ type=double* */ v3 = t. /*@target=Test3.prop*/ prop = getDouble();
var /*@ type=double* */ v6 =
- /*@ type=Test3* */ t. /*@target=Test3::prop*/ /*@target=Test3::prop*/
- prop /*@target=num::==*/ ??= getDouble();
+ /*@ type=Test3* */ t. /*@target=Test3.prop*/ /*@target=Test3.prop*/
+ prop /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 =
- /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getInt();
+ /*@ type=Test3* */ t. /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 =
- /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getNum();
+ /*@ type=Test3* */ t. /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 =
- /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++ /*@ type=Test3* */ t
- .
- /*@target=Test3::prop*/ /*@target=Test3::prop*/
+ /*@ type=Test3* */ t. /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getDouble();
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++ /*@ type=Test3* */ t.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/
prop;
var /*@ type=double* */ v11 = /*@ type=Test3* */ t.
- /*@ type=double* */ /*@target=Test3::prop*/ /*@target=Test3::prop*/
- /*@ type=double* */ prop /*@ target=double::+ */ ++;
+ /*@ type=double* */ /*@target=Test3.prop*/ /*@target=Test3.prop*/
+ /*@ type=double* */ prop /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart b/pkg/front_end/testcases/inference/infer_assign_to_static.dart
index 9021f82..3476095 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_static.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart
@@ -25,71 +25,71 @@
void test_topLevelVariable() {
topLevelVariable = /*@ typeArgs=B* */ f();
- topLevelVariable /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ topLevelVariable /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- topLevelVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ topLevelVariable /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- topLevelVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ topLevelVariable /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- topLevelVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ topLevelVariable /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --topLevelVariable;
+ /*@target=B.-*/ --topLevelVariable;
- topLevelVariable /*@ target=B::- */ --;
+ topLevelVariable /*@target=B.-*/ --;
var /*@ type=B* */ v1 = topLevelVariable = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- topLevelVariable /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ topLevelVariable /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- topLevelVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ topLevelVariable /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- topLevelVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ topLevelVariable /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- topLevelVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ topLevelVariable /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --topLevelVariable;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --topLevelVariable;
var /*@ type=B* */ v7 = /*@ type=B* */ topLevelVariable
- /*@ type=B* */ /*@ target=B::- */ --;
+ /*@ type=B* */ /*@target=B.-*/ --;
}
void test_staticVariable() {
B.staticVariable = /*@ typeArgs=B* */ f();
- B.staticVariable /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ B.staticVariable /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- B.staticVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ B.staticVariable /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- B.staticVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ B.staticVariable /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- B.staticVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ B.staticVariable /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --B.staticVariable;
+ /*@target=B.-*/ --B.staticVariable;
- B.staticVariable /*@ target=B::- */ --;
+ B.staticVariable /*@target=B.-*/ --;
var /*@ type=B* */ v1 = B.staticVariable = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- B.staticVariable /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ B.staticVariable /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- B.staticVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ B.staticVariable /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- B.staticVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ B.staticVariable /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- B.staticVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ B.staticVariable /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --B.staticVariable;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --B.staticVariable;
var /*@ type=B* */ v7 =
- B. /*@ type=B* */ staticVariable /*@ type=B* */ /*@ target=B::- */ --;
+ B. /*@ type=B* */ staticVariable /*@ type=B* */ /*@target=B.-*/ --;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart
index eb199fc..5025e5b 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart
@@ -16,14 +16,14 @@
void test1() {
var /*@ type=int* */ v1 = topLevelInt = getInt();
- var /*@ type=int* */ v4 = topLevelInt /*@ target=num::== */ ??= getInt();
+ var /*@ type=int* */ v4 = topLevelInt /*@target=num.==*/ ??= getInt();
- var /*@ type=int* */ v7 = topLevelInt /*@ target=num::+ */ += getInt();
+ var /*@ type=int* */ v7 = topLevelInt /*@target=num.+*/ += getInt();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++topLevelInt;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++topLevelInt;
var /*@ type=int* */ v11 = /*@ type=int* */ topLevelInt
- /*@ type=int* */ /*@ target=num::+ */ ++;
+ /*@ type=int* */ /*@target=num.+*/ ++;
}
void test2() {
@@ -33,43 +33,41 @@
var /*@ type=double* */ v3 = topLevelNum = getDouble();
- var /*@ type=num* */ v4 = topLevelNum /*@ target=num::== */ ??= getInt();
+ var /*@ type=num* */ v4 = topLevelNum /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = topLevelNum /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = topLevelNum /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = topLevelNum /*@ target=num::== */ ??= getDouble();
+ var /*@ type=num* */ v6 = topLevelNum /*@target=num.==*/ ??= getDouble();
- var /*@ type=num* */ v7 = topLevelNum /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v7 = topLevelNum /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = topLevelNum /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = topLevelNum /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v9 = topLevelNum /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v9 = topLevelNum /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++topLevelNum;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++topLevelNum;
var /*@ type=num* */ v11 = /*@ type=num* */ topLevelNum
- /*@ type=num* */ /*@ target=num::+ */ ++;
+ /*@ type=num* */ /*@target=num.+*/ ++;
}
void test3() {
var /*@ type=double* */ v3 = topLevelDouble = getDouble();
var /*@ type=double* */ v6 =
- topLevelDouble /*@ target=num::== */ ??= getDouble();
+ topLevelDouble /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 =
- topLevelDouble /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 = topLevelDouble /*@target=double.+*/ += getInt();
- var /*@ type=double* */ v8 =
- topLevelDouble /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 = topLevelDouble /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 =
- topLevelDouble /*@ target=double::+ */ += getDouble();
+ topLevelDouble /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++topLevelDouble;
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++topLevelDouble;
var /*@ type=double* */ v11 = /*@ type=double* */ topLevelDouble
- /*@ type=double* */ /*@ target=double::+ */ ++;
+ /*@ type=double* */ /*@target=double.+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_custom.dart b/pkg/front_end/testcases/inference/infer_binary_custom.dart
index d25eef7..b84b3ae 100644
--- a/pkg/front_end/testcases/inference/infer_binary_custom.dart
+++ b/pkg/front_end/testcases/inference/infer_binary_custom.dart
@@ -10,8 +10,8 @@
double operator -(other) => 2.0;
}
-var v_add = new A() /*@target=A::+*/ + 'foo';
-var v_minus = new A() /*@target=A::-*/ - 'bar';
+var v_add = new A() /*@target=A.+*/ + 'foo';
+var v_minus = new A() /*@target=A.-*/ - 'bar';
main() {
v_add;
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_double.dart b/pkg/front_end/testcases/inference/infer_binary_double_double.dart
index ad180e6..701ec6b 100644
--- a/pkg/front_end/testcases/inference/infer_binary_double_double.dart
+++ b/pkg/front_end/testcases/inference/infer_binary_double_double.dart
@@ -5,18 +5,18 @@
/*@testedFeatures=inference*/
library test;
-var a_equal = 1.0 /*@target=num::==*/ == 2.0;
-var a_notEqual = 1.0 /*@target=num::==*/ != 2.0;
-var a_add = 1.0 /*@target=double::+*/ + 2.0;
-var a_subtract = 1.0 /*@target=double::-*/ - 2.0;
-var a_multiply = 1.0 /*@target=double::**/ * 2.0;
-var a_divide = 1.0 /*@target=double::/ */ / 2.0;
-var a_floorDivide = 1.0 /*@target=double::~/ */ ~/ 2.0;
-var a_greater = 1.0 /*@target=num::>*/ > 2.0;
-var a_less = 1.0 /*@target=num::<*/ < 2.0;
-var a_greaterEqual = 1.0 /*@target=num::>=*/ >= 2.0;
-var a_lessEqual = 1.0 /*@target=num::<=*/ <= 2.0;
-var a_modulo = 1.0 /*@target=double::%*/ % 2.0;
+var a_equal = 1.0 /*@target=num.==*/ == 2.0;
+var a_notEqual = 1.0 /*@target=num.==*/ != 2.0;
+var a_add = 1.0 /*@target=double.+*/ + 2.0;
+var a_subtract = 1.0 /*@target=double.-*/ - 2.0;
+var a_multiply = 1.0 /*@target=double.**/ * 2.0;
+var a_divide = 1.0 /*@target=double./ */ / 2.0;
+var a_floorDivide = 1.0 /*@target=double.~/ */ ~/ 2.0;
+var a_greater = 1.0 /*@target=num.>*/ > 2.0;
+var a_less = 1.0 /*@target=num.<*/ < 2.0;
+var a_greaterEqual = 1.0 /*@target=num.>=*/ >= 2.0;
+var a_lessEqual = 1.0 /*@target=num.<=*/ <= 2.0;
+var a_modulo = 1.0 /*@target=double.%*/ % 2.0;
main() {
a_equal;
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_int.dart b/pkg/front_end/testcases/inference/infer_binary_double_int.dart
index 7794c6d..45f02a8 100644
--- a/pkg/front_end/testcases/inference/infer_binary_double_int.dart
+++ b/pkg/front_end/testcases/inference/infer_binary_double_int.dart
@@ -5,18 +5,18 @@
/*@testedFeatures=inference*/
library test;
-var a_equal = 1.0 /*@target=num::==*/ == 2;
-var a_notEqual = 1.0 /*@target=num::==*/ != 2;
-var a_add = 1.0 /*@target=double::+*/ + 2;
-var a_subtract = 1.0 /*@target=double::-*/ - 2;
-var a_multiply = 1.0 /*@target=double::**/ * 2;
-var a_divide = 1.0 /*@target=double::/ */ / 2;
-var a_floorDivide = 1.0 /*@target=double::~/ */ ~/ 2;
-var a_greater = 1.0 /*@target=num::>*/ > 2;
-var a_less = 1.0 /*@target=num::<*/ < 2;
-var a_greaterEqual = 1.0 /*@target=num::>=*/ >= 2;
-var a_lessEqual = 1.0 /*@target=num::<=*/ <= 2;
-var a_modulo = 1.0 /*@target=double::%*/ % 2;
+var a_equal = 1.0 /*@target=num.==*/ == 2;
+var a_notEqual = 1.0 /*@target=num.==*/ != 2;
+var a_add = 1.0 /*@target=double.+*/ + 2;
+var a_subtract = 1.0 /*@target=double.-*/ - 2;
+var a_multiply = 1.0 /*@target=double.**/ * 2;
+var a_divide = 1.0 /*@target=double./ */ / 2;
+var a_floorDivide = 1.0 /*@target=double.~/ */ ~/ 2;
+var a_greater = 1.0 /*@target=num.>*/ > 2;
+var a_less = 1.0 /*@target=num.<*/ < 2;
+var a_greaterEqual = 1.0 /*@target=num.>=*/ >= 2;
+var a_lessEqual = 1.0 /*@target=num.<=*/ <= 2;
+var a_modulo = 1.0 /*@target=double.%*/ % 2;
main() {
a_equal;
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_double.dart b/pkg/front_end/testcases/inference/infer_binary_int_double.dart
index 64d270f..f3a91cb 100644
--- a/pkg/front_end/testcases/inference/infer_binary_int_double.dart
+++ b/pkg/front_end/testcases/inference/infer_binary_int_double.dart
@@ -5,18 +5,18 @@
/*@testedFeatures=inference*/
library test;
-var a_equal = 1 /*@target=num::==*/ == 2.0;
-var a_notEqual = 1 /*@target=num::==*/ != 2.0;
-var a_add = 1 /*@target=num::+*/ + 2.0;
-var a_subtract = 1 /*@target=num::-*/ - 2.0;
-var a_multiply = 1 /*@target=num::**/ * 2.0;
-var a_divide = 1 /*@target=num::/ */ / 2.0;
-var a_floorDivide = 1 /*@target=num::~/ */ ~/ 2.0;
-var a_greater = 1 /*@target=num::>*/ > 2.0;
-var a_less = 1 /*@target=num::<*/ < 2.0;
-var a_greaterEqual = 1 /*@target=num::>=*/ >= 2.0;
-var a_lessEqual = 1 /*@target=num::<=*/ <= 2.0;
-var a_modulo = 1 /*@target=num::%*/ % 2.0;
+var a_equal = 1 /*@target=num.==*/ == 2.0;
+var a_notEqual = 1 /*@target=num.==*/ != 2.0;
+var a_add = 1 /*@target=num.+*/ + 2.0;
+var a_subtract = 1 /*@target=num.-*/ - 2.0;
+var a_multiply = 1 /*@target=num.**/ * 2.0;
+var a_divide = 1 /*@target=num./ */ / 2.0;
+var a_floorDivide = 1 /*@target=num.~/ */ ~/ 2.0;
+var a_greater = 1 /*@target=num.>*/ > 2.0;
+var a_less = 1 /*@target=num.<*/ < 2.0;
+var a_greaterEqual = 1 /*@target=num.>=*/ >= 2.0;
+var a_lessEqual = 1 /*@target=num.<=*/ <= 2.0;
+var a_modulo = 1 /*@target=num.%*/ % 2.0;
main() {
a_equal;
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_int.dart b/pkg/front_end/testcases/inference/infer_binary_int_int.dart
index 7283155..8176f7f 100644
--- a/pkg/front_end/testcases/inference/infer_binary_int_int.dart
+++ b/pkg/front_end/testcases/inference/infer_binary_int_int.dart
@@ -5,23 +5,23 @@
/*@testedFeatures=inference*/
library test;
-var a_equal = 1 /*@target=num::==*/ == 2;
-var a_notEqual = 1 /*@target=num::==*/ != 2;
-var a_bitXor = 1 /*@target=int::^*/ ^ 2;
-var a_bitAnd = 1 /*@target=int::&*/ & 2;
-var a_bitOr = 1 /*@target=int::|*/ | 2;
-var a_bitShiftRight = 1 /*@target=int::>>*/ >> 2;
-var a_bitShiftLeft = 1 /*@target=int::<<*/ << 2;
-var a_add = 1 /*@target=num::+*/ + 2;
-var a_subtract = 1 /*@target=num::-*/ - 2;
-var a_multiply = 1 /*@target=num::**/ * 2;
-var a_divide = 1 /*@target=num::/ */ / 2;
-var a_floorDivide = 1 /*@target=num::~/ */ ~/ 2;
-var a_greater = 1 /*@target=num::>*/ > 2;
-var a_less = 1 /*@target=num::<*/ < 2;
-var a_greaterEqual = 1 /*@target=num::>=*/ >= 2;
-var a_lessEqual = 1 /*@target=num::<=*/ <= 2;
-var a_modulo = 1 /*@target=num::%*/ % 2;
+var a_equal = 1 /*@target=num.==*/ == 2;
+var a_notEqual = 1 /*@target=num.==*/ != 2;
+var a_bitXor = 1 /*@target=int.^*/ ^ 2;
+var a_bitAnd = 1 /*@target=int.&*/ & 2;
+var a_bitOr = 1 /*@target=int.|*/ | 2;
+var a_bitShiftRight = 1 /*@target=int.>>*/ >> 2;
+var a_bitShiftLeft = 1 /*@target=int.<<*/ << 2;
+var a_add = 1 /*@target=num.+*/ + 2;
+var a_subtract = 1 /*@target=num.-*/ - 2;
+var a_multiply = 1 /*@target=num.**/ * 2;
+var a_divide = 1 /*@target=num./ */ / 2;
+var a_floorDivide = 1 /*@target=num.~/ */ ~/ 2;
+var a_greater = 1 /*@target=num.>*/ > 2;
+var a_less = 1 /*@target=num.<*/ < 2;
+var a_greaterEqual = 1 /*@target=num.>=*/ >= 2;
+var a_lessEqual = 1 /*@target=num.<=*/ <= 2;
+var a_modulo = 1 /*@target=num.%*/ % 2;
main() {
a_equal;
diff --git a/pkg/front_end/testcases/inference/infer_conditional.dart b/pkg/front_end/testcases/inference/infer_conditional.dart
index 26bc6ea..b707956 100644
--- a/pkg/front_end/testcases/inference/infer_conditional.dart
+++ b/pkg/front_end/testcases/inference/infer_conditional.dart
@@ -5,8 +5,8 @@
/*@testedFeatures=inference*/
library test;
-var a = 1 /*@target=num::==*/ == 2 ? 1 : 2.0;
-var b = 1 /*@target=num::==*/ == 2 ? 1.0 : 2;
+var a = 1 /*@target=num.==*/ == 2 ? 1 : 2.0;
+var b = 1 /*@target=num.==*/ == 2 ? 1.0 : 2;
main() {
a;
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart
index 4acae34..b1fca68 100644
--- a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart
@@ -17,15 +17,15 @@
String s;
int i;
- s = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
- s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
- s = new B(). /*@target=B::z*/ z;
- s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
+ s = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
+ s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.y*/ y;
+ s = new B(). /*@target=B.z*/ z;
+ s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.w*/ w;
- i = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
- i = new B(). /*@target=B::y*/ y;
- i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
- i = new B(). /*@target=B::w*/ w;
+ i = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
+ i = new B(). /*@target=B.y*/ y;
+ i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.z*/ z;
+ i = new B(). /*@target=B.w*/ w;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
index ffa41ac..92785eb 100644
--- a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
@@ -2,17 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
-// ^
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.y*/ y;
+// ^
//
-// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
-// ^
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.w*/ w;
+// ^
//
-// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
-// ^
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.z*/ z;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -58,18 +58,18 @@
core::String* s;
core::int* i;
s = new self::B::•().{self::B::x} as{TypeError,ForDynamic} core::String*;
- s = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
- ^" in new self::B::•().{self::B::y} as{TypeError} core::String*;
+ s = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.y*/ y;
+ ^" in new self::B::•().{self::B::y} as{TypeError} core::String*;
s = new self::B::•().{self::B::z};
- s = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
- ^" in new self::B::•().{self::B::w} as{TypeError} core::String*;
+ s = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.w*/ w;
+ ^" in new self::B::•().{self::B::w} as{TypeError} core::String*;
i = new self::B::•().{self::B::x} as{TypeError,ForDynamic} core::int*;
i = new self::B::•().{self::B::y};
- i = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
- ^" in new self::B::•().{self::B::z} as{TypeError} core::int*;
+ i = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.z*/ z;
+ ^" in new self::B::•().{self::B::z} as{TypeError} core::int*;
i = new self::B::•().{self::B::w};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
index ffa41ac..92785eb 100644
--- a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
@@ -2,17 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
-// ^
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.y*/ y;
+// ^
//
-// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
-// ^
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.w*/ w;
+// ^
//
-// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
-// ^
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.z*/ z;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -58,18 +58,18 @@
core::String* s;
core::int* i;
s = new self::B::•().{self::B::x} as{TypeError,ForDynamic} core::String*;
- s = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
- ^" in new self::B::•().{self::B::y} as{TypeError} core::String*;
+ s = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.y*/ y;
+ ^" in new self::B::•().{self::B::y} as{TypeError} core::String*;
s = new self::B::•().{self::B::z};
- s = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
- ^" in new self::B::•().{self::B::w} as{TypeError} core::String*;
+ s = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.w*/ w;
+ ^" in new self::B::•().{self::B::w} as{TypeError} core::String*;
i = new self::B::•().{self::B::x} as{TypeError,ForDynamic} core::int*;
i = new self::B::•().{self::B::y};
- i = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
- ^" in new self::B::•().{self::B::z} as{TypeError} core::int*;
+ i = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.z*/ z;
+ ^" in new self::B::•().{self::B::z} as{TypeError} core::int*;
i = new self::B::•().{self::B::w};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart
index a191aef..0dee028 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart
@@ -22,13 +22,13 @@
]; // list literals
var c2 = /*@typeArgs=dynamic*/ const [];
var d = <dynamic, dynamic>{'a': 'b'}; // map literals
-var e = new A().. /*@target=A::x*/ x = 3; // cascades
+var e = new A().. /*@target=A.x*/ x = 3; // cascades
var f =
- 2 /*@target=num::+*/ + 3; // binary expressions are OK if the left operand
+ 2 /*@target=num.+*/ + 3; // binary expressions are OK if the left operand
// is from a library in a different strongest
// connected component.
-var g = /*@target=int::unary-*/ -3;
-var h = new A() /*@target=A::+*/ + 3;
+var g = /*@target=int.unary-*/ -3;
+var h = new A() /*@target=A.+*/ + 3;
var i = /*error:UNDEFINED_OPERATOR,info:DYNAMIC_INVOKE*/ -new A();
var j = /*info:UNNECESSARY_CAST*/ null as B;
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
index e77093c..7dc9b4c 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
@@ -118,7 +118,7 @@
Try correcting the operator to an existing operator, or defining a 'unary-' operator.
var i = /*error:UNDEFINED_OPERATOR,info:DYNAMIC_INVOKE*/ -new A();
^";
-static field self::B* j = null as self::B*;
+static field self::B* j = null;
static method test1() → dynamic {
self::a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart
index 6226e35..20d13e8 100644
--- a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart
@@ -14,8 +14,8 @@
}
foo() {
- String y = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
- int z = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
+ String y = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
+ int z = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart
index 178c14a..f365cfa 100644
--- a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart
@@ -14,8 +14,8 @@
}
foo() {
- String y = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
- int z = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
+ String y = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
+ int z = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart
index 3d24e87..64bd487 100644
--- a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart
@@ -11,5 +11,5 @@
main() {
var /*@ type=double* */ y =
- new C(). /*@ typeArgs=double* */ /*@target=C::m*/ m(1, b: 'bbb', c: 2.0);
+ new C(). /*@ typeArgs=double* */ /*@target=C.m*/ m(1, b: 'bbb', c: 2.0);
}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart
index b2c869d..015ce09 100644
--- a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart
@@ -11,5 +11,5 @@
main() {
var /*@ type=double* */ y =
- new C(). /*@ typeArgs=double* */ /*@target=C::m*/ m(1, 2.0);
+ new C(). /*@ typeArgs=double* */ /*@target=C.m*/ m(1, 2.0);
}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart
index 7da1ab4..bee5566 100644
--- a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart
@@ -11,5 +11,5 @@
main() {
var /*@ type=double* */ y =
- new C(). /*@ typeArgs=double* */ /*@target=C::m*/ m(1, 'bbb', 2.0);
+ new C(). /*@ typeArgs=double* */ /*@target=C.m*/ m(1, 'bbb', 2.0);
}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart
index 76fa370..7300e53 100644
--- a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart
@@ -10,5 +10,5 @@
}
main() {
- var /*@ type=int* */ y = new C(). /*@ typeArgs=int* */ /*@target=C::m*/ m(42);
+ var /*@ type=int* */ y = new C(). /*@ typeArgs=int* */ /*@target=C.m*/ m(42);
}
diff --git a/pkg/front_end/testcases/inference/infer_method_function_typed.dart b/pkg/front_end/testcases/inference/infer_method_function_typed.dart
index 92b778d..4853f92 100644
--- a/pkg/front_end/testcases/inference/infer_method_function_typed.dart
+++ b/pkg/front_end/testcases/inference/infer_method_function_typed.dart
@@ -21,7 +21,7 @@
T f<T>() => null;
g(B b) {
- b. /*@target=B::x*/ x(/*@ typeArgs=() ->* dynamic */ f());
+ b. /*@target=B.x*/ x(/*@ typeArgs=() ->* dynamic */ f());
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression.dart b/pkg/front_end/testcases/inference/infer_prefix_expression.dart
index 0561e23..5c06bcc 100644
--- a/pkg/front_end/testcases/inference/infer_prefix_expression.dart
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression.dart
@@ -6,8 +6,8 @@
library test;
var a_not = !true;
-var a_complement = /*@target=int::~*/ ~1;
-var a_negate = /*@target=int::unary-*/ -1;
+var a_complement = /*@target=int.~*/ ~1;
+var a_negate = /*@target=int.unary-*/ -1;
main() {
a_not;
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart
index fe447a9..e0ac0b7 100644
--- a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart
@@ -12,8 +12,8 @@
}
var a = new A();
-var v_complement = /*@target=A::~*/ ~a;
-var v_negate = /*@target=A::unary-*/ -a;
+var v_complement = /*@target=A.~*/ ~a;
+var v_negate = /*@target=A.unary-*/ -a;
main() {
a;
diff --git a/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart
index 1fd2c2f..6e81a6d 100644
--- a/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart
+++ b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart
@@ -7,11 +7,11 @@
List<String> strings() {
var /*@ type=Iterable<String*>* */ stuff = /*@ typeArgs=dynamic */ []
- . /*@ typeArgs=String* */ /*@target=Iterable::expand*/ expand(
+ . /*@ typeArgs=String* */ /*@target=Iterable.expand*/ expand(
/*@ returnType=List<String*>* */ (/*@ type=dynamic */ i) {
return <String>[];
});
- return stuff. /*@target=Iterable::toList*/ toList();
+ return stuff. /*@target=Iterable.toList*/ toList();
}
main() {
diff --git a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart
index 63e77eb..2d53a08 100644
--- a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart
+++ b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart
@@ -21,7 +21,7 @@
T f<T>() => null;
g(B b) {
- b. /*@target=B::x*/ x = /*@ typeArgs=() ->* dynamic */ f();
+ b. /*@target=B.x*/ x = /*@ typeArgs=() ->* dynamic */ f();
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart
index 8e536dc..b8c2734 100644
--- a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart
@@ -17,5 +17,5 @@
main() {
// Ok because the setter accepts `Object`.
- new B(). /*@target=B::x*/ x = "hello";
+ new B(). /*@target=B.x*/ x = "hello";
}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart
index e203004..9d13c19 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart
@@ -14,8 +14,8 @@
}
foo() {
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- int z = new B(). /*@target=B::x*/ x;
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ int z = new B(). /*@target=B.x*/ x;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
index 9d37d48..8d35b5e 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -33,9 +33,9 @@
return 3;
}
static method foo() → dynamic {
- core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
+ core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
core::int* z = new self::B::•().{self::B::x};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
index 9d37d48..8d35b5e 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -33,9 +33,9 @@
return 3;
}
static method foo() → dynamic {
- core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
+ core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
core::int* z = new self::B::•().{self::B::x};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart
index 5dd2297..b8d1dcc 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart
@@ -14,8 +14,8 @@
}
foo() {
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- int z = new B(). /*@target=B::x*/ x;
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ int z = new B(). /*@target=B.x*/ x;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
index 3b22291..fc9974f 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -43,9 +43,9 @@
abstract member-signature get runtimeType() → core::Type*;
}
static method foo() → dynamic {
- core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
+ core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
core::int* z = new self::B::•().{self::B::x};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
index 3b22291..fc9974f 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -43,9 +43,9 @@
abstract member-signature get runtimeType() → core::Type*;
}
static method foo() → dynamic {
- core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
+ core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
core::int* z = new self::B::•().{self::B::x};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart
index 1ae4b97..9f68adc 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart
@@ -9,13 +9,13 @@
int x = 0;
test1() {
- var /*@ type=int* */ a = /*@target=A::x*/ x;
+ var /*@ type=int* */ a = /*@target=A.x*/ x;
a = /*error:INVALID_ASSIGNMENT*/ "hi";
a = 3;
- var /*@ type=int* */ b = /*@target=A::y*/ y;
+ var /*@ type=int* */ b = /*@target=A.y*/ y;
b = /*error:INVALID_ASSIGNMENT*/ "hi";
b = 4;
- var /*@ type=int* */ c = /*@target=A::z*/ z;
+ var /*@ type=int* */ c = /*@target=A.z*/ z;
c = /*error:INVALID_ASSIGNMENT*/ "hi";
c = 4;
}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart
index 6a235ad..895f48c 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart
@@ -16,8 +16,8 @@
}
foo() {
- int y = new C(). /*@target=C::x*/ x;
- String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
+ int y = new C(). /*@target=C.x*/ x;
+ String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
}
main() {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
index 5d0788c..a082667 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
+// ^
//
import self as self;
import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
@@ -38,9 +38,9 @@
}
static method foo() → dynamic {
core::int* y = new self::C::•().{self::C::x};
- core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
- ^" in new self::C::•().{self::C::x} as{TypeError} core::String*;
+ core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
+ ^" in new self::C::•().{self::C::x} as{TypeError} core::String*;
}
static method main() → dynamic {
self::foo();
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
index 5d0788c..a082667 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
+// ^
//
import self as self;
import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
@@ -38,9 +38,9 @@
}
static method foo() → dynamic {
core::int* y = new self::C::•().{self::C::x};
- core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
- ^" in new self::C::•().{self::C::x} as{TypeError} core::String*;
+ core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
+ ^" in new self::C::•().{self::C::x} as{TypeError} core::String*;
}
static method main() → dynamic {
self::foo();
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
index 2089092..e47f1a8 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
@@ -15,9 +15,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
+// ^
//
import self as test;
import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
@@ -51,9 +51,9 @@
}
static method foo() → dynamic {
core::int* y = new test::C::•().{test::C::x};
- core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
- ^" in new test::C::•().{test::C::x} as{TypeError} core::String*;
+ core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
+ ^" in new test::C::•().{test::C::x} as{TypeError} core::String*;
}
static method main() → dynamic {
test::foo();
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
index 2089092..e47f1a8 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
@@ -15,9 +15,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
+// ^
//
import self as test;
import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
@@ -51,9 +51,9 @@
}
static method foo() → dynamic {
core::int* y = new test::C::•().{test::C::x};
- core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
- ^" in new test::C::•().{test::C::x} as{TypeError} core::String*;
+ core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C.x*/ x;
+ ^" in new test::C::•().{test::C::x} as{TypeError} core::String*;
}
static method main() → dynamic {
test::foo();
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart
index c1be80c..a99ae3f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart
@@ -16,8 +16,8 @@
}
foo() {
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- int z = new B(). /*@target=B::x*/ x;
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ int z = new B(). /*@target=B.x*/ x;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
index 91a6c7e..d3a6b7f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
@@ -6,9 +6,9 @@
// get w => /*error:RETURN_OF_INVALID_TYPE*/ "hello";
// ^
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -52,9 +52,9 @@
abstract member-signature get runtimeType() → core::Type*;
}
static method foo() → dynamic {
- core::String* y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
+ core::String* y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
core::int* z = new self::B::•().{self::B::x};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
index 91a6c7e..d3a6b7f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
@@ -6,9 +6,9 @@
// get w => /*error:RETURN_OF_INVALID_TYPE*/ "hello";
// ^
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -52,9 +52,9 @@
abstract member-signature get runtimeType() → core::Type*;
}
static method foo() → dynamic {
- core::String* y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
- ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
+ core::String* y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:68: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B.x*/ x;
+ ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
core::int* z = new self::B::•().{self::B::x};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart
index 957177a..fc18874 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart
@@ -11,12 +11,12 @@
class B<E> extends A<E> {
E y;
- get x => /*@target=B::y*/ y;
+ get x => /*@target=B.y*/ y;
}
foo() {
- int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
- String z = new B<String>(). /*@target=B::x*/ x;
+ int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B.x*/ x;
+ String z = new B<String>(). /*@target=B.x*/ x;
}
main() {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
index d16a82c..1fd5661 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:73: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B.x*/ x;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -34,9 +34,9 @@
return this.{self::B::y};
}
static method foo() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
- ^" in new self::B::•<core::String*>().{self::B::x} as{TypeError} core::int*;
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:73: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B.x*/ x;
+ ^" in new self::B::•<core::String*>().{self::B::x} as{TypeError} core::int*;
core::String* z = new self::B::•<core::String*>().{self::B::x};
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
index d16a82c..1fd5661 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:73: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B.x*/ x;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -34,9 +34,9 @@
return this.{self::B::y};
}
static method foo() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
- ^" in new self::B::•<core::String*>().{self::B::x} as{TypeError} core::int*;
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:73: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B.x*/ x;
+ ^" in new self::B::•<core::String*>().{self::B::x} as{TypeError} core::int*;
core::String* z = new self::B::•<core::String*>().{self::B::x};
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart
index 5025679..ce6cdf5 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart
@@ -27,8 +27,8 @@
foo() {
int y = /*error:INVALID_ASSIGNMENT*/ new /*@typeArgs=dynamic*/ B()
- . /*@target=B::m*/ m(null, null);
- String z = new /*@typeArgs=dynamic*/ B(). /*@target=B::m*/ m(null, null);
+ . /*@target=B.m*/ m(null, null);
+ String z = new /*@typeArgs=dynamic*/ B(). /*@target=B.m*/ m(null, null);
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
index 64cc79b..f64e68d 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// . /*@target=B::m*/ m(null, null);
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:25: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// . /*@target=B.m*/ m(null, null);
+// ^
//
import self as self;
import "dart:core" as core;
@@ -66,9 +66,9 @@
method m(dynamic a, (dynamic, self::B::E*) →* dynamic f) → core::String* {}
}
static method foo() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- . /*@target=B::m*/ m(null, null);
- ^" in new self::B::•<dynamic>().{self::B::m}(null, null) as{TypeError} core::int*;
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:25: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ . /*@target=B.m*/ m(null, null);
+ ^" in new self::B::•<dynamic>().{self::B::m}(null, null) as{TypeError} core::int*;
core::String* z = new self::B::•<dynamic>().{self::B::m}(null, null);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
index 64cc79b..f64e68d 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// . /*@target=B::m*/ m(null, null);
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:25: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// . /*@target=B.m*/ m(null, null);
+// ^
//
import self as self;
import "dart:core" as core;
@@ -66,9 +66,9 @@
method m(dynamic a, (dynamic, self::B::E*) →* dynamic f) → core::String* {}
}
static method foo() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- . /*@target=B::m*/ m(null, null);
- ^" in new self::B::•<dynamic>().{self::B::m}(null, null) as{TypeError} core::int*;
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:25: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ . /*@target=B.m*/ m(null, null);
+ ^" in new self::B::•<dynamic>().{self::B::m}(null, null) as{TypeError} core::int*;
core::String* z = new self::B::•<dynamic>().{self::B::m}(null, null);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart
index 49235aa..3a437cf 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart
@@ -26,11 +26,10 @@
foo() {
int y = /*error:INVALID_ASSIGNMENT*/ new B<String>()
- . /*@target=B::m*/ m(null, null)
- . /*@target=A::value*/ value;
- String z = new B<String>()
- . /*@target=B::m*/ m(null, null)
- . /*@target=A::value*/ value;
+ . /*@target=B.m*/ m(null, null)
+ . /*@target=A.value*/ value;
+ String z =
+ new B<String>(). /*@target=B.m*/ m(null, null). /*@target=A.value*/ value;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
index 58bf956..3aef9b2 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// . /*@target=A::value*/ value;
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:29: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// . /*@target=A.value*/ value;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -53,9 +53,9 @@
method m(dynamic a, (dynamic, core::int*) →* dynamic f) → self::A<self::B::E*>* {}
}
static method foo() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- . /*@target=A::value*/ value;
- ^" in new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value} as{TypeError} core::int*;
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:29: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ . /*@target=A.value*/ value;
+ ^" in new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value} as{TypeError} core::int*;
core::String* z = new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
index 58bf956..3aef9b2 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
@@ -2,9 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// . /*@target=A::value*/ value;
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:29: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// . /*@target=A.value*/ value;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -53,9 +53,9 @@
method m(dynamic a, (dynamic, core::int*) →* dynamic f) → self::A<self::B::E*>* {}
}
static method foo() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- . /*@target=A::value*/ value;
- ^" in new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value} as{TypeError} core::int*;
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:29: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ . /*@target=A.value*/ value;
+ ^" in new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value} as{TypeError} core::int*;
core::String* z = new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
index 685eb09..386213d 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
@@ -27,9 +27,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// . /*@target=A::value*/ value;
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:29: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// . /*@target=A.value*/ value;
+// ^
//
import self as test;
import "dart:core" as core;
@@ -78,9 +78,9 @@
method m(dynamic a, (dynamic, core::int*) →* dynamic f) → test::A<test::B::E*>* {}
}
static method foo() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- . /*@target=A::value*/ value;
- ^" in new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value} as{TypeError} core::int*;
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:29: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ . /*@target=A.value*/ value;
+ ^" in new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value} as{TypeError} core::int*;
core::String* z = new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
index 685eb09..386213d 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
@@ -27,9 +27,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// . /*@target=A::value*/ value;
-// ^
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:29: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// . /*@target=A.value*/ value;
+// ^
//
import self as test;
import "dart:core" as core;
@@ -78,9 +78,9 @@
method m(dynamic a, (dynamic, core::int*) →* dynamic f) → test::A<test::B::E*>* {}
}
static method foo() → dynamic {
- core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- . /*@target=A::value*/ value;
- ^" in new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value} as{TypeError} core::int*;
+ core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:29: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ . /*@target=A.value*/ value;
+ ^" in new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value} as{TypeError} core::int*;
core::String* z = new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart
index 518852f..1ddaadb 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart
@@ -14,8 +14,8 @@
}
foo() {
- String y = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
- int z = /*info:DYNAMIC_CAST*/ new B(). /*@target=B::x*/ x;
+ String y = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
+ int z = /*info:DYNAMIC_CAST*/ new B(). /*@target=B.x*/ x;
}
main() {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart
index 6f21631..8d30352 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart
@@ -63,7 +63,7 @@
// We're not properly inferring that map.keys is an Iterable<String>
// and that x is a String.
- for (var /*@ type=String* */ x in map. /*@target=Map::keys*/ keys) {
+ for (var /*@ type=String* */ x in map. /*@target=Map.keys*/ keys) {
String y = x;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart
index 46e0672..e50a19d 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart
@@ -7,9 +7,9 @@
test() {
for (var /*@ type=int* */ i = 0;
- i /*@target=num::<*/ < 10;
- i /*@ target=num::+ */ ++) {
- int j = i /*@target=num::+*/ + 1;
+ i /*@target=num.<*/ < 10;
+ i /*@target=num.+*/ ++) {
+ int j = i /*@target=num.+*/ + 1;
}
}
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart b/pkg/front_end/testcases/inference/inferred_type_cascade.dart
index c7f21af..c5306d8 100644
--- a/pkg/front_end/testcases/inference/inferred_type_cascade.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart
@@ -12,8 +12,8 @@
}
var v = new A()
- .. /*@target=A::a*/ a = 1
- .. /*@target=A::b*/ b. /*@target=List::add*/ add(2)
- .. /*@target=A::m*/ m();
+ .. /*@target=A.a*/ a = 1
+ .. /*@target=A.b*/ b. /*@target=List.add*/ add(2)
+ .. /*@target=A.m*/ m();
main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart
index 776efe5..082a541 100644
--- a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart
@@ -10,7 +10,7 @@
}
C c = new C();
-var x = c /*@target=C::**/ * c;
+var x = c /*@target=C.**/ * c;
main() {
c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart
index 72a8365..0b7a8c6 100644
--- a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart
@@ -12,7 +12,7 @@
abstract class C implements I {}
C c;
-var x = c /*@target=I::**/ * c;
+var x = c /*@target=I.**/ * c;
main() {
c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart
index 6e3f1c4..f14fabf 100644
--- a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart
@@ -11,5 +11,5 @@
main() {
C c = new C();
- var /*@ type=bool* */ x = c /*@target=C::[]*/ [0];
+ var /*@ type=bool* */ x = c /*@target=C.[]*/ [0];
}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart
index 5d66da6..e5b29cd 100644
--- a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart
@@ -13,7 +13,7 @@
f() {
C c;
- var /*@ type=bool* */ x = c /*@target=I::[]*/ [0];
+ var /*@ type=bool* */ x = c /*@target=I.[]*/ [0];
}
main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart
index 26e560c..e5e734e 100644
--- a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart
@@ -10,7 +10,7 @@
}
C c = new C();
-var x = /*@target=C::unary-*/ -c;
+var x = /*@target=C.unary-*/ -c;
main() {
c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart
index db149d1..fe138eb 100644
--- a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart
@@ -12,7 +12,7 @@
abstract class C implements I {}
C c;
-var x = /*@target=I::unary-*/ -c;
+var x = /*@target=I.unary-*/ -c;
main() {
c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart
index 813e3cd..2779467 100644
--- a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart
@@ -10,6 +10,6 @@
}
C f() => null;
-var x = f(). /*@target=C::g*/ g;
+var x = f(). /*@target=C.g*/ g;
main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart
index b4874c6..a715e3d 100644
--- a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart
@@ -12,6 +12,6 @@
abstract class C implements I {}
C f() => null;
-var x = f(). /*@target=I::g*/ g;
+var x = f(). /*@target=I.g*/ g;
main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart
index 387aeff..de6ce68 100644
--- a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart
@@ -10,6 +10,6 @@
}
C f() => null;
-var x = f(). /*@target=C::g*/ g();
+var x = f(). /*@target=C.g*/ g();
main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart
index e31a0d3..03a17e8 100644
--- a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart
@@ -12,6 +12,6 @@
abstract class C implements I {}
C f() => null;
-var x = f(). /*@target=I::g*/ g();
+var x = f(). /*@target=I.g*/ g();
main() {}
diff --git a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart
index 4c3240d..4d4c90c 100644
--- a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart
+++ b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart
@@ -21,6 +21,6 @@
int get x => 0;
}
-var y = new C(). /*@target=C::x*/ x;
+var y = new C(). /*@target=C.x*/ x;
main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff.dart b/pkg/front_end/testcases/inference/instantiate_tearoff.dart
index 10eeb1f..b6ab9e0 100644
--- a/pkg/front_end/testcases/inference/instantiate_tearoff.dart
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff.dart
@@ -15,7 +15,7 @@
class D extends C {
void test() {
int Function(int) func;
- func = super. /*@target=C::f*/ f;
+ func = super. /*@target=C.f*/ f;
}
}
@@ -23,7 +23,7 @@
T h<T>(T x) => x;
int Function(int) func;
func = f;
- func = new C(). /*@target=C::f*/ f;
+ func = new C(). /*@target=C.f*/ f;
func = C.g;
func = h;
}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart
index 58437b6..d4a8217 100644
--- a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart
@@ -12,7 +12,7 @@
void test(C<String> c) {
// Tear-off of c.f needs to be type checked due to contravariance. The
// instantiation should occur after the type check.
- void Function(String) Function(int) tearoff = c. /*@target=C::f*/ f;
+ void Function(String) Function(int) tearoff = c. /*@target=C.f*/ f;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart
index 75c6ee2..679266e 100644
--- a/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart
+++ b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart
@@ -9,7 +9,7 @@
void foo() {
List myList = getListOfString();
- myList. /*@ typeArgs=int* */ /*@target=Iterable::map*/ map(
+ myList. /*@ typeArgs=int* */ /*@target=Iterable.map*/ map(
/*@ returnType=int* */ (/*@ type=dynamic */ type) => 42);
}
diff --git a/pkg/front_end/testcases/inference/lambda_void_context.dart b/pkg/front_end/testcases/inference/lambda_void_context.dart
index 96f67220..5929960 100644
--- a/pkg/front_end/testcases/inference/lambda_void_context.dart
+++ b/pkg/front_end/testcases/inference/lambda_void_context.dart
@@ -7,8 +7,8 @@
f() {
List<int> o;
- o. /*@target=Iterable::forEach*/ forEach(
- /*@ returnType=int* */ (/*@ type=int* */ i) => i /*@target=num::+*/ + 1);
+ o. /*@target=Iterable.forEach*/ forEach(
+ /*@ returnType=int* */ (/*@ type=int* */ i) => i /*@target=num.+*/ + 1);
}
main() {}
diff --git a/pkg/front_end/testcases/inference/list_literals.dart b/pkg/front_end/testcases/inference/list_literals.dart
index 64f3a1b..08e0240 100644
--- a/pkg/front_end/testcases/inference/list_literals.dart
+++ b/pkg/front_end/testcases/inference/list_literals.dart
@@ -7,16 +7,16 @@
test1() {
var /*@ type=List<int*>* */ x = /*@ typeArgs=int* */ [1, 2, 3];
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
- x. /*@target=List::add*/ add(4);
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+ x. /*@target=List.add*/ add(4);
List<num> y = x;
}
test2() {
var /*@ type=List<num*>* */ x = /*@ typeArgs=num* */ [1, 2.0, 3];
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- x. /*@target=List::add*/ add(4.0);
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ x. /*@target=List.add*/ add(4.0);
List<int> y = /*info:ASSIGNMENT_CAST*/ x;
}
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.strong.expect b/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
index 2c8a187..cf02cf7 100644
--- a/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
@@ -2,37 +2,37 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
-// ^
+// pkg/front_end/testcases/inference/list_literals.dart:10:70: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+// ^
//
-// pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
-// ^
+// pkg/front_end/testcases/inference/list_literals.dart:11:70: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+// ^
//
-// pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
-// ^
+// pkg/front_end/testcases/inference/list_literals.dart:18:70: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+// ^
//
import self as self;
import "dart:core" as core;
static method test1() → dynamic {
core::List<core::int*>* x = <core::int*>[1, 2, 3];
- x.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- ^" in "hi" as{TypeError} core::int*);
- x.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
- ^" in 4.0 as{TypeError} core::int*);
+ x.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:10:70: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ ^" in "hi" as{TypeError} core::int*);
+ x.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:11:70: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+ ^" in 4.0 as{TypeError} core::int*);
x.{core::List::add}(4);
core::List<core::num*>* y = x;
}
static method test2() → dynamic {
core::List<core::num*>* x = <core::num*>[1, 2.0, 3];
- x.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- ^" in "hi" as{TypeError} core::num*);
+ x.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:18:70: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ ^" in "hi" as{TypeError} core::num*);
x.{core::List::add}(4.0);
core::List<core::int*>* y = x as{TypeError} core::List<core::int*>*;
}
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
index 2c8a187..cf02cf7 100644
--- a/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
@@ -2,37 +2,37 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
-// ^
+// pkg/front_end/testcases/inference/list_literals.dart:10:70: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+// ^
//
-// pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
-// ^
+// pkg/front_end/testcases/inference/list_literals.dart:11:70: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+// ^
//
-// pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
-// ^
+// pkg/front_end/testcases/inference/list_literals.dart:18:70: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+// ^
//
import self as self;
import "dart:core" as core;
static method test1() → dynamic {
core::List<core::int*>* x = <core::int*>[1, 2, 3];
- x.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- ^" in "hi" as{TypeError} core::int*);
- x.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
- ^" in 4.0 as{TypeError} core::int*);
+ x.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:10:70: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ ^" in "hi" as{TypeError} core::int*);
+ x.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:11:70: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+ ^" in 4.0 as{TypeError} core::int*);
x.{core::List::add}(4);
core::List<core::num*>* y = x;
}
static method test2() → dynamic {
core::List<core::num*>* x = <core::num*>[1, 2.0, 3];
- x.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
- x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- ^" in "hi" as{TypeError} core::num*);
+ x.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:18:70: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+ x. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ ^" in "hi" as{TypeError} core::num*);
x.{core::List::add}(4.0);
core::List<core::int*>* y = x as{TypeError} core::List<core::int*>*;
}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart
index 52be7b9..405c751 100644
--- a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart
@@ -7,7 +7,7 @@
test1() {
var /*@ type=List<Null?>* */ x = /*@ typeArgs=Null? */ [null];
- x. /*@target=List::add*/ add(/*error:INVALID_CAST_LITERAL*/ 42);
+ x. /*@target=List.add*/ add(/*error:INVALID_CAST_LITERAL*/ 42);
}
main() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart b/pkg/front_end/testcases/inference/list_literals_top_level.dart
index bcd83e2..70a14e5 100644
--- a/pkg/front_end/testcases/inference/list_literals_top_level.dart
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart
@@ -7,16 +7,16 @@
var x1 = /*@ typeArgs=int* */ [1, 2, 3];
test1() {
- x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
- x1. /*@target=List::add*/ add(4);
+ x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+ x1. /*@target=List.add*/ add(4);
List<num> y = x1;
}
var x2 = /*@ typeArgs=num* */ [1, 2.0, 3];
test2() {
- x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- x2. /*@target=List::add*/ add(4.0);
+ x2. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ x2. /*@target=List.add*/ add(4.0);
List<int> y = /*info:ASSIGNMENT_CAST*/ x2;
}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
index e24becc..03e500a 100644
--- a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
@@ -2,17 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
-// ^
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+// ^
//
-// pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
-// ^
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+// ^
//
-// pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
-// ^
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// x2. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+// ^
//
import self as self;
import "dart:core" as core;
@@ -20,19 +20,19 @@
static field core::List<core::int*>* x1 = <core::int*>[1, 2, 3];
static field core::List<core::num*>* x2 = <core::num*>[1, 2.0, 3];
static method test1() → dynamic {
- self::x1.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
- x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- ^" in "hi" as{TypeError} core::int*);
- self::x1.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
- x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
- ^" in 4.0 as{TypeError} core::int*);
+ self::x1.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ ^" in "hi" as{TypeError} core::int*);
+ self::x1.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+ x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+ ^" in 4.0 as{TypeError} core::int*);
self::x1.{core::List::add}(4);
core::List<core::num*>* y = self::x1;
}
static method test2() → dynamic {
- self::x2.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
- x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- ^" in "hi" as{TypeError} core::num*);
+ self::x2.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+ x2. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ ^" in "hi" as{TypeError} core::num*);
self::x2.{core::List::add}(4.0);
core::List<core::int*>* y = self::x2 as{TypeError} core::List<core::int*>*;
}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
index e24becc..03e500a 100644
--- a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
@@ -2,17 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
-// ^
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+// ^
//
-// pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
-// ^
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+// ^
//
-// pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
-// ^
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// x2. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+// ^
//
import self as self;
import "dart:core" as core;
@@ -20,19 +20,19 @@
static field core::List<core::int*>* x1 = <core::int*>[1, 2, 3];
static field core::List<core::num*>* x2 = <core::num*>[1, 2.0, 3];
static method test1() → dynamic {
- self::x1.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
- x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- ^" in "hi" as{TypeError} core::int*);
- self::x1.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
- x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
- ^" in 4.0 as{TypeError} core::int*);
+ self::x1.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+ x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ ^" in "hi" as{TypeError} core::int*);
+ self::x1.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+ x1. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+ ^" in 4.0 as{TypeError} core::int*);
self::x1.{core::List::add}(4);
core::List<core::num*>* y = self::x1;
}
static method test2() → dynamic {
- self::x2.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
- x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
- ^" in "hi" as{TypeError} core::num*);
+ self::x2.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+ x2. /*@target=List.add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+ ^" in "hi" as{TypeError} core::num*);
self::x2.{core::List::add}(4.0);
core::List<core::int*>* y = self::x2 as{TypeError} core::List<core::int*>*;
}
diff --git a/pkg/front_end/testcases/inference/logical_or_promotion.dart b/pkg/front_end/testcases/inference/logical_or_promotion.dart
index 0719422..0efd379 100644
--- a/pkg/front_end/testcases/inference/logical_or_promotion.dart
+++ b/pkg/front_end/testcases/inference/logical_or_promotion.dart
@@ -15,7 +15,7 @@
void f(Object o) {
if (o is A || o is B) {
if (o is A) {
- /*@target=C::a*/ a = /*@ promotedType=A* */ o;
+ /*@target=C.a*/ a = /*@ promotedType=A* */ o;
}
}
}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart b/pkg/front_end/testcases/inference/map_literals.dart
index 6a851c4..e50d6d1 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart
+++ b/pkg/front_end/testcases/inference/map_literals.dart
@@ -7,12 +7,12 @@
test1() {
var /*@ type=Map<int*, String*>* */ x = /*@ typeArgs=int*, String* */ {1: 'x', 2: 'y'};
- x /*@target=Map::[]=*/ [3] = 'z';
- x /*@target=Map::[]=*/ [
+ x /*@target=Map.[]=*/ [3] = 'z';
+ x /*@target=Map.[]=*/ [
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
- x /*@target=Map::[]=*/ [
+ x /*@target=Map.[]=*/ [
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
- x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
Map<num, String> y = x;
}
@@ -22,13 +22,13 @@
2: 'y',
3.0: new RegExp('.')
};
- x /*@target=Map::[]=*/ [3] = 'z';
- x /*@target=Map::[]=*/ [
+ x /*@target=Map.[]=*/ [3] = 'z';
+ x /*@target=Map.[]=*/ [
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
- x /*@target=Map::[]=*/ [4.0] = 'u';
- x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ x /*@target=Map.[]=*/ [4.0] = 'u';
+ x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
Pattern p = null;
- x /*@target=Map::[]=*/ [2] = p;
+ x /*@target=Map.[]=*/ [2] = p;
Map<int, String> y = /*info:ASSIGNMENT_CAST*/ x;
}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
index 936f05f..25d74ad 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
@@ -10,18 +10,18 @@
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
-// ^
+// pkg/front_end/testcases/inference/map_literals.dart:15:60: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+// ^
//
// pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+// pkg/front_end/testcases/inference/map_literals.dart:29:60: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
// - 'Pattern' is from 'dart:core'.
-// x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
-// ^
+// x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -35,9 +35,9 @@
x.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
^" in 4.0 as{TypeError} core::int*, "u");
- x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
- ^" in 42 as{TypeError} core::String*);
+ x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:60: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ ^" in 42 as{TypeError} core::String*);
core::Map<core::num*, core::String*>* y = x;
}
static method test2() → dynamic {
@@ -47,10 +47,10 @@
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::num*, "w");
x.{core::Map::[]=}(4.0, "u");
- x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+ x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:60: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
- 'Pattern' is from 'dart:core'.
- x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
- ^" in 42 as{TypeError} core::Pattern*);
+ x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ ^" in 42 as{TypeError} core::Pattern*);
core::Pattern* p = null;
x.{core::Map::[]=}(2, p);
core::Map<core::int*, core::String*>* y = x as{TypeError} core::Map<core::int*, core::String*>*;
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
index 936f05f..25d74ad 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
@@ -10,18 +10,18 @@
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
-// ^
+// pkg/front_end/testcases/inference/map_literals.dart:15:60: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+// ^
//
// pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+// pkg/front_end/testcases/inference/map_literals.dart:29:60: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
// - 'Pattern' is from 'dart:core'.
-// x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
-// ^
+// x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -35,9 +35,9 @@
x.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
^" in 4.0 as{TypeError} core::int*, "u");
- x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
- ^" in 42 as{TypeError} core::String*);
+ x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:60: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ ^" in 42 as{TypeError} core::String*);
core::Map<core::num*, core::String*>* y = x;
}
static method test2() → dynamic {
@@ -47,10 +47,10 @@
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::num*, "w");
x.{core::Map::[]=}(4.0, "u");
- x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+ x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:60: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
- 'Pattern' is from 'dart:core'.
- x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
- ^" in 42 as{TypeError} core::Pattern*);
+ x /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ ^" in 42 as{TypeError} core::Pattern*);
core::Pattern* p = null;
x.{core::Map::[]=}(2, p);
core::Map<core::int*, core::String*>* y = x as{TypeError} core::Map<core::int*, core::String*>*;
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart
index 5cce7ec..744f9e2 100644
--- a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart
@@ -7,7 +7,7 @@
test1() {
var /*@ type=Map<Null?, Null?>* */ x = /*@ typeArgs=Null?, Null? */ {null: null};
- x /*@target=Map::[]=*/ [
+ x /*@target=Map.[]=*/ [
/*error:INVALID_CAST_LITERAL*/ 3] = /*error:INVALID_CAST_LITERAL*/ 'z';
}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart b/pkg/front_end/testcases/inference/map_literals_top_level.dart
index a9338a3..362c81b 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart
@@ -7,21 +7,21 @@
var x1 = /*@ typeArgs=int*, String* */ {1: 'x', 2: 'y'};
test1() {
- x1 /*@target=Map::[]=*/ [3] = 'z';
- x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
- x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
- x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ x1 /*@target=Map.[]=*/ [3] = 'z';
+ x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+ x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+ x1 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
Map<num, String> y = x1;
}
var x2 = /*@ typeArgs=num*, Pattern* */ {1: 'x', 2: 'y', 3.0: new RegExp('.')};
test2() {
- x2 /*@target=Map::[]=*/ [3] = 'z';
- x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
- x2 /*@target=Map::[]=*/ [4.0] = 'u';
- x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ x2 /*@target=Map.[]=*/ [3] = 'z';
+ x2 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+ x2 /*@target=Map.[]=*/ [4.0] = 'u';
+ x2 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
Pattern p = null;
- x2 /*@target=Map::[]=*/ [2] = p;
+ x2 /*@target=Map.[]=*/ [2] = p;
Map<int, String> y = /*info:ASSIGNMENT_CAST*/ x2;
}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
index edf1acd..e7d7a55 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
@@ -2,26 +2,26 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
-// ^
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:11:66: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
-// ^
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:12:66: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
-// ^
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:13:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// x1 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
-// ^
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:20:66: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
+// x2 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:22:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
// - 'Pattern' is from 'dart:core'.
-// x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
-// ^
+// x2 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -30,27 +30,27 @@
static field core::Map<core::num*, core::Pattern*>* x2 = <core::num*, core::Pattern*>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
static method test1() → dynamic {
self::x1.{core::Map::[]=}(3, "z");
- self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
- ^" in "hi" as{TypeError} core::int*, "w");
- self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
- ^" in 4.0 as{TypeError} core::int*, "u");
- self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
- ^" in 42 as{TypeError} core::String*);
+ self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:66: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+ ^" in "hi" as{TypeError} core::int*, "w");
+ self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:66: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+ ^" in 4.0 as{TypeError} core::int*, "u");
+ self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ x1 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ ^" in 42 as{TypeError} core::String*);
core::Map<core::num*, core::String*>* y = self::x1;
}
static method test2() → dynamic {
self::x2.{core::Map::[]=}(3, "z");
- self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
- x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
- ^" in "hi" as{TypeError} core::num*, "w");
+ self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:66: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
+ x2 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+ ^" in "hi" as{TypeError} core::num*, "w");
self::x2.{core::Map::[]=}(4.0, "u");
- self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+ self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
- 'Pattern' is from 'dart:core'.
- x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
- ^" in 42 as{TypeError} core::Pattern*);
+ x2 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ ^" in 42 as{TypeError} core::Pattern*);
core::Pattern* p = null;
self::x2.{core::Map::[]=}(2, p);
core::Map<core::int*, core::String*>* y = self::x2 as{TypeError} core::Map<core::int*, core::String*>*;
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
index edf1acd..e7d7a55 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
@@ -2,26 +2,26 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
-// ^
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:11:66: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
-// ^
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:12:66: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
-// ^
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:13:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// x1 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
-// ^
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:20:66: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
+// x2 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:22:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
// - 'Pattern' is from 'dart:core'.
-// x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
-// ^
+// x2 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -30,27 +30,27 @@
static field core::Map<core::num*, core::Pattern*>* x2 = <core::num*, core::Pattern*>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
static method test1() → dynamic {
self::x1.{core::Map::[]=}(3, "z");
- self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
- ^" in "hi" as{TypeError} core::int*, "w");
- self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
- ^" in 4.0 as{TypeError} core::int*, "u");
- self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
- x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
- ^" in 42 as{TypeError} core::String*);
+ self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:66: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+ ^" in "hi" as{TypeError} core::int*, "w");
+ self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:66: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ x1 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+ ^" in 4.0 as{TypeError} core::int*, "u");
+ self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+ x1 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ ^" in 42 as{TypeError} core::String*);
core::Map<core::num*, core::String*>* y = self::x1;
}
static method test2() → dynamic {
self::x2.{core::Map::[]=}(3, "z");
- self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
- x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
- ^" in "hi" as{TypeError} core::num*, "w");
+ self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:66: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
+ x2 /*@target=Map.[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+ ^" in "hi" as{TypeError} core::num*, "w");
self::x2.{core::Map::[]=}(4.0, "u");
- self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+ self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
- 'Pattern' is from 'dart:core'.
- x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
- ^" in 42 as{TypeError} core::Pattern*);
+ x2 /*@target=Map.[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+ ^" in 42 as{TypeError} core::Pattern*);
core::Pattern* p = null;
self::x2.{core::Map::[]=}(2, p);
core::Map<core::int*, core::String*>* y = self::x2 as{TypeError} core::Map<core::int*, core::String*>*;
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart
index a1490d6..15727c0 100644
--- a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart
@@ -11,6 +11,6 @@
class D<T> {}
-var f = new C(). /*@target=C::f*/ f<int>();
+var f = new C(). /*@target=C.f*/ f<int>();
main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart
index 3b57d56..3f59db8 100644
--- a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart
@@ -12,6 +12,6 @@
class D<T> {}
C c;
-var f = c. /*@target=C::f*/ f<int>();
+var f = c. /*@target=C.f*/ f<int>();
main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart
index 650c578..d1d0d9c 100644
--- a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart
@@ -10,9 +10,9 @@
}
g(C c) {
- var /*@ type=int* */ x = /*@ type=C* */ /*@target=C::==*/ c
- ?. /*@target=C::f*/ f();
- /*@ type=C* */ /*@target=C::==*/ c?. /*@target=C::f*/ f();
+ var /*@ type=int* */ x = /*@ type=C* */ /*@target=C.==*/ c
+ ?. /*@target=C.f*/ f();
+ /*@ type=C* */ /*@target=C.==*/ c?. /*@target=C.f*/ f();
}
main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart b/pkg/front_end/testcases/inference/null_aware_property_get.dart
index 7297335..d5f2175 100644
--- a/pkg/front_end/testcases/inference/null_aware_property_get.dart
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart
@@ -10,9 +10,9 @@
}
void f(C c) {
- var /*@ type=int* */ x = /*@ type=C* */ /*@target=C::==*/ c
- ?. /*@target=C::x*/ x;
- /*@ type=C* */ /*@target=C::==*/ c?. /*@target=C::x*/ x;
+ var /*@ type=int* */ x = /*@ type=C* */ /*@target=C.==*/ c
+ ?. /*@target=C.x*/ x;
+ /*@ type=C* */ /*@target=C.==*/ c?. /*@target=C.x*/ x;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart b/pkg/front_end/testcases/inference/null_coalescing_operator.dart
index bbf853c..6ea5820 100644
--- a/pkg/front_end/testcases/inference/null_coalescing_operator.dart
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart
@@ -8,6 +8,6 @@
main() {
List<int> x;
var /*@ type=List<int*>* */ y =
- x /*@ target=List::== */ ?? /*@ typeArgs=int* */ [];
+ x /*@target=List.==*/ ?? /*@ typeArgs=int* */ [];
List<int> z = y;
}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart
index 0836850..3ade64d 100644
--- a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart
@@ -7,5 +7,5 @@
main() {
List<int> x;
- List<num> y = x /*@ target=List::== */ ?? /*@ typeArgs=num* */ [];
+ List<num> y = x /*@target=List.==*/ ?? /*@ typeArgs=num* */ [];
}
diff --git a/pkg/front_end/testcases/inference/overloaded_int_operators.dart b/pkg/front_end/testcases/inference/overloaded_int_operators.dart
index 64d74b4..cb5a0c2a 100644
--- a/pkg/front_end/testcases/inference/overloaded_int_operators.dart
+++ b/pkg/front_end/testcases/inference/overloaded_int_operators.dart
@@ -11,56 +11,56 @@
double d = 1.0;
// (double, double) -> double
- var /*@ type=double* */ ddPlus = d /*@target=double::+*/ + d;
- var /*@ type=double* */ ddMinus = d /*@target=double::-*/ - d;
- var /*@ type=double* */ ddTimes = d /*@target=double::**/ * d;
- var /*@ type=double* */ ddMod = d /*@target=double::%*/ % d;
+ var /*@ type=double* */ ddPlus = d /*@target=double.+*/ + d;
+ var /*@ type=double* */ ddMinus = d /*@target=double.-*/ - d;
+ var /*@ type=double* */ ddTimes = d /*@target=double.**/ * d;
+ var /*@ type=double* */ ddMod = d /*@target=double.%*/ % d;
// (double, int) -> double
- var /*@ type=double* */ diPlus = d /*@target=double::+*/ + i;
- var /*@ type=double* */ diMinus = d /*@target=double::-*/ - i;
- var /*@ type=double* */ diTimes = d /*@target=double::**/ * i;
- var /*@ type=double* */ diMod = d /*@target=double::%*/ % i;
+ var /*@ type=double* */ diPlus = d /*@target=double.+*/ + i;
+ var /*@ type=double* */ diMinus = d /*@target=double.-*/ - i;
+ var /*@ type=double* */ diTimes = d /*@target=double.**/ * i;
+ var /*@ type=double* */ diMod = d /*@target=double.%*/ % i;
// (double, num) -> double
- var /*@ type=double* */ dnPlus = d /*@target=double::+*/ + n;
- var /*@ type=double* */ dnMinus = d /*@target=double::-*/ - n;
- var /*@ type=double* */ dnTimes = d /*@target=double::**/ * n;
- var /*@ type=double* */ dnMod = d /*@target=double::%*/ % n;
+ var /*@ type=double* */ dnPlus = d /*@target=double.+*/ + n;
+ var /*@ type=double* */ dnMinus = d /*@target=double.-*/ - n;
+ var /*@ type=double* */ dnTimes = d /*@target=double.**/ * n;
+ var /*@ type=double* */ dnMod = d /*@target=double.%*/ % n;
// (int, double) -> double
- var /*@ type=double* */ idPlus = i /*@target=num::+*/ + d;
- var /*@ type=double* */ idMinus = i /*@target=num::-*/ - d;
- var /*@ type=double* */ idTimes = i /*@target=num::**/ * d;
- var /*@ type=double* */ idMod = i /*@target=num::%*/ % d;
+ var /*@ type=double* */ idPlus = i /*@target=num.+*/ + d;
+ var /*@ type=double* */ idMinus = i /*@target=num.-*/ - d;
+ var /*@ type=double* */ idTimes = i /*@target=num.**/ * d;
+ var /*@ type=double* */ idMod = i /*@target=num.%*/ % d;
// (int, int) -> int
- var /*@ type=int* */ iiPlus = i /*@target=num::+*/ + i;
- var /*@ type=int* */ iiMinus = i /*@target=num::-*/ - i;
- var /*@ type=int* */ iiTimes = i /*@target=num::**/ * i;
- var /*@ type=int* */ iiMod = i /*@target=num::%*/ % i;
+ var /*@ type=int* */ iiPlus = i /*@target=num.+*/ + i;
+ var /*@ type=int* */ iiMinus = i /*@target=num.-*/ - i;
+ var /*@ type=int* */ iiTimes = i /*@target=num.**/ * i;
+ var /*@ type=int* */ iiMod = i /*@target=num.%*/ % i;
// (int, num) -> num
- var /*@ type=num* */ inPlus = i /*@target=num::+*/ + n;
- var /*@ type=num* */ inMinus = i /*@target=num::-*/ - n;
- var /*@ type=num* */ inTimes = i /*@target=num::**/ * n;
- var /*@ type=num* */ inMod = i /*@target=num::%*/ % n;
+ var /*@ type=num* */ inPlus = i /*@target=num.+*/ + n;
+ var /*@ type=num* */ inMinus = i /*@target=num.-*/ - n;
+ var /*@ type=num* */ inTimes = i /*@target=num.**/ * n;
+ var /*@ type=num* */ inMod = i /*@target=num.%*/ % n;
// (num, double) -> num
- var /*@ type=num* */ ndPlus = n /*@target=num::+*/ + d;
- var /*@ type=num* */ ndMinus = n /*@target=num::-*/ - d;
- var /*@ type=num* */ ndTimes = n /*@target=num::**/ * d;
- var /*@ type=num* */ ndMod = n /*@target=num::%*/ % d;
+ var /*@ type=num* */ ndPlus = n /*@target=num.+*/ + d;
+ var /*@ type=num* */ ndMinus = n /*@target=num.-*/ - d;
+ var /*@ type=num* */ ndTimes = n /*@target=num.**/ * d;
+ var /*@ type=num* */ ndMod = n /*@target=num.%*/ % d;
// (num, int) -> num
- var /*@ type=num* */ niPlus = n /*@target=num::+*/ + i;
- var /*@ type=num* */ niMinus = n /*@target=num::-*/ - i;
- var /*@ type=num* */ niTimes = n /*@target=num::**/ * i;
- var /*@ type=num* */ niMod = n /*@target=num::%*/ % i;
+ var /*@ type=num* */ niPlus = n /*@target=num.+*/ + i;
+ var /*@ type=num* */ niMinus = n /*@target=num.-*/ - i;
+ var /*@ type=num* */ niTimes = n /*@target=num.**/ * i;
+ var /*@ type=num* */ niMod = n /*@target=num.%*/ % i;
// (num, num) -> num
- var /*@ type=num* */ nnPlus = n /*@target=num::+*/ + n;
- var /*@ type=num* */ nnMinus = n /*@target=num::-*/ - n;
- var /*@ type=num* */ nnTimes = n /*@target=num::**/ * n;
- var /*@ type=num* */ nnMod = n /*@target=num::%*/ % n;
+ var /*@ type=num* */ nnPlus = n /*@target=num.+*/ + n;
+ var /*@ type=num* */ nnMinus = n /*@target=num.-*/ - n;
+ var /*@ type=num* */ nnTimes = n /*@target=num.**/ * n;
+ var /*@ type=num* */ nnMod = n /*@target=num.%*/ % n;
}
diff --git a/pkg/front_end/testcases/inference/override_equals.dart b/pkg/front_end/testcases/inference/override_equals.dart
index 02ad16f..b8ec051 100644
--- a/pkg/front_end/testcases/inference/override_equals.dart
+++ b/pkg/front_end/testcases/inference/override_equals.dart
@@ -13,27 +13,27 @@
class SubNullEquality extends NullEquality {
void test() {
var /*@ type=bool* */ super_equals_self =
- super /*@target=NullEquality::==*/ == this;
+ super /*@target=NullEquality.==*/ == this;
var /*@ type=bool* */ super_equals_null =
- super /*@target=NullEquality::==*/ == null;
+ super /*@target=NullEquality.==*/ == null;
var /*@ type=bool* */ super_not_equals_self =
- super /*@target=NullEquality::==*/ != this;
+ super /*@target=NullEquality.==*/ != this;
var /*@ type=bool* */ super_not_equals_null =
- super /*@target=NullEquality::==*/ != null;
+ super /*@target=NullEquality.==*/ != null;
}
}
test() {
NullEquality n = new NullEquality();
- var /*@ type=bool* */ equals_self = n /*@target=NullEquality::==*/ == n;
- var /*@ type=bool* */ equals_null = n /*@target=NullEquality::==*/ == null;
- var /*@ type=bool* */ null_equals = null /*@target=Object::==*/ == n;
- var /*@ type=bool* */ not_equals_self = n /*@target=NullEquality::==*/ != n;
- var /*@ type=bool* */ not_equals_null = n /*@target=NullEquality::==*/ != null;
- var /*@ type=bool* */ null_not_equals = null /*@target=Object::==*/ != n;
+ var /*@ type=bool* */ equals_self = n /*@target=NullEquality.==*/ == n;
+ var /*@ type=bool* */ equals_null = n /*@target=NullEquality.==*/ == null;
+ var /*@ type=bool* */ null_equals = null /*@target=Object.==*/ == n;
+ var /*@ type=bool* */ not_equals_self = n /*@target=NullEquality.==*/ != n;
+ var /*@ type=bool* */ not_equals_null = n /*@target=NullEquality.==*/ != null;
+ var /*@ type=bool* */ null_not_equals = null /*@target=Object.==*/ != n;
}
main() {
test();
- new SubNullEquality(). /*@target=SubNullEquality::test*/ test();
+ new SubNullEquality(). /*@target=SubNullEquality.test*/ test();
}
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart b/pkg/front_end/testcases/inference/promote_bounds.dart
index 7a631cb..5f9215a 100644
--- a/pkg/front_end/testcases/inference/promote_bounds.dart
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart
@@ -16,11 +16,11 @@
void f<T extends B>(T a) {
if (a is String) {
// Not promoted; we can still call foo.
- a. /*@target=B::foo*/ foo();
+ a. /*@target=B.foo*/ foo();
}
if (a is C) {
// Promoted; we can now call bar.
- /*@ promotedType=f::T* & C* */ a. /*@target=C::bar*/ bar();
+ /*@ promotedType=f::T* & C* */ a. /*@target=C.bar*/ bar();
}
}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart
index d89ab96..4b9bb91 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart
@@ -12,7 +12,7 @@
main() {
var /*@ type=A* */ a = new A();
A b = a; // doesn't require down cast
- print(a. /*@target=A::x*/ x); // doesn't require dynamic invoke
- print(a. /*@target=A::x*/ x /*@target=num::+*/ +
+ print(a. /*@target=A.x*/ x); // doesn't require dynamic invoke
+ print(a. /*@target=A.x*/ x /*@target=num.+*/ +
2); // ok to use in bigger expression
}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart
index df88d78..4507d0f 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart
@@ -11,10 +11,10 @@
test5() {
var /*@ type=A* */ a1 = new A();
- a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
+ a1. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
A a2 = new A();
- a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
+ a2. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
}
main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
index 082765b..f1d52f4 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
@@ -2,13 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
-// ^
+// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// a1. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
+// ^
//
-// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
-// ^
+// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// a2. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
+// ^
//
import self as self;
import "dart:core" as core;
@@ -31,12 +31,12 @@
}
static method test5() → dynamic {
self::A* a1 = new self::A::•();
- a1.{self::A::x} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
- ^" in "hi" as{TypeError} core::int*;
+ a1.{self::A::x} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ a1. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+ ^" in "hi" as{TypeError} core::int*;
self::A* a2 = new self::A::•();
- a2.{self::A::x} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
- ^" in "hi" as{TypeError} core::int*;
+ a2.{self::A::x} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ a2. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+ ^" in "hi" as{TypeError} core::int*;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
index 082765b..f1d52f4 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
@@ -2,13 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
-// ^
+// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// a1. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
+// ^
//
-// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
-// ^
+// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// a2. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
+// ^
//
import self as self;
import "dart:core" as core;
@@ -31,12 +31,12 @@
}
static method test5() → dynamic {
self::A* a1 = new self::A::•();
- a1.{self::A::x} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
- ^" in "hi" as{TypeError} core::int*;
+ a1.{self::A::x} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ a1. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+ ^" in "hi" as{TypeError} core::int*;
self::A* a2 = new self::A::•();
- a2.{self::A::x} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
- a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
- ^" in "hi" as{TypeError} core::int*;
+ a2.{self::A::x} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ a2. /*@target=A.x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+ ^" in "hi" as{TypeError} core::int*;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart
index 8a461a7..1cdf400 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart
@@ -23,10 +23,10 @@
void main() {
var /*@ type=D* */ d1 = new D();
- print(d1. /*@target=D::c*/ c. /*@target=C::b*/ b. /*@target=B::a*/ a
- . /*@target=A::x*/ x);
+ print(d1. /*@target=D.c*/ c. /*@target=C.b*/ b. /*@target=B.a*/ a
+ . /*@target=A.x*/ x);
D d2 = new D();
- print(d2. /*@target=D::c*/ c. /*@target=C::b*/ b. /*@target=B::a*/ a
- . /*@target=A::x*/ x);
+ print(d2. /*@target=D.c*/ c. /*@target=C.b*/ b. /*@target=B.a*/ a
+ . /*@target=A.x*/ x);
}
diff --git a/pkg/front_end/testcases/inference/property_get_toplevel.dart b/pkg/front_end/testcases/inference/property_get_toplevel.dart
index b067a2e..1f9513d 100644
--- a/pkg/front_end/testcases/inference/property_get_toplevel.dart
+++ b/pkg/front_end/testcases/inference/property_get_toplevel.dart
@@ -12,9 +12,9 @@
}
C c = new C();
-var function_ref = c. /*@target=C::function*/ function;
+var function_ref = c. /*@target=C.function*/ function;
var function_ref_list = /*@ typeArgs=() ->* int* */ [
- c. /*@target=C::function*/ function
+ c. /*@target=C.function*/ function
];
main() {}
diff --git a/pkg/front_end/testcases/inference/property_set.dart b/pkg/front_end/testcases/inference/property_set.dart
index 1dd54cf..a9a36e4 100644
--- a/pkg/front_end/testcases/inference/property_set.dart
+++ b/pkg/front_end/testcases/inference/property_set.dart
@@ -15,37 +15,37 @@
A<Object> a_object = new A<Object>();
A<dynamic> a_dynamic = new A<dynamic>();
var /*@ type=List<int*>* */ x_int =
- a_int. /*@target=A::x*/ x = /*@ typeArgs=int* */ [0];
+ a_int. /*@target=A.x*/ x = /*@ typeArgs=int* */ [0];
var /*@ type=List<int*>* */ y_int =
- a_int. /*@target=A::y*/ y = /*@ typeArgs=int* */ [0];
+ a_int. /*@target=A.y*/ y = /*@ typeArgs=int* */ [0];
var /*@ type=List<Object*>* */ x_object =
- a_object. /*@target=A::x*/ x = /*@ typeArgs=Object* */ [0];
+ a_object. /*@target=A.x*/ x = /*@ typeArgs=Object* */ [0];
var /*@ type=List<Object*>* */ y_object =
- a_object. /*@target=A::y*/ y = /*@ typeArgs=Object* */ [0];
+ a_object. /*@target=A.y*/ y = /*@ typeArgs=Object* */ [0];
var /*@ type=List<dynamic>* */ x_dynamic =
- a_dynamic. /*@target=A::x*/ x = /*@ typeArgs=dynamic */ [0];
+ a_dynamic. /*@target=A.x*/ x = /*@ typeArgs=dynamic */ [0];
var /*@ type=List<dynamic>* */ y_dynamic =
- a_dynamic. /*@target=A::y*/ y = /*@ typeArgs=dynamic */ [0];
- var /*@ type=List<int*>* */ x_int_explicit = a_int. /*@target=A::x*/ x = <int>[0];
- var /*@ type=List<int*>* */ y_int_explicit = a_int. /*@target=A::y*/ y = <int>[0];
+ a_dynamic. /*@target=A.y*/ y = /*@ typeArgs=dynamic */ [0];
+ var /*@ type=List<int*>* */ x_int_explicit = a_int. /*@target=A.x*/ x = <int>[0];
+ var /*@ type=List<int*>* */ y_int_explicit = a_int. /*@target=A.y*/ y = <int>[0];
var /*@ type=List<int*>* */ x_object_explicit =
- a_object. /*@target=A::x*/ x = <int>[0];
+ a_object. /*@target=A.x*/ x = <int>[0];
var /*@ type=List<int*>* */ y_object_explicit =
- a_object. /*@target=A::y*/ y = <int>[0];
+ a_object. /*@target=A.y*/ y = <int>[0];
var /*@ type=List<int*>* */ x_dynamic_explicit =
- a_dynamic. /*@target=A::x*/ x = <int>[0];
+ a_dynamic. /*@target=A.x*/ x = <int>[0];
var /*@ type=List<int*>* */ y_dynamic_explicit =
- a_dynamic. /*@target=A::y*/ y = <int>[0];
- List<int> x_int_downward = a_int. /*@target=A::x*/ x = /*@ typeArgs=int* */ [0];
- List<int> y_int_downward = a_int. /*@target=A::y*/ y = /*@ typeArgs=int* */ [0];
+ a_dynamic. /*@target=A.y*/ y = <int>[0];
+ List<int> x_int_downward = a_int. /*@target=A.x*/ x = /*@ typeArgs=int* */ [0];
+ List<int> y_int_downward = a_int. /*@target=A.y*/ y = /*@ typeArgs=int* */ [0];
List<int> x_object_downward =
- a_object. /*@target=A::x*/ x = /*@ typeArgs=Object* */ [0];
+ a_object. /*@target=A.x*/ x = /*@ typeArgs=Object* */ [0];
List<int> y_object_downward =
- a_object. /*@target=A::y*/ y = /*@ typeArgs=Object* */ [0];
+ a_object. /*@target=A.y*/ y = /*@ typeArgs=Object* */ [0];
List<int> x_dynamic_downward =
- a_dynamic. /*@target=A::x*/ x = /*@ typeArgs=dynamic */ [0];
+ a_dynamic. /*@target=A.x*/ x = /*@ typeArgs=dynamic */ [0];
List<int> y_dynamic_downward =
- a_dynamic. /*@target=A::y*/ y = /*@ typeArgs=dynamic */ [0];
+ a_dynamic. /*@target=A.y*/ y = /*@ typeArgs=dynamic */ [0];
}
main() {}
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart b/pkg/front_end/testcases/inference/property_set_bad_setter.dart
index f57da87..573f5c5 100644
--- a/pkg/front_end/testcases/inference/property_set_bad_setter.dart
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart
@@ -10,7 +10,7 @@
}
void f(A a) {
- var /*@ type=int* */ x = a. /*@target=A::x*/ x = 0;
+ var /*@ type=int* */ x = a. /*@target=A.x*/ x = 0;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart
index 92af6c8..2095e06 100644
--- a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart
@@ -9,10 +9,10 @@
T a;
void op(double b) {
- double r1 = /*@target=C::a*/ a /*@target=num::+*/ + b;
- double r2 = /*@target=C::a*/ a /*@target=num::-*/ - b;
- double r3 = /*@target=C::a*/ a /*@target=num::**/ * b;
- double r4 = /*@target=C::a*/ a /*@target=num::/ */ / b;
+ double r1 = /*@target=C.a*/ a /*@target=num.+*/ + b;
+ double r2 = /*@target=C.a*/ a /*@target=num.-*/ - b;
+ double r3 = /*@target=C.a*/ a /*@target=num.**/ * b;
+ double r4 = /*@target=C.a*/ a /*@target=num./ */ / b;
}
}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart
index 757a80f..01149dd 100644
--- a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart
@@ -9,15 +9,15 @@
T a;
void op(int b) {
- T r1 = /*@target=C::a*/ a /*@target=num::+*/ + b;
- T r2 = /*@target=C::a*/ a /*@target=num::-*/ - b;
- T r3 = /*@target=C::a*/ a /*@target=num::**/ * b;
+ T r1 = /*@target=C.a*/ a /*@target=num.+*/ + b;
+ T r2 = /*@target=C.a*/ a /*@target=num.-*/ - b;
+ T r3 = /*@target=C.a*/ a /*@target=num.**/ * b;
}
void opEq(int b) {
- /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::+*/ += b;
- /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::-*/ -= b;
- /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::**/ *= b;
+ /*@target=C.a*/ /*@target=C.a*/ a /*@target=num.+*/ += b;
+ /*@target=C.a*/ /*@target=C.a*/ a /*@target=num.-*/ -= b;
+ /*@target=C.a*/ /*@target=C.a*/ a /*@target=num.**/ *= b;
}
}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart
index 17f1189..2455538 100644
--- a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart
@@ -9,15 +9,15 @@
T a;
void op(T b) {
- T r1 = /*@target=C::a*/ a /*@target=num::+*/ + b;
- T r2 = /*@target=C::a*/ a /*@target=num::-*/ - b;
- T r3 = /*@target=C::a*/ a /*@target=num::**/ * b;
+ T r1 = /*@target=C.a*/ a /*@target=num.+*/ + b;
+ T r2 = /*@target=C.a*/ a /*@target=num.-*/ - b;
+ T r3 = /*@target=C.a*/ a /*@target=num.**/ * b;
}
void opEq(T b) {
- /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::+*/ += b;
- /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::-*/ -= b;
- /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::**/ *= b;
+ /*@target=C.a*/ /*@target=C.a*/ a /*@target=num.+*/ += b;
+ /*@target=C.a*/ /*@target=C.a*/ a /*@target=num.-*/ -= b;
+ /*@target=C.a*/ /*@target=C.a*/ a /*@target=num.**/ *= b;
}
}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.strong.transformed.expect
index 470be38..3dfcba9 100644
--- a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.strong.transformed.expect
@@ -8,14 +8,14 @@
: super core::Object::•()
;
method op(generic-covariant-impl self::C::T* b) → void {
- self::C::T* r1 = this.{self::C::a}.{core::num::+}(b) as{TypeError} self::C::T*;
- self::C::T* r2 = this.{self::C::a}.{core::num::-}(b) as{TypeError} self::C::T*;
- self::C::T* r3 = this.{self::C::a}.{core::num::*}(b) as{TypeError} self::C::T*;
+ self::C::T* r1 = this.{self::C::a}.{core::num::+}(b);
+ self::C::T* r2 = this.{self::C::a}.{core::num::-}(b);
+ self::C::T* r3 = this.{self::C::a}.{core::num::*}(b);
}
method opEq(generic-covariant-impl self::C::T* b) → void {
- this.{self::C::a} = this.{self::C::a}.{core::num::+}(b) as{TypeError} self::C::T*;
- this.{self::C::a} = this.{self::C::a}.{core::num::-}(b) as{TypeError} self::C::T*;
- this.{self::C::a} = this.{self::C::a}.{core::num::*}(b) as{TypeError} self::C::T*;
+ this.{self::C::a} = this.{self::C::a}.{core::num::+}(b);
+ this.{self::C::a} = this.{self::C::a}.{core::num::-}(b);
+ this.{self::C::a} = this.{self::C::a}.{core::num::*}(b);
}
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart b/pkg/front_end/testcases/inference/super_index_set.dart
index 195028e..231ebaa 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart
+++ b/pkg/front_end/testcases/inference/super_index_set.dart
@@ -16,7 +16,7 @@
class C extends B {
void operator []=(Object x, Object y) {}
void h() {
- super /*@target=B::[]=*/ [
+ super /*@target=B.[]=*/ [
/*@ typeArgs=int* */ f()] = /*@ typeArgs=String* */ f();
}
}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart b/pkg/front_end/testcases/inference/super_index_set_substitution.dart
index f17da64..b816d69 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart
@@ -16,7 +16,7 @@
class C<U> extends B<Future<U>> {
void operator []=(Object x, Object y) {}
void h() {
- super /*@target=B::[]=*/ [
+ super /*@target=B.[]=*/ [
/*@ typeArgs=Map<int*, Future<C::U*>*>* */ f()] =
/*@ typeArgs=List<Future<C::U*>*>* */ f();
}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation.dart b/pkg/front_end/testcases/inference/super_method_invocation.dart
index 21b7a9b..eae71c0 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation.dart
+++ b/pkg/front_end/testcases/inference/super_method_invocation.dart
@@ -11,7 +11,7 @@
class D extends C {
void g() {
- var /*@ type=int* */ x = super. /*@target=C::f*/ f();
+ var /*@ type=int* */ x = super. /*@target=C.f*/ f();
}
}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart
index b9d5a78..4edb1b7 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart
@@ -21,7 +21,7 @@
E<Future<U>> g(Object x) => null;
void h() {
var /*@ type=D<Future<C::U*>*>* */ x =
- super. /*@target=B::g*/ g(/*@ typeArgs=E<Future<C::U*>*>* */ f());
+ super. /*@target=B.g*/ g(/*@ typeArgs=E<Future<C::U*>*>* */ f());
}
}
diff --git a/pkg/front_end/testcases/inference/super_property_get.dart b/pkg/front_end/testcases/inference/super_property_get.dart
index 3edcecd..db32690 100644
--- a/pkg/front_end/testcases/inference/super_property_get.dart
+++ b/pkg/front_end/testcases/inference/super_property_get.dart
@@ -11,7 +11,7 @@
class D extends C {
void g() {
- var /*@ type=int* */ y = super. /*@target=C::x*/ x;
+ var /*@ type=int* */ y = super. /*@target=C.x*/ x;
}
}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart
index 6c7f7da..6c10e63 100644
--- a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart
@@ -11,7 +11,7 @@
class D extends C {
void g() {
- var /*@ type=int* */ y = super. /*@target=C::f*/ f();
+ var /*@ type=int* */ y = super. /*@target=C.f*/ f();
}
}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart
index 75fa5b5..6b478bc 100644
--- a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart
@@ -16,7 +16,7 @@
class D extends C {
void g() {
var /*@ type=int* */ y =
- super. /*@target=C::f*/ f /*@target=CallableClass::call*/ ();
+ super. /*@target=C.f*/ f /*@target=CallableClass.call*/ ();
}
}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart b/pkg/front_end/testcases/inference/super_property_get_substitution.dart
index 07eaf74..ee71262 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart
@@ -19,7 +19,7 @@
E<Future<U>> get x => null;
void set x(Object x) {}
void g() {
- var /*@ type=D<Future<C::U*>*>* */ y = super. /*@target=B::x*/ x;
+ var /*@ type=D<Future<C::U*>*>* */ y = super. /*@target=B.x*/ x;
}
}
diff --git a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart
index d700836..89ba585 100644
--- a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart
+++ b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart
@@ -11,7 +11,7 @@
class D extends C {
void g() {
- var /*@ type=() ->* int* */ y = super. /*@target=C::f*/ f;
+ var /*@ type=() ->* int* */ y = super. /*@target=C.f*/ f;
}
}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart b/pkg/front_end/testcases/inference/super_property_set_substitution.dart
index d917705..2101e53 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart
@@ -21,7 +21,7 @@
E<Future<U>> get x => null;
void set x(Object x) {}
void g() {
- super. /*@target=B::x*/ x = /*@ typeArgs=D<Future<C::U*>*>* */ f();
+ super. /*@target=B.x*/ x = /*@ typeArgs=D<Future<C::U*>*>* */ f();
}
}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart
index 6ee518e..a365728 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart
@@ -11,7 +11,7 @@
main() {
var /*@ type=List<dynamic>* */ v =
- new C(). /*@target=C::f*/ f<dynamic>(/*@ returnType=int* */ () {
+ new C(). /*@target=C.f*/ f<dynamic>(/*@ returnType=int* */ () {
return 1;
});
}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart
index f89acf4..81d2ea3 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart
@@ -11,7 +11,7 @@
main() {
var /*@ type=List<int*>* */ v =
- new C(). /*@target=C::f*/ f<int>(/*@ returnType=int* */ () {
+ new C(). /*@target=C.f*/ f<int>(/*@ returnType=int* */ () {
return 1;
});
}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart
index f5761bf..e107471 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart
@@ -10,7 +10,7 @@
}
main() {
- var /*@ type=List<int*>* */ v = new C(). /*@ typeArgs=int* */ /*@target=C::f*/ f(
+ var /*@ type=List<int*>* */ v = new C(). /*@ typeArgs=int* */ /*@target=C.f*/ f(
/*@ returnType=int* */ () {
return 1;
});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart
index 7f3b9c4..8704e7a4 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart
@@ -9,7 +9,7 @@
double f(x) => 1.0;
}
-var v = new C(). /*@target=C::f*/ f(/*@ returnType=int* */ () {
+var v = new C(). /*@target=C.f*/ f(/*@ returnType=int* */ () {
return 1;
});
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
index 3fdcdcd..3f1a4c8 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
@@ -16,15 +16,15 @@
// c is required to infer b, and vice versa.
var b = /*@ returnType=() ->* invalid-type */ () =>
- a. /*@ typeArgs=() ->* invalid-type */ /*@target=A::f*/ f(c);
+ a. /*@ typeArgs=() ->* invalid-type */ /*@target=A.f*/ f(c);
var c = /*@ returnType=invalid-type */ () =>
- a. /*@ typeArgs=invalid-type */ /*@target=A::f*/ f(b);
+ a. /*@ typeArgs=invalid-type */ /*@target=A.f*/ f(b);
// e's use of a.g breaks the circularity, because a.g is not generic, therefore
// the type of e does not depend on the type of d.
var d = /*@ returnType=() ->* int* */ () =>
- a. /*@ typeArgs=() ->* int* */ /*@target=A::f*/ f(e);
-var e = /*@ returnType=int* */ () => a. /*@target=A::g*/ g(d);
+ a. /*@ typeArgs=() ->* int* */ /*@target=A.f*/ f(e);
+var e = /*@ returnType=int* */ () => a. /*@target=A.g*/ g(d);
main() {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart
index 0c21605..747cb3f 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart
@@ -12,18 +12,18 @@
// There's a circularity between a and b because the type of `int + x` depends
// on the type of x.
-var a = /*@ returnType=num* */ () => intValue /*@target=num::+*/ + b;
+var a = /*@ returnType=num* */ () => intValue /*@target=num.+*/ + b;
var b = a();
// But there's no circularity between c and d because the type of `num + x` is
// always num.
-var c = /*@ returnType=num* */ () => numValue /*@target=num::+*/ + d;
+var c = /*@ returnType=num* */ () => numValue /*@target=num.+*/ + d;
var d = c();
// Similar for double.
-var e = /*@ returnType=double* */ () => doubleValue /*@target=double::+*/ + f;
+var e = /*@ returnType=double* */ () => doubleValue /*@target=double.+*/ + f;
var f = e();
main() {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.outline.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.outline.expect
index c44763e..0c6966f 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.outline.expect
@@ -4,7 +4,7 @@
//
// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:5: Error: Can't infer the type of 'a': circularity found during type inference.
// Specify the type explicitly.
-// var a = /*@ returnType=num* */ () => intValue /*@target=num::+*/ + b;
+// var a = /*@ returnType=num* */ () => intValue /*@target=num.+*/ + b;
// ^
//
import self as self;
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
index ca2d303..b80c8e2 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
@@ -4,7 +4,7 @@
//
// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:5: Error: Can't infer the type of 'a': circularity found during type inference.
// Specify the type explicitly.
-// var a = /*@ returnType=num* */ () => intValue /*@target=num::+*/ + b;
+// var a = /*@ returnType=num* */ () => intValue /*@target=num.+*/ + b;
// ^
//
import self as self;
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect
index ca2d303..b80c8e2 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect
@@ -4,7 +4,7 @@
//
// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:5: Error: Can't infer the type of 'a': circularity found during type inference.
// Specify the type explicitly.
-// var a = /*@ returnType=num* */ () => intValue /*@target=num::+*/ + b;
+// var a = /*@ returnType=num* */ () => intValue /*@target=num.+*/ + b;
// ^
//
import self as self;
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart
index a609915..c5280e5 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart
@@ -9,8 +9,8 @@
// can be inferred for A.y and B.y.
class A {
- var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
- var y = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
+ var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B.x*/ x;
+ var y = /*@returnType=invalid-type*/ () => new B(). /*@target=B.x*/ x;
}
class B extends A {
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.outline.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.outline.expect
index 445d1a7..0599095 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.outline.expect
@@ -4,7 +4,7 @@
//
// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:12:7: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
+// var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B.x*/ x;
// ^
//
import self as self;
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
index 45135a6..762518c 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
@@ -4,7 +4,7 @@
//
// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:12:7: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
+// var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B.x*/ x;
// ^
//
import self as self;
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
index 45135a6..762518c 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
@@ -4,7 +4,7 @@
//
// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:12:7: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
+// var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B.x*/ x;
// ^
//
import self as self;
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart
index 968995d..ec76db0 100644
--- a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart
@@ -19,10 +19,10 @@
A aLocal;
for (aLocal in /*@ typeArgs=Iterable<A*>* */ f()) {}
- for (/*@target=C::aField*/ /*@target=C::aField*/ aField
+ for (/*@target=C.aField*/ /*@target=C.aField*/ aField
in /*@ typeArgs=Iterable<A*>* */ f()) {}
- for (/*@target=C::aSetter*/ /*@target=C::aSetter*/ aSetter
+ for (/*@target=C.aSetter*/ /*@target=C.aSetter*/ aSetter
in /*@ typeArgs=Iterable<A*>* */ f()) {}
for (aTopLevel in /*@ typeArgs=Iterable<A*>* */ f()) {}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart
index 6b8a751..21e96f7 100644
--- a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart
@@ -32,23 +32,23 @@
}
void test1(G g) {
- g /*@target=G::[]*/ /*@target=G::[]=*/ [
- 0] /*@ target=A::* */ *= /*@ typeArgs=D* */ f();
- var /*@ type=C* */ x = g /*@target=G::[]*/ /*@target=G::[]=*/ [0]
- /*@ target=A::* */
+ g /*@target=G.[]*/ /*@target=G.[]=*/ [
+ 0] /*@target=A.**/ *= /*@ typeArgs=D* */ f();
+ var /*@ type=C* */ x = g /*@target=G.[]*/ /*@target=G.[]=*/ [0]
+ /*@target=A.**/
*= /*@ typeArgs=D* */ f();
}
void test2(G g) {
- /*@ target=A::+ */ ++g /*@target=G::[]*/ /*@target=G::[]=*/ [0];
- var /*@ type=C* */ x = /*@ target=A::+ */ ++g /*@target=G::[]*/ /*@target=G::[]=*/ [
+ /*@target=A.+*/ ++g /*@target=G.[]*/ /*@target=G.[]=*/ [0];
+ var /*@ type=C* */ x = /*@target=A.+*/ ++g /*@target=G.[]*/ /*@target=G.[]=*/ [
0];
}
void test3(G g) {
- g /*@target=G::[] */ /*@target=G::[]=*/ [0] /*@ target=A::+ */ ++;
+ g /*@target=G.[]*/ /*@target=G.[]=*/ [0] /*@target=A.+*/ ++;
var /*@ type=A* */ x =
- g /*@target=G::[]*/ /*@target=G::[]=*/ [0] /*@ target=A::+ */ ++;
+ g /*@target=G.[]*/ /*@target=G.[]=*/ [0] /*@target=A.+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
index f95b47e..90e202f 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
@@ -22,54 +22,54 @@
B member;
void test() {
- /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ /*@target=Test.member*/ member = /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --
- /*@target=Test::member*/ /*@target=Test::member*/ member;
+ /*@target=B.-*/ --
+ /*@target=Test.member*/ /*@target=Test.member*/ member;
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::- */ --;
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.-*/ --;
- var /*@ type=B* */ v1 = /*@target=Test::member*/ member =
+ var /*@ type=B* */ v1 = /*@target=Test.member*/ member =
/*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = /*@target=Test::member*/ /*@target=Test::member*/
+ var /*@ type=B* */ v2 = /*@target=Test.member*/ /*@target=Test.member*/
member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ +=
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ +=
/*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *=
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *=
/*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &=
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &=
/*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --
- /*@target=Test::member*/ /*@target=Test::member*/ member;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --
+ /*@target=Test.member*/ /*@target=Test.member*/ member;
var /*@ type=B* */ v7 =
- /*@ type=B* */ /*@target=Test::member*/ /*@target=Test::member*/
- /*@ type=B* */ member /*@ target=B::- */ --;
+ /*@ type=B* */ /*@target=Test.member*/ /*@target=Test.member*/
+ /*@ type=B* */ member /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
index 5e7045f..d2dc509 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
@@ -13,28 +13,28 @@
int t;
void test() {
- var /*@ type=int* */ v1 = /*@target=Test1::t*/ t = getInt();
+ var /*@ type=int* */ v1 = /*@target=Test1.t*/ t = getInt();
- var /*@ type=num* */ v2 = /*@target=Test1::t*/ t = getNum();
+ var /*@ type=num* */ v2 = /*@target=Test1.t*/ t = getNum();
- var /*@ type=int* */ v4 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
- /*@ target=num::== */ ??= getInt();
+ var /*@ type=int* */ v4 = /*@target=Test1.t*/ /*@target=Test1.t*/ t
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
- /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = /*@target=Test1.t*/ /*@target=Test1.t*/ t
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=int* */ v7 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
- /*@ target=num::+ */ += getInt();
+ var /*@ type=int* */ v7 = /*@target=Test1.t*/ /*@target=Test1.t*/ t
+ /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
- /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = /*@target=Test1.t*/ /*@target=Test1.t*/ t
+ /*@target=num.+*/ += getNum();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++
- /*@target=Test1::t*/ /*@target=Test1::t*/ t;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++
+ /*@target=Test1.t*/ /*@target=Test1.t*/ t;
var /*@ type=int* */ v11 =
- /*@ type=int* */ /*@target=Test1::t*/ /*@target=Test1::t*/
- /*@ type=int* */ t /*@ target=num::+ */ ++;
+ /*@ type=int* */ /*@target=Test1.t*/ /*@target=Test1.t*/
+ /*@ type=int* */ t /*@target=num.+*/ ++;
}
}
@@ -42,36 +42,36 @@
num t;
void test() {
- var /*@ type=int* */ v1 = /*@target=Test2::t*/ t = getInt();
+ var /*@ type=int* */ v1 = /*@target=Test2.t*/ t = getInt();
- var /*@ type=num* */ v2 = /*@target=Test2::t*/ t = getNum();
+ var /*@ type=num* */ v2 = /*@target=Test2.t*/ t = getNum();
- var /*@ type=double* */ v3 = /*@target=Test2::t*/ t = getDouble();
+ var /*@ type=double* */ v3 = /*@target=Test2.t*/ t = getDouble();
- var /*@ type=num* */ v4 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::== */ ??= getInt();
+ var /*@ type=num* */ v4 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::== */ ??= getDouble();
+ var /*@ type=num* */ v6 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.==*/ ??= getDouble();
- var /*@ type=num* */ v7 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v7 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v9 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
- /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v9 = /*@target=Test2.t*/ /*@target=Test2.t*/ t
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++
- /*@target=Test2::t*/ /*@target=Test2::t*/ t;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++
+ /*@target=Test2.t*/ /*@target=Test2.t*/ t;
var /*@ type=num* */ v11 =
- /*@ type=num* */ /*@target=Test2::t*/ /*@target=Test2::t*/
- /*@ type=num* */ t /*@ target=num::+ */ ++;
+ /*@ type=num* */ /*@target=Test2.t*/ /*@target=Test2.t*/
+ /*@ type=num* */ t /*@target=num.+*/ ++;
}
}
@@ -79,31 +79,31 @@
double t;
void test3() {
- var /*@ type=num* */ v2 = /*@target=Test3::t*/ t = getNum();
+ var /*@ type=num* */ v2 = /*@target=Test3.t*/ t = getNum();
- var /*@ type=double* */ v3 = /*@target=Test3::t*/ t = getDouble();
+ var /*@ type=double* */ v3 = /*@target=Test3.t*/ t = getDouble();
- var /*@ type=num* */ v5 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=double* */ v6 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=num::== */ ??= getDouble();
+ var /*@ type=double* */ v6 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=double.+*/ += getInt();
- var /*@ type=double* */ v8 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=double.+*/ += getNum();
- var /*@ type=double* */ v9 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
- /*@ target=double::+ */ += getDouble();
+ var /*@ type=double* */ v9 = /*@target=Test3.t*/ /*@target=Test3.t*/ t
+ /*@target=double.+*/ += getDouble();
var /*@ type=double* */ v10 =
- /*@ target=double::+ */ ++ /*@target=Test3::t*/ /*@target=Test3::t*/ t;
+ /*@target=double.+*/ ++ /*@target=Test3.t*/ /*@target=Test3.t*/ t;
var /*@ type=double* */ v11 =
- /*@ type=double* */ /*@target=Test3::t*/ /*@target=Test3::t*/
- /*@ type=double* */ t /*@ target=double::+ */ ++;
+ /*@ type=double* */ /*@target=Test3.t*/ /*@target=Test3.t*/
+ /*@ type=double* */ t /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart
index 8eb3740..4b7b3b6e 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart
@@ -6,6 +6,6 @@
library test;
List<double> a = <double>[];
-var b = (a /*@target=List::[]=*/ [0] = 1.0);
+var b = (a /*@target=List.[]=*/ [0] = 1.0);
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
index 902751b..9f372f0 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
@@ -27,59 +27,59 @@
void test() {
Test t = /*@ typeArgs=Test* */ f();
- t /*@target=Test::[]=*/ [
+ t /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()];
+ t /*@target=Test.[]*/ [/*@ typeArgs=Index* */ f()];
- /*@ target=B::- */ --t
- /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@target=B.-*/ --t
+ /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()];
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
- var /*@ type=B* */ v1 = t /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v1 = t /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v2 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=A* */ v3 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- var /*@ type=B* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v4 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=C* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()];
+ var /*@ type=B* */ v6 = t /*@target=Test.[]*/ [/*@ typeArgs=Index* */ f()];
var /*@ type=B* */ v7 =
- /*@ target=B::- */ --t
- /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@target=B.-*/ --t
+ /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()];
- var /*@ type=B* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ var /*@ type=B* */ v8 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
index 5b3be70..1920c98 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
@@ -34,38 +34,38 @@
void test() {
Test t = /*@ typeArgs=Test* */ f();
- t /*@target=Test::[]=*/ [
+ t /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=A* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/ ??= /*@ typeArgs=A* */ f();
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=A.==*/ ??= /*@ typeArgs=A* */ f();
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=E* */ f();
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=B.+*/ += /*@ typeArgs=E* */ f();
- /*@ target=B::- */ --t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@target=B.-*/ --t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()];
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
- var /*@ type=A* */ v1 = t /*@target=Test::[]=*/ [
+ var /*@ type=A* */ v1 = t /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=A* */ f();
- var /*@ type=A* */ v2 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=A* */ v2 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/ ??= /*@ typeArgs=A* */ f();
+ /*@target=A.==*/ ??= /*@ typeArgs=A* */ f();
- var /*@ type=D* */ v3 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=D* */ v3 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=E* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=E* */ f();
var /*@ type=D* */ v4 =
- /*@ target=B::- */ --t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@target=B.-*/ --t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()];
- var /*@ type=B* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ var /*@ type=B* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart
index fb7df35..0734921 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart
@@ -27,55 +27,55 @@
class Test extends Base {
void test() {
- super /*@target=Base::[]=*/ [
+ super /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::-*/ --super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ /*@target=B.-*/ --super /*@target=Base.[]*/ /*@target=Base.[]=*/
[/*@ typeArgs=Index* */ f()];
- super /*@target=Base::[]*/ /*@target=Base::[]=*/
- [/*@ typeArgs=Index* */ f()] /*@ target=B::-*/ --;
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
- var /*@ type=B* */ v1 = super /*@target=Base::[]=*/ [
+ var /*@ type=B* */ v1 = super /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ var /*@ type=B* */ v2 = super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ var /*@ type=A* */ v3 = super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- var /*@ type=B* */ v4 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ var /*@ type=B* */ v4 = super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ var /*@ type=C* */ v5 = super /*@target=Base.[]*/ /*@target=Base.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::-*/ --super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ [/*@ typeArgs=Index* */ f()];
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ [/*@ typeArgs=Index* */ f()];
- var /*@ type=B* */ v7 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
- [/*@ typeArgs=Index* */ f()] /*@ target=B::-*/ --;
+ var /*@ type=B* */ v7 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart
index ebd811a..22af2a9 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart
@@ -10,8 +10,8 @@
double getDouble() => 0.0;
abstract class Base<T, U> {
- T operator [](String s) => /*@target=Base::getValue*/ getValue(s);
- void operator []=(String s, U v) => /*@target=Base::setValue*/ setValue(s, v);
+ T operator [](String s) => /*@target=Base.getValue*/ getValue(s);
+ void operator []=(String s, U v) => /*@target=Base.setValue*/ setValue(s, v);
T getValue(String s);
void setValue(String s, U v);
@@ -19,322 +19,313 @@
abstract class Test1 extends Base<int, int> {
void test() {
- var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = super /*@target=Base.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
var /*@ type=int* */ v4 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=int* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=int* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=num::+ */ ++;
+ var /*@ type=int* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=num.+*/ ++;
}
}
abstract class Test2 extends Base<int, num> {
void test() {
- var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = super /*@target=Base.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- super /*@target=Base::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = super /*@target=Base.[]=*/ ['x'] = getDouble();
var /*@ type=int* */ v4 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=int* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
var /*@ type=double* */ v9 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getDouble();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=int* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=num::+ */ ++;
+ var /*@ type=int* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=num.+*/ ++;
}
}
abstract class Test3 extends Base<int, double> {
void test() {
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- super /*@target=Base::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = super /*@target=Base.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=int* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
var /*@ type=double* */ v9 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getDouble();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=int* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=num::+ */ ++;
+ var /*@ type=int* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=num.+*/ ++;
}
}
abstract class Test4 extends Base<num, int> {
void test() {
- var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = super /*@target=Base.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
var /*@ type=num* */ v4 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=num* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=num::+ */ ++;
+ var /*@ type=num* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=num.+*/ ++;
}
}
abstract class Test5 extends Base<num, num> {
void test() {
- var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = super /*@target=Base.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- super /*@target=Base::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = super /*@target=Base.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v4 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=num* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=num::+ */ ++;
+ var /*@ type=num* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=num.+*/ ++;
}
}
abstract class Test6 extends Base<num, double> {
void test() {
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- super /*@target=Base::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = super /*@target=Base.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::+ */ += getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=num* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=num::+ */ ++;
+ var /*@ type=num* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=num.+*/ ++;
}
}
abstract class Test7 extends Base<double, int> {
void test() {
- var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = super /*@target=Base.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
var /*@ type=num* */ v4 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=double::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=double::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=double.+*/ += getNum();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=double* */ v11 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=double::+ */ ++;
+ var /*@ type=double* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=double.+*/ ++;
}
}
abstract class Test8 extends Base<double, num> {
void test() {
- var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = super /*@target=Base.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- super /*@target=Base::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = super /*@target=Base.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v4 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v6 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=double::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=double::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=double::+ */ += getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=double* */ v11 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=double::+ */ ++;
+ var /*@ type=double* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=double.+*/ ++;
}
}
abstract class Test9 extends Base<double, double> {
void test() {
- var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = super /*@target=Base.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- super /*@target=Base::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = super /*@target=Base.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v5 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v6 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=num::== */ ??= getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=double::+ */ += getInt();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=double::+ */ += getNum();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
- /*@ target=double::+ */ += getDouble();
+ super /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x']
+ /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
- /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++super
+ /*@target=Base.[]*/ /*@target=Base.[]=*/ ['x'];
- var /*@ type=double* */ v11 =
- super /*@target=Base::[]*/ /*@target=Base::[]=*/
- ['x'] /*@ target=double::+ */ ++;
+ var /*@ type=double* */ v11 = super /*@target=Base.[]*/ /*@target=Base.[]=*/
+ ['x'] /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
index 919b38b..1f2b516 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
@@ -2,34 +2,34 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:108:34: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// /*@ target=num::+ */ += getInt();
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:106:31: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// /*@target=num.+*/ += getInt();
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:116:50: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// var /*@ type=int* */ v10 = /*@target=num.+*/ ++super
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:120:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// ['x'] /*@target=num.+*/ ++;
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:244:34: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// /*@target=double.+*/ += getInt();
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:118:53: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:248:34: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// /*@target=double.+*/ += getNum();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:122:36: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// ['x'] /*@ target=num::+ */ ++;
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:250:56: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// var /*@ type=double* */ v10 = /*@target=double.+*/ ++super
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:254:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// ['x'] /*@target=double.+*/ ++;
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:248:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// /*@ target=double::+ */ += getInt();
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:252:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// /*@ target=double::+ */ += getNum();
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:254:59: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:259:43: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// ['x'] /*@ target=double::+ */ ++;
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -96,17 +96,17 @@
core::double* v3 = let final core::String* #t66 = "x" in let final core::double* #t67 = self::getDouble() in let final void #t68 = super.{self::Base::[]=}(#t66, #t67) in #t67;
core::num* v5 = let final core::String* #t69 = "x" in let final core::int* #t70 = super.{self::Base::[]}(#t69) in #t70.{core::num::==}(null) ?{core::num*} let final core::num* #t71 = self::getNum() as{TypeError} core::double* in let final void #t72 = super.{self::Base::[]=}(#t69, #t71) in #t71 : #t70;
core::num* v6 = let final core::String* #t73 = "x" in let final core::int* #t74 = super.{self::Base::[]}(#t73) in #t74.{core::num::==}(null) ?{core::num*} let final core::double* #t75 = self::getDouble() in let final void #t76 = super.{self::Base::[]=}(#t73, #t75) in #t75 : #t74;
- core::int* v7 = let final core::String* #t77 = "x" in let final core::int* #t78 = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:108:34: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- /*@ target=num::+ */ += getInt();
- ^" in super.{self::Base::[]}(#t77).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t80 = super.{self::Base::[]=}(#t77, #t78) in #t78;
+ core::int* v7 = let final core::String* #t77 = "x" in let final core::int* #t78 = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:106:31: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ /*@target=num.+*/ += getInt();
+ ^" in super.{self::Base::[]}(#t77).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t80 = super.{self::Base::[]=}(#t77, #t78) in #t78;
core::num* v8 = let final core::String* #t81 = "x" in let final core::num* #t82 = super.{self::Base::[]}(#t81).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t83 = super.{self::Base::[]=}(#t81, #t82) in #t82;
core::double* v9 = let final core::String* #t84 = "x" in let final core::double* #t85 = super.{self::Base::[]}(#t84).{core::num::+}(self::getDouble()) in let final void #t86 = super.{self::Base::[]=}(#t84, #t85) in #t85;
- core::int* v10 = let final core::String* #t87 = "x" in let final core::int* #t88 = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:118:53: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
- ^" in super.{self::Base::[]}(#t87).{core::num::+}(1) as{TypeError} core::double* in let final void #t90 = super.{self::Base::[]=}(#t87, #t88) in #t88;
- core::int* v11 = let final core::String* #t91 = "x" in let final core::int* #t92 = super.{self::Base::[]}(#t91) in let final void #t93 = super.{self::Base::[]=}(#t91, let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:122:36: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- ['x'] /*@ target=num::+ */ ++;
- ^" in #t92.{core::num::+}(1) as{TypeError} core::double*) in #t92;
+ core::int* v10 = let final core::String* #t87 = "x" in let final core::int* #t88 = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:116:50: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++super
+ ^" in super.{self::Base::[]}(#t87).{core::num::+}(1) as{TypeError} core::double* in let final void #t90 = super.{self::Base::[]=}(#t87, #t88) in #t88;
+ core::int* v11 = let final core::String* #t91 = "x" in let final core::int* #t92 = super.{self::Base::[]}(#t91) in let final void #t93 = super.{self::Base::[]=}(#t91, let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:120:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ ['x'] /*@target=num.+*/ ++;
+ ^" in #t92.{core::num::+}(1) as{TypeError} core::double*) in #t92;
}
}
abstract class Test4 extends self::Base<core::num*, core::int*> {
@@ -167,18 +167,18 @@
core::num* v2 = let final core::String* #t189 = "x" in let final core::num* #t190 = self::getNum() as{TypeError} core::int* in let final void #t191 = super.{self::Base::[]=}(#t189, #t190) in #t190;
core::num* v4 = let final core::String* #t192 = "x" in let final core::double* #t193 = super.{self::Base::[]}(#t192) in #t193.{core::num::==}(null) ?{core::num*} let final core::int* #t194 = self::getInt() in let final void #t195 = super.{self::Base::[]=}(#t192, #t194) in #t194 : #t193;
core::num* v5 = let final core::String* #t196 = "x" in let final core::double* #t197 = super.{self::Base::[]}(#t196) in #t197.{core::num::==}(null) ?{core::num*} let final core::num* #t198 = self::getNum() as{TypeError} core::int* in let final void #t199 = super.{self::Base::[]=}(#t196, #t198) in #t198 : #t197;
- core::double* v7 = let final core::String* #t200 = "x" in let final core::double #t201 = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:248:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- /*@ target=double::+ */ += getInt();
- ^" in super.{self::Base::[]}(#t200).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t203 = super.{self::Base::[]=}(#t200, #t201) in #t201;
- core::double* v8 = let final core::String* #t204 = "x" in let final core::double #t205 = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:252:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- /*@ target=double::+ */ += getNum();
- ^" in super.{self::Base::[]}(#t204).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t207 = super.{self::Base::[]=}(#t204, #t205) in #t205;
- core::double* v10 = let final core::String* #t208 = "x" in let final core::double #t209 = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:254:59: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
- ^" in super.{self::Base::[]}(#t208).{core::double::+}(1) as{TypeError} core::int* in let final void #t211 = super.{self::Base::[]=}(#t208, #t209) in #t209;
- core::double* v11 = let final core::String* #t212 = "x" in let final core::double* #t213 = super.{self::Base::[]}(#t212) in let final void #t214 = super.{self::Base::[]=}(#t212, let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:259:43: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- ['x'] /*@ target=double::+ */ ++;
- ^" in #t213.{core::double::+}(1) as{TypeError} core::int*) in #t213;
+ core::double* v7 = let final core::String* #t200 = "x" in let final core::double #t201 = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:244:34: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@target=double.+*/ += getInt();
+ ^" in super.{self::Base::[]}(#t200).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t203 = super.{self::Base::[]=}(#t200, #t201) in #t201;
+ core::double* v8 = let final core::String* #t204 = "x" in let final core::double #t205 = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:248:34: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@target=double.+*/ += getNum();
+ ^" in super.{self::Base::[]}(#t204).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t207 = super.{self::Base::[]=}(#t204, #t205) in #t205;
+ core::double* v10 = let final core::String* #t208 = "x" in let final core::double #t209 = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:250:56: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++super
+ ^" in super.{self::Base::[]}(#t208).{core::double::+}(1) as{TypeError} core::int* in let final void #t211 = super.{self::Base::[]=}(#t208, #t209) in #t209;
+ core::double* v11 = let final core::String* #t212 = "x" in let final core::double* #t213 = super.{self::Base::[]}(#t212) in let final void #t214 = super.{self::Base::[]=}(#t212, let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:254:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ ['x'] /*@target=double.+*/ ++;
+ ^" in #t213.{core::double::+}(1) as{TypeError} core::int*) in #t213;
}
}
abstract class Test8 extends self::Base<core::double*, core::num*> {
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart
index 521bde5..9575841 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart
@@ -25,56 +25,56 @@
void operator []=(Index i, B v) {}
void test() {
- this /*@target=Test::[]=*/ [
+ this /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --this /*@target=Test::[]*/ /*@target=Test::[]=*/
+ /*@target=B.-*/ --this /*@target=Test.[]*/ /*@target=Test.[]=*/
[/*@ typeArgs=Index* */ f()];
- this /*@target=Test::[]*/ /*@target=Test::[]=*/
- [/*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ this /*@target=Test.[]*/ /*@target=Test.[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
- var /*@ type=B* */ v1 = this /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v1 = this /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v2 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=A* */ v3 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- var /*@ type=B* */ v4 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=B* */ v4 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ var /*@ type=C* */ v5 = this /*@target=Test.[]*/ /*@target=Test.[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
var /*@ type=B* */ v6 =
- /*@ target=B::- */ --this /*@target=Test::[]*/ /*@target=Test::[]=*/
+ /*@target=B.-*/ --this /*@target=Test.[]*/ /*@target=Test.[]=*/
[/*@ typeArgs=Index* */ f()];
- var /*@ type=B* */ v7 = this /*@target=Test::[]*/ /*@target=Test::[]=*/
- [/*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+ var /*@ type=B* */ v7 = this /*@target=Test.[]*/ /*@target=Test.[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart
index 35de18e..707cc68 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart
@@ -14,32 +14,32 @@
void operator []=(String s, int v);
void test() {
- var /*@ type=int* */ v1 = this /*@target=Test1::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = this /*@target=Test1.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = this /*@target=Test1::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = this /*@target=Test1.[]=*/ ['x'] = getNum();
var /*@ type=int* */ v4 = this
- /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ /*@target=Test1.[]*/ /*@target=Test1.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = this
- /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test1.[]*/ /*@target=Test1.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=int* */ v7 = this
- /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
- /*@target=num::+*/ += getInt();
+ /*@target=Test1.[]*/ /*@target=Test1.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 = this
- /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
- /*@target=num::+*/ += getNum();
+ /*@target=Test1.[]*/ /*@target=Test1.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
- var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
- /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x'];
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++this
+ /*@target=Test1.[]*/ /*@target=Test1.[]=*/ ['x'];
var /*@ type=int* */ v11 = this
- /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
- /*@target=num::+*/ ++;
+ /*@target=Test1.[]*/ /*@target=Test1.[]=*/ ['x']
+ /*@target=num.+*/ ++;
}
}
@@ -48,43 +48,42 @@
void operator []=(String s, num v);
void test() {
- var /*@ type=int* */ v1 = this /*@target=Test2::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = this /*@target=Test2.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = this /*@target=Test2::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = this /*@target=Test2.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- this /*@target=Test2::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = this /*@target=Test2.[]=*/ ['x'] = getDouble();
var /*@ type=int* */ v4 = this
- /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ /*@target=Test2.[]*/ /*@target=Test2.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = this
- /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test2.[]*/ /*@target=Test2.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 = this
- /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ /*@target=Test2.[]*/ /*@target=Test2.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=int* */ v7 = this
- /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
- /*@target=num::+*/ += getInt();
+ /*@target=Test2.[]*/ /*@target=Test2.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 = this
- /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
- /*@target=num::+*/ += getNum();
+ /*@target=Test2.[]*/ /*@target=Test2.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
var /*@ type=double* */ v9 = this
- /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
- /*@target=num::+*/ += getDouble();
+ /*@target=Test2.[]*/ /*@target=Test2.[]=*/ ['x']
+ /*@target=num.+*/ += getDouble();
- var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
- /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x'];
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++this
+ /*@target=Test2.[]*/ /*@target=Test2.[]=*/ ['x'];
var /*@ type=int* */ v11 = this
- /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
- /*@target=num::+*/ ++;
+ /*@target=Test2.[]*/ /*@target=Test2.[]=*/ ['x']
+ /*@target=num.+*/ ++;
}
}
@@ -93,37 +92,36 @@
void operator []=(String s, double v);
void test() {
- var /*@ type=num* */ v2 = this /*@target=Test3::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = this /*@target=Test3.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- this /*@target=Test3::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = this /*@target=Test3.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v5 = this
- /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test3.[]*/ /*@target=Test3.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 = this
- /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ /*@target=Test3.[]*/ /*@target=Test3.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=int* */ v7 = this
- /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
- /*@target=num::+*/ += getInt();
+ /*@target=Test3.[]*/ /*@target=Test3.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 = this
- /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
- /*@target=num::+*/ += getNum();
+ /*@target=Test3.[]*/ /*@target=Test3.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
var /*@ type=double* */ v9 = this
- /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
- /*@target=num::+*/ += getDouble();
+ /*@target=Test3.[]*/ /*@target=Test3.[]=*/ ['x']
+ /*@target=num.+*/ += getDouble();
- var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
- /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x'];
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++this
+ /*@target=Test3.[]*/ /*@target=Test3.[]=*/ ['x'];
var /*@ type=int* */ v11 = this
- /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
- /*@target=num::+*/ ++;
+ /*@target=Test3.[]*/ /*@target=Test3.[]=*/ ['x']
+ /*@target=num.+*/ ++;
}
}
@@ -132,32 +130,32 @@
void operator []=(String s, int v);
void test() {
- var /*@ type=int* */ v1 = this /*@target=Test4::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = this /*@target=Test4.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = this /*@target=Test4::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = this /*@target=Test4.[]=*/ ['x'] = getNum();
var /*@ type=num* */ v4 = this
- /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ /*@target=Test4.[]*/ /*@target=Test4.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = this
- /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test4.[]*/ /*@target=Test4.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v7 = this
- /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
- /*@target=num::+*/ += getInt();
+ /*@target=Test4.[]*/ /*@target=Test4.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 = this
- /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
- /*@target=num::+*/ += getNum();
+ /*@target=Test4.[]*/ /*@target=Test4.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v10 = /*@target=num::+*/ ++this
- /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x'];
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++this
+ /*@target=Test4.[]*/ /*@target=Test4.[]=*/ ['x'];
var /*@ type=num* */ v11 = this
- /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
- /*@target=num::+*/ ++;
+ /*@target=Test4.[]*/ /*@target=Test4.[]=*/ ['x']
+ /*@target=num.+*/ ++;
}
}
@@ -166,43 +164,42 @@
void operator []=(String s, num v);
void test() {
- var /*@ type=int* */ v1 = this /*@target=Test5::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = this /*@target=Test5.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = this /*@target=Test5::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = this /*@target=Test5.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- this /*@target=Test5::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = this /*@target=Test5.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v4 = this
- /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ /*@target=Test5.[]*/ /*@target=Test5.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = this
- /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test5.[]*/ /*@target=Test5.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 = this
- /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ /*@target=Test5.[]*/ /*@target=Test5.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 = this
- /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
- /*@target=num::+*/ += getInt();
+ /*@target=Test5.[]*/ /*@target=Test5.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 = this
- /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
- /*@target=num::+*/ += getNum();
+ /*@target=Test5.[]*/ /*@target=Test5.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 = this
- /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
- /*@target=num::+*/ += getDouble();
+ /*@target=Test5.[]*/ /*@target=Test5.[]=*/ ['x']
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@target=num::+*/ ++this
- /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x'];
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++this
+ /*@target=Test5.[]*/ /*@target=Test5.[]=*/ ['x'];
var /*@ type=num* */ v11 = this
- /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
- /*@target=num::+*/ ++;
+ /*@target=Test5.[]*/ /*@target=Test5.[]=*/ ['x']
+ /*@target=num.+*/ ++;
}
}
@@ -211,37 +208,36 @@
void operator []=(String s, double v);
void test() {
- var /*@ type=num* */ v2 = this /*@target=Test6::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = this /*@target=Test6.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 =
- this /*@target=Test6::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = this /*@target=Test6.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v5 = this
- /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test6.[]*/ /*@target=Test6.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 = this
- /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ /*@target=Test6.[]*/ /*@target=Test6.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 = this
- /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
- /*@target=num::+*/ += getInt();
+ /*@target=Test6.[]*/ /*@target=Test6.[]=*/ ['x']
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 = this
- /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
- /*@target=num::+*/ += getNum();
+ /*@target=Test6.[]*/ /*@target=Test6.[]=*/ ['x']
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 = this
- /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
- /*@target=num::+*/ += getDouble();
+ /*@target=Test6.[]*/ /*@target=Test6.[]=*/ ['x']
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@target=num::+*/ ++this
- /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x'];
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++this
+ /*@target=Test6.[]*/ /*@target=Test6.[]=*/ ['x'];
var /*@ type=num* */ v11 = this
- /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
- /*@target=num::+*/ ++;
+ /*@target=Test6.[]*/ /*@target=Test6.[]=*/ ['x']
+ /*@target=num.+*/ ++;
}
}
@@ -250,33 +246,33 @@
void operator []=(String s, int v);
void test() {
- var /*@ type=int* */ v1 = this /*@target=Test7::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = this /*@target=Test7.[]=*/ ['x'] = getInt();
var /*@ type=num* */ v2 = this
- /*@target=Test7::[]=*/ ['x'] = getNum();
+ /*@target=Test7.[]=*/ ['x'] = getNum();
var /*@ type=num* */ v4 = this
- /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ /*@target=Test7.[]*/ /*@target=Test7.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = this
- /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test7.[]*/ /*@target=Test7.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v7 = this
- /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
- /*@target=double::+*/ += getInt();
+ /*@target=Test7.[]*/ /*@target=Test7.[]=*/ ['x']
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 = this
- /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
- /*@target=double::+*/ += getNum();
+ /*@target=Test7.[]*/ /*@target=Test7.[]=*/ ['x']
+ /*@target=double.+*/ += getNum();
- var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
- /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x'];
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++this
+ /*@target=Test7.[]*/ /*@target=Test7.[]=*/ ['x'];
var /*@ type=double* */ v11 = this
- /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
- /*@target=double::+*/ ++;
+ /*@target=Test7.[]*/ /*@target=Test7.[]=*/ ['x']
+ /*@target=double.+*/ ++;
}
}
@@ -285,44 +281,44 @@
void operator []=(String s, num v);
void test() {
- var /*@ type=int* */ v1 = this /*@target=Test8::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = this /*@target=Test8.[]=*/ ['x'] = getInt();
var /*@ type=num* */ v2 = this
- /*@target=Test8::[]=*/ ['x'] = getNum();
+ /*@target=Test8.[]=*/ ['x'] = getNum();
var /*@ type=double* */ v3 = this
- /*@target=Test8::[]=*/ ['x'] = getDouble();
+ /*@target=Test8.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v4 = this
- /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ /*@target=Test8.[]*/ /*@target=Test8.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = this
- /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test8.[]*/ /*@target=Test8.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v6 = this
- /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ /*@target=Test8.[]*/ /*@target=Test8.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 = this
- /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
- /*@target=double::+*/ += getInt();
+ /*@target=Test8.[]*/ /*@target=Test8.[]=*/ ['x']
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 = this
- /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
- /*@target=double::+*/ += getNum();
+ /*@target=Test8.[]*/ /*@target=Test8.[]=*/ ['x']
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 = this
- /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
- /*@target=double::+*/ += getDouble();
+ /*@target=Test8.[]*/ /*@target=Test8.[]=*/ ['x']
+ /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
- /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x'];
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++this
+ /*@target=Test8.[]*/ /*@target=Test8.[]=*/ ['x'];
var /*@ type=double* */ v11 = this
- /*@target=Test8::[]*/ /*@target=Test8::[]=*/ [
- 'x'] /*@target=double::+*/ ++;
+ /*@target=Test8.[]*/ /*@target=Test8.[]=*/ [
+ 'x'] /*@target=double.+*/ ++;
}
}
@@ -331,37 +327,37 @@
void operator []=(String s, double v);
void test() {
- var /*@ type=num* */ v2 = this /*@target=Test9::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = this /*@target=Test9.[]=*/ ['x'] = getNum();
var /*@ type=double* */ v3 = this
- /*@target=Test9::[]=*/ ['x'] = getDouble();
+ /*@target=Test9.[]=*/ ['x'] = getDouble();
var /*@ type=num* */ v5 = this
- /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ /*@target=Test9.[]*/ /*@target=Test9.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v6 = this
- /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ /*@target=Test9.[]*/ /*@target=Test9.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 = this
- /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
- /*@target=double::+*/ += getInt();
+ /*@target=Test9.[]*/ /*@target=Test9.[]=*/ ['x']
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 = this
- /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
- /*@target=double::+*/ += getNum();
+ /*@target=Test9.[]*/ /*@target=Test9.[]=*/ ['x']
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 = this
- /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
- /*@target=double::+*/ += getDouble();
+ /*@target=Test9.[]*/ /*@target=Test9.[]=*/ ['x']
+ /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
- /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x'];
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++this
+ /*@target=Test9.[]*/ /*@target=Test9.[]=*/ ['x'];
var /*@ type=double* */ v11 = this
- /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
- /*@target=double::+*/ ++;
+ /*@target=Test9.[]*/ /*@target=Test9.[]=*/ ['x']
+ /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
index 93a6f12..de71071 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
@@ -2,33 +2,33 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:111:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// /*@target=num::+*/ += getInt();
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:109:27: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// /*@target=num.+*/ += getInt();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:121:51: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:119:50: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// var /*@ type=int* */ v10 = /*@target=num.+*/ ++this
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:126:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// /*@target=num::+*/ ++;
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:124:27: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// /*@target=num.+*/ ++;
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:268:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// /*@target=double::+*/ += getInt();
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:264:30: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// /*@target=double.+*/ += getInt();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:272:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// /*@target=double::+*/ += getNum();
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:268:30: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// /*@target=double.+*/ += getNum();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:274:57: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:270:56: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// var /*@ type=double* */ v10 = /*@target=double.+*/ ++this
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:279:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// /*@target=double::+*/ ++;
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:275:30: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// /*@target=double.+*/ ++;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -101,17 +101,17 @@
core::double* v3 = let final core::String* #t66 = "x" in let final core::double* #t67 = self::getDouble() in let final void #t68 = this.{self::Test3::[]=}(#t66, #t67) in #t67;
core::num* v5 = let final core::String* #t69 = "x" in let final core::int* #t70 = this.{self::Test3::[]}(#t69) in #t70.{core::num::==}(null) ?{core::num*} let final core::num* #t71 = self::getNum() as{TypeError} core::double* in let final void #t72 = this.{self::Test3::[]=}(#t69, #t71) in #t71 : #t70;
core::num* v6 = let final core::String* #t73 = "x" in let final core::int* #t74 = this.{self::Test3::[]}(#t73) in #t74.{core::num::==}(null) ?{core::num*} let final core::double* #t75 = self::getDouble() in let final void #t76 = this.{self::Test3::[]=}(#t73, #t75) in #t75 : #t74;
- core::int* v7 = let final core::String* #t77 = "x" in let final core::int* #t78 = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:111:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- /*@target=num::+*/ += getInt();
- ^" in this.{self::Test3::[]}(#t77).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t80 = this.{self::Test3::[]=}(#t77, #t78) in #t78;
+ core::int* v7 = let final core::String* #t77 = "x" in let final core::int* #t78 = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:109:27: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ /*@target=num.+*/ += getInt();
+ ^" in this.{self::Test3::[]}(#t77).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t80 = this.{self::Test3::[]=}(#t77, #t78) in #t78;
core::num* v8 = let final core::String* #t81 = "x" in let final core::num* #t82 = this.{self::Test3::[]}(#t81).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t83 = this.{self::Test3::[]=}(#t81, #t82) in #t82;
core::double* v9 = let final core::String* #t84 = "x" in let final core::double* #t85 = this.{self::Test3::[]}(#t84).{core::num::+}(self::getDouble()) in let final void #t86 = this.{self::Test3::[]=}(#t84, #t85) in #t85;
- core::int* v10 = let final core::String* #t87 = "x" in let final core::int* #t88 = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:121:51: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
- ^" in this.{self::Test3::[]}(#t87).{core::num::+}(1) as{TypeError} core::double* in let final void #t90 = this.{self::Test3::[]=}(#t87, #t88) in #t88;
- core::int* v11 = let final core::String* #t91 = "x" in let final core::int* #t92 = this.{self::Test3::[]}(#t91) in let final void #t93 = this.{self::Test3::[]=}(#t91, let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:126:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- /*@target=num::+*/ ++;
- ^" in #t92.{core::num::+}(1) as{TypeError} core::double*) in #t92;
+ core::int* v10 = let final core::String* #t87 = "x" in let final core::int* #t88 = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:119:50: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++this
+ ^" in this.{self::Test3::[]}(#t87).{core::num::+}(1) as{TypeError} core::double* in let final void #t90 = this.{self::Test3::[]=}(#t87, #t88) in #t88;
+ core::int* v11 = let final core::String* #t91 = "x" in let final core::int* #t92 = this.{self::Test3::[]}(#t91) in let final void #t93 = this.{self::Test3::[]=}(#t91, let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:124:27: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ /*@target=num.+*/ ++;
+ ^" in #t92.{core::num::+}(1) as{TypeError} core::double*) in #t92;
}
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
@@ -220,18 +220,18 @@
core::num* v2 = let final core::String* #t189 = "x" in let final core::num* #t190 = self::getNum() as{TypeError} core::int* in let final void #t191 = this.{self::Test7::[]=}(#t189, #t190) in #t190;
core::num* v4 = let final core::String* #t192 = "x" in let final core::double* #t193 = this.{self::Test7::[]}(#t192) in #t193.{core::num::==}(null) ?{core::num*} let final core::int* #t194 = self::getInt() in let final void #t195 = this.{self::Test7::[]=}(#t192, #t194) in #t194 : #t193;
core::num* v5 = let final core::String* #t196 = "x" in let final core::double* #t197 = this.{self::Test7::[]}(#t196) in #t197.{core::num::==}(null) ?{core::num*} let final core::num* #t198 = self::getNum() as{TypeError} core::int* in let final void #t199 = this.{self::Test7::[]=}(#t196, #t198) in #t198 : #t197;
- core::double* v7 = let final core::String* #t200 = "x" in let final core::double #t201 = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:268:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- /*@target=double::+*/ += getInt();
- ^" in this.{self::Test7::[]}(#t200).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t203 = this.{self::Test7::[]=}(#t200, #t201) in #t201;
- core::double* v8 = let final core::String* #t204 = "x" in let final core::double #t205 = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:272:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- /*@target=double::+*/ += getNum();
- ^" in this.{self::Test7::[]}(#t204).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t207 = this.{self::Test7::[]=}(#t204, #t205) in #t205;
- core::double* v10 = let final core::String* #t208 = "x" in let final core::double #t209 = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:274:57: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
- ^" in this.{self::Test7::[]}(#t208).{core::double::+}(1) as{TypeError} core::int* in let final void #t211 = this.{self::Test7::[]=}(#t208, #t209) in #t209;
- core::double* v11 = let final core::String* #t212 = "x" in let final core::double* #t213 = this.{self::Test7::[]}(#t212) in let final void #t214 = this.{self::Test7::[]=}(#t212, let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:279:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- /*@target=double::+*/ ++;
- ^" in #t213.{core::double::+}(1) as{TypeError} core::int*) in #t213;
+ core::double* v7 = let final core::String* #t200 = "x" in let final core::double #t201 = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:264:30: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@target=double.+*/ += getInt();
+ ^" in this.{self::Test7::[]}(#t200).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t203 = this.{self::Test7::[]=}(#t200, #t201) in #t201;
+ core::double* v8 = let final core::String* #t204 = "x" in let final core::double #t205 = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:268:30: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@target=double.+*/ += getNum();
+ ^" in this.{self::Test7::[]}(#t204).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t207 = this.{self::Test7::[]=}(#t204, #t205) in #t205;
+ core::double* v10 = let final core::String* #t208 = "x" in let final core::double #t209 = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:270:56: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++this
+ ^" in this.{self::Test7::[]}(#t208).{core::double::+}(1) as{TypeError} core::int* in let final void #t211 = this.{self::Test7::[]=}(#t208, #t209) in #t209;
+ core::double* v11 = let final core::String* #t212 = "x" in let final core::double* #t213 = this.{self::Test7::[]}(#t212) in let final void #t214 = this.{self::Test7::[]=}(#t212, let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:275:30: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@target=double.+*/ ++;
+ ^" in #t213.{core::double::+}(1) as{TypeError} core::int*) in #t213;
}
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
index b758ab5..7c7e04b 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
@@ -15,273 +15,279 @@
}
void test1(Test<int, int> t) {
- var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = t /*@target=Test.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=int* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ var /*@ type=int* */ v4 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=int* */ v7 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getInt();
var /*@ type=num* */ v8 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getNum();
var /*@ type=int* */ v10 =
- /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=num.+*/ ++t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=int* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=num::+ */ ++;
+ var /*@ type=int* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ ++;
}
void test2(Test<int, num> t) {
- var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = t /*@target=Test.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = t /*@target=Test.[]=*/ ['x'] = getDouble();
- var /*@ type=int* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ var /*@ type=int* */ v4 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ var /*@ type=num* */ v6 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=int* */ v7 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getInt();
var /*@ type=num* */ v8 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getNum();
var /*@ type=double* */ v9 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getDouble();
var /*@ type=int* */ v10 =
- /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=num.+*/ ++t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=int* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=num::+ */ ++;
+ var /*@ type=int* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ ++;
}
void test3(Test<int, double> t) {
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = t /*@target=Test.[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ var /*@ type=num* */ v6 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=int* */ v7 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getInt();
var /*@ type=num* */ v8 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getNum();
var /*@ type=double* */ v9 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getDouble();
var /*@ type=int* */ v10 =
- /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=num.+*/ ++t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=int* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=num::+ */ ++;
+ var /*@ type=int* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ ++;
}
void test4(Test<num, int> t) {
- var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = t /*@target=Test.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ var /*@ type=num* */ v4 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v7 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getInt();
var /*@ type=num* */ v8 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getNum();
var /*@ type=num* */ v10 =
- /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=num.+*/ ++t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=num* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=num::+ */ ++;
+ var /*@ type=num* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ ++;
}
void test5(Test<num, num> t) {
- var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = t /*@target=Test.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = t /*@target=Test.[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ var /*@ type=num* */ v4 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ var /*@ type=num* */ v6 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getInt();
var /*@ type=num* */ v8 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getNum();
var /*@ type=num* */ v9 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getDouble();
var /*@ type=num* */ v10 =
- /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=num.+*/ ++t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=num* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=num::+ */ ++;
+ var /*@ type=num* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ ++;
}
void test6(Test<num, double> t) {
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = t /*@target=Test.[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ var /*@ type=num* */ v6 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getInt();
var /*@ type=num* */ v8 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getNum();
var /*@ type=num* */ v9 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
getDouble();
var /*@ type=num* */ v10 =
- /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=num.+*/ ++t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=num* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=num::+ */ ++;
+ var /*@ type=num* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ ++;
}
void test7(Test<double, int> t) {
- var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = t /*@target=Test.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ var /*@ type=num* */ v4 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ getInt();
- var /*@ type=double* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ getNum();
var /*@ type=double* */ v10 =
- /*@ target=double::+ */ ++t
- /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=double.+*/ ++t
+ /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=double* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ ++;
+ var /*@ type=double* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ ++;
}
void test8(Test<double, num> t) {
- var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+ var /*@ type=int* */ v1 = t /*@target=Test.[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = t /*@target=Test.[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getInt();
+ var /*@ type=num* */ v4 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=double* */ v6 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ var /*@ type=double* */ v6 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ getInt();
- var /*@ type=double* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ getNum();
- var /*@ type=double* */ v9 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ += getDouble();
+ var /*@ type=double* */ v9 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ getDouble();
var /*@ type=double* */ v10 =
- /*@ target=double::+ */ ++t
- /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=double.+*/ ++t
+ /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=double* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ ++;
+ var /*@ type=double* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ ++;
}
void test9(Test<double, double> t) {
- var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+ var /*@ type=num* */ v2 = t /*@target=Test.[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
+ var /*@ type=double* */ v3 = t /*@target=Test.[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=double* */ v6 =
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
- /*@target=num::==*/ ??= getDouble();
+ var /*@ type=double* */ v6 = t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x']
+ /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ getInt();
- var /*@ type=double* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ getNum();
- var /*@ type=double* */ v9 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ += getDouble();
+ var /*@ type=double* */ v9 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ getDouble();
var /*@ type=double* */ v10 =
- /*@ target=double::+ */ ++t
- /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ /*@target=double.+*/ ++t
+ /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
- var /*@ type=double* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
- 'x'] /*@ target=double::+ */ ++;
+ var /*@ type=double* */ v11 =
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
index b9143e7..4b4c09b 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
@@ -2,33 +2,33 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:90:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:90:74: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:102:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:102:25: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// /*@target=num.+*/ ++t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:105:74: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ ++;
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:211:77: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:215:77: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:219:28: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// /*@target=double.+*/ ++t
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:105:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// 'x'] /*@ target=num::+ */ ++;
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:211:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// 'x'] /*@ target=double::+ */ += getInt();
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:214:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// 'x'] /*@ target=double::+ */ += getNum();
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:217:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// /*@ target=double::+ */ ++t
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:221:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// 'x'] /*@ target=double::+ */ ++;
-// ^
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:223:77: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ ++;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -84,17 +84,17 @@
core::double* v3 = let final self::Test<core::int*, core::double*>* #t86 = t in let final core::String* #t87 = "x" in let final core::double* #t88 = self::getDouble() in let final void #t89 = #t86.{self::Test::[]=}(#t87, #t88) in #t88;
core::num* v5 = let final self::Test<core::int*, core::double*>* #t90 = t in let final core::String* #t91 = "x" in let final core::int* #t92 = #t90.{self::Test::[]}(#t91) in #t92.{core::num::==}(null) ?{core::num*} let final core::num* #t93 = self::getNum() as{TypeError} core::double* in let final void #t94 = #t90.{self::Test::[]=}(#t91, #t93) in #t93 : #t92;
core::num* v6 = let final self::Test<core::int*, core::double*>* #t95 = t in let final core::String* #t96 = "x" in let final core::int* #t97 = #t95.{self::Test::[]}(#t96) in #t97.{core::num::==}(null) ?{core::num*} let final core::double* #t98 = self::getDouble() in let final void #t99 = #t95.{self::Test::[]=}(#t96, #t98) in #t98 : #t97;
- core::int* v7 = let final self::Test<core::int*, core::double*>* #t100 = t in let final core::String* #t101 = "x" in let final core::int* #t102 = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:90:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
- ^" in #t100.{self::Test::[]}(#t101).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t104 = #t100.{self::Test::[]=}(#t101, #t102) in #t102;
+ core::int* v7 = let final self::Test<core::int*, core::double*>* #t100 = t in let final core::String* #t101 = "x" in let final core::int* #t102 = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:90:74: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ +=
+ ^" in #t100.{self::Test::[]}(#t101).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t104 = #t100.{self::Test::[]=}(#t101, #t102) in #t102;
core::num* v8 = let final self::Test<core::int*, core::double*>* #t105 = t in let final core::String* #t106 = "x" in let final core::num* #t107 = #t105.{self::Test::[]}(#t106).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t108 = #t105.{self::Test::[]=}(#t106, #t107) in #t107;
core::double* v9 = let final self::Test<core::int*, core::double*>* #t109 = t in let final core::String* #t110 = "x" in let final core::double* #t111 = #t109.{self::Test::[]}(#t110).{core::num::+}(self::getDouble()) in let final void #t112 = #t109.{self::Test::[]=}(#t110, #t111) in #t111;
- core::int* v10 = let final self::Test<core::int*, core::double*>* #t113 = t in let final core::String* #t114 = "x" in let final core::int* #t115 = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:102:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
- ^" in #t113.{self::Test::[]}(#t114).{core::num::+}(1) as{TypeError} core::double* in let final void #t117 = #t113.{self::Test::[]=}(#t114, #t115) in #t115;
- core::int* v11 = let final self::Test<core::int*, core::double*>* #t118 = t in let final core::String* #t119 = "x" in let final core::int* #t120 = #t118.{self::Test::[]}(#t119) in let final void #t121 = #t118.{self::Test::[]=}(#t119, let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:105:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
- 'x'] /*@ target=num::+ */ ++;
- ^" in #t120.{core::num::+}(1) as{TypeError} core::double*) in #t120;
+ core::int* v10 = let final self::Test<core::int*, core::double*>* #t113 = t in let final core::String* #t114 = "x" in let final core::int* #t115 = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:102:25: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ /*@target=num.+*/ ++t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'];
+ ^" in #t113.{self::Test::[]}(#t114).{core::num::+}(1) as{TypeError} core::double* in let final void #t117 = #t113.{self::Test::[]=}(#t114, #t115) in #t115;
+ core::int* v11 = let final self::Test<core::int*, core::double*>* #t118 = t in let final core::String* #t119 = "x" in let final core::int* #t120 = #t118.{self::Test::[]}(#t119) in let final void #t121 = #t118.{self::Test::[]=}(#t119, let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:105:74: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=num.+*/ ++;
+ ^" in #t120.{core::num::+}(1) as{TypeError} core::double*) in #t120;
}
static method test4(self::Test<core::num*, core::int*>* t) → void {
core::int* v1 = let final self::Test<core::num*, core::int*>* #t123 = t in let final core::String* #t124 = "x" in let final core::int* #t125 = self::getInt() in let final void #t126 = #t123.{self::Test::[]=}(#t124, #t125) in #t125;
@@ -135,18 +135,18 @@
core::num* v2 = let final self::Test<core::double*, core::int*>* #t246 = t in let final core::String* #t247 = "x" in let final core::num* #t248 = self::getNum() as{TypeError} core::int* in let final void #t249 = #t246.{self::Test::[]=}(#t247, #t248) in #t248;
core::num* v4 = let final self::Test<core::double*, core::int*>* #t250 = t in let final core::String* #t251 = "x" in let final core::double* #t252 = #t250.{self::Test::[]}(#t251) in #t252.{core::num::==}(null) ?{core::num*} let final core::int* #t253 = self::getInt() in let final void #t254 = #t250.{self::Test::[]=}(#t251, #t253) in #t253 : #t252;
core::num* v5 = let final self::Test<core::double*, core::int*>* #t255 = t in let final core::String* #t256 = "x" in let final core::double* #t257 = #t255.{self::Test::[]}(#t256) in #t257.{core::num::==}(null) ?{core::num*} let final core::num* #t258 = self::getNum() as{TypeError} core::int* in let final void #t259 = #t255.{self::Test::[]=}(#t256, #t258) in #t258 : #t257;
- core::double* v7 = let final self::Test<core::double*, core::int*>* #t260 = t in let final core::String* #t261 = "x" in let final core::double #t262 = let final<BottomType> #t263 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:211:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- 'x'] /*@ target=double::+ */ += getInt();
- ^" in #t260.{self::Test::[]}(#t261).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t264 = #t260.{self::Test::[]=}(#t261, #t262) in #t262;
- core::double* v8 = let final self::Test<core::double*, core::int*>* #t265 = t in let final core::String* #t266 = "x" in let final core::double #t267 = let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:214:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- 'x'] /*@ target=double::+ */ += getNum();
- ^" in #t265.{self::Test::[]}(#t266).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t269 = #t265.{self::Test::[]=}(#t266, #t267) in #t267;
- core::double* v10 = let final self::Test<core::double*, core::int*>* #t270 = t in let final core::String* #t271 = "x" in let final core::double #t272 = let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:217:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- /*@ target=double::+ */ ++t
- ^" in #t270.{self::Test::[]}(#t271).{core::double::+}(1) as{TypeError} core::int* in let final void #t274 = #t270.{self::Test::[]=}(#t271, #t272) in #t272;
- core::double* v11 = let final self::Test<core::double*, core::int*>* #t275 = t in let final core::String* #t276 = "x" in let final core::double* #t277 = #t275.{self::Test::[]}(#t276) in let final void #t278 = #t275.{self::Test::[]=}(#t276, let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:221:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
- 'x'] /*@ target=double::+ */ ++;
- ^" in #t277.{core::double::+}(1) as{TypeError} core::int*) in #t277;
+ core::double* v7 = let final self::Test<core::double*, core::int*>* #t260 = t in let final core::String* #t261 = "x" in let final core::double #t262 = let final<BottomType> #t263 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:211:77: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ ^" in #t260.{self::Test::[]}(#t261).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t264 = #t260.{self::Test::[]=}(#t261, #t262) in #t262;
+ core::double* v8 = let final self::Test<core::double*, core::int*>* #t265 = t in let final core::String* #t266 = "x" in let final core::double #t267 = let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:215:77: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ +=
+ ^" in #t265.{self::Test::[]}(#t266).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t269 = #t265.{self::Test::[]=}(#t266, #t267) in #t267;
+ core::double* v10 = let final self::Test<core::double*, core::int*>* #t270 = t in let final core::String* #t271 = "x" in let final core::double #t272 = let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:219:28: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@target=double.+*/ ++t
+ ^" in #t270.{self::Test::[]}(#t271).{core::double::+}(1) as{TypeError} core::int* in let final void #t274 = #t270.{self::Test::[]=}(#t271, #t272) in #t272;
+ core::double* v11 = let final self::Test<core::double*, core::int*>* #t275 = t in let final core::String* #t276 = "x" in let final core::double* #t277 = #t275.{self::Test::[]}(#t276) in let final void #t278 = #t275.{self::Test::[]=}(#t276, let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:223:77: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ t /*@target=Test.[]*/ /*@target=Test.[]=*/ ['x'] /*@target=double.+*/ ++;
+ ^" in #t277.{core::double::+}(1) as{TypeError} core::int*) in #t277;
}
static method test8(self::Test<core::double*, core::num*>* t) → void {
core::int* v1 = let final self::Test<core::double*, core::num*>* #t280 = t in let final core::String* #t281 = "x" in let final core::int* #t282 = self::getInt() in let final void #t283 = #t280.{self::Test::[]=}(#t281, #t282) in #t282;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
index 79c53e3..17beb65 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
@@ -22,36 +22,36 @@
B local;
local = /*@ typeArgs=B* */ f();
- local /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ local /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ local /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ local /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ local /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --local;
+ /*@target=B.-*/ --local;
- local /*@ target=B::- */ --;
+ local /*@target=B.-*/ --;
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- local /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ local /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 = local
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 = local
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 = local
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --local;
var /*@ type=B* */ v7 = /*@ type=B* */ local
- /*@ type=B* */ /*@ target=B::- */ --;
+ /*@ type=B* */ /*@target=B.-*/ --;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
index e8b79a0..39e0b15 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
@@ -14,18 +14,18 @@
var /*@ type=num* */ v2 = t = getNum();
- var /*@ type=int* */ v4 = t /*@ target=num::== */ ??= getInt();
+ var /*@ type=int* */ v4 = t /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=num.==*/ ??= getNum();
- var /*@ type=int* */ v7 = t /*@ target=num::+ */ += getInt();
+ var /*@ type=int* */ v7 = t /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = t /*@target=num.+*/ += getNum();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++t;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++t;
var /*@ type=int* */ v11 =
- /*@ type=int* */ t /*@ type=int* */ /*@ target=num::+ */ ++;
+ /*@ type=int* */ t /*@ type=int* */ /*@target=num.+*/ ++;
}
void test2(num t) {
@@ -35,22 +35,22 @@
var /*@ type=double* */ v3 = t = getDouble();
- var /*@ type=num* */ v4 = t /*@ target=num::== */ ??= getInt();
+ var /*@ type=num* */ v4 = t /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = t /*@ target=num::== */ ??= getDouble();
+ var /*@ type=num* */ v6 = t /*@target=num.==*/ ??= getDouble();
- var /*@ type=num* */ v7 = t /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v7 = t /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = t /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v9 = t /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v9 = t /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++t;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++t;
var /*@ type=num* */ v11 =
- /*@ type=num* */ t /*@ type=num* */ /*@ target=num::+ */ ++;
+ /*@ type=num* */ t /*@ type=num* */ /*@target=num.+*/ ++;
}
void test3(double t) {
@@ -58,20 +58,20 @@
var /*@ type=double* */ v3 = t = getDouble();
- var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = t /*@target=num.==*/ ??= getNum();
- var /*@ type=double* */ v6 = t /*@ target=num::== */ ??= getDouble();
+ var /*@ type=double* */ v6 = t /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 = t /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 = t /*@target=double.+*/ += getInt();
- var /*@ type=double* */ v8 = t /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 = t /*@target=double.+*/ += getNum();
- var /*@ type=double* */ v9 = t /*@ target=double::+ */ += getDouble();
+ var /*@ type=double* */ v9 = t /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++t;
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++t;
var /*@ type=double* */ v11 =
- /*@ type=double* */ t /*@ type=double* */ /*@ target=double::+ */ ++;
+ /*@ type=double* */ t /*@ type=double* */ /*@target=double.+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart
index a15c8d5..70d06ae 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart
@@ -9,22 +9,22 @@
int f;
}
-var v_assign = (new A(). /*@target=A::f*/ f = 1);
+var v_assign = (new A(). /*@target=A.f*/ f = 1);
var v_plus = (new /*@ type=A* */ A()
- . /*@target=A::f*/ /*@target=A::f*/ f /*@ target=num::+ */ += 1);
+ . /*@target=A.f*/ /*@target=A.f*/ f /*@target=num.+*/ += 1);
var v_minus = (new /*@ type=A* */ A()
- . /*@target=A::f*/ /*@target=A::f*/ f /*@ target=num::- */ -= 1);
+ . /*@target=A.f*/ /*@target=A.f*/ f /*@target=num.-*/ -= 1);
var v_multiply = (new /*@ type=A* */ A()
- . /*@target=A::f*/ /*@target=A::f*/ f /*@ target=num::* */ *= 1);
-var v_prefix_pp = (/*@ target=num::+ */ ++new /*@ type=A* */ A()
- . /*@target=A::f*/ /*@target=A::f*/ f);
-var v_prefix_mm = (/*@ target=num::- */ --new /*@ type=A* */ A()
- . /*@target=A::f*/ /*@target=A::f*/ f);
+ . /*@target=A.f*/ /*@target=A.f*/ f /*@target=num.**/ *= 1);
+var v_prefix_pp = (/*@target=num.+*/ ++new /*@ type=A* */ A()
+ . /*@target=A.f*/ /*@target=A.f*/ f);
+var v_prefix_mm = (/*@target=num.-*/ --new /*@ type=A* */ A()
+ . /*@target=A.f*/ /*@target=A.f*/ f);
var v_postfix_pp = (new /*@ type=A* */ A()
- . /*@ type=int* */ /*@target=A::f*/ /*@target=A::f*/
- /*@ type=int* */ f /*@ target=num::+ */ ++);
+ . /*@ type=int* */ /*@target=A.f*/ /*@target=A.f*/
+ /*@ type=int* */ f /*@target=num.+*/ ++);
var v_postfix_mm = (new /*@ type=A* */ A()
- . /*@ type=int* */ /*@target=A::f*/ /*@target=A::f*/
- /*@ type=int* */ f /*@ target=num::- */ --);
+ . /*@ type=int* */ /*@target=A.f*/ /*@target=A.f*/
+ /*@ type=int* */ f /*@target=num.-*/ --);
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart
index 57ab96d..99f6754 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart
@@ -14,15 +14,15 @@
A a;
}
-var v_prefix_pp = (/*@ target=A::+ */ ++new /*@ type=B* */ B()
- . /*@target=B::a*/ /*@target=B::a*/ a);
-var v_prefix_mm = (/*@ target=A::- */ --new /*@ type=B* */ B()
- . /*@target=B::a*/ /*@target=B::a*/ a);
+var v_prefix_pp = (/*@target=A.+*/ ++new /*@ type=B* */ B()
+ . /*@target=B.a*/ /*@target=B.a*/ a);
+var v_prefix_mm = (/*@target=A.-*/ --new /*@ type=B* */ B()
+ . /*@target=B.a*/ /*@target=B.a*/ a);
var v_postfix_pp = (new /*@ type=B* */ B()
- . /*@ type=A* */ /*@target=B::a*/ /*@target=B::a*/
- /*@ type=int* */ a /*@ target=A::+ */ ++);
+ . /*@ type=A* */ /*@target=B.a*/ /*@target=B.a*/
+ /*@ type=int* */ a /*@target=A.+*/ ++);
var v_postfix_mm = (new /*@ type=B* */ B()
- . /*@ type=A* */ /*@target=B::a*/ /*@target=B::a*/
- /*@ type=double* */ a /*@ target=A::- */ --);
+ . /*@ type=A* */ /*@target=B.a*/ /*@target=B.a*/
+ /*@ type=double* */ a /*@target=A.-*/ --);
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
index 673684a..f0cbd54 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
@@ -2,26 +2,26 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:39: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:36: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-// var v_prefix_pp = (/*@ target=A::+ */ ++new /*@ type=B* */ B()
-// ^
+// var v_prefix_pp = (/*@target=A.+*/ ++new /*@ type=B* */ B()
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:39: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:36: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-// var v_prefix_mm = (/*@ target=A::- */ --new /*@ type=B* */ B()
-// ^
+// var v_prefix_mm = (/*@target=A.-*/ --new /*@ type=B* */ B()
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:23:43: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:23:40: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-// /*@ type=int* */ a /*@ target=A::+ */ ++);
+// /*@ type=int* */ a /*@target=A.+*/ ++);
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:26:43: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
+// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
+// /*@ type=double* */ a /*@target=A.-*/ --);
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:26:46: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
-// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-// /*@ type=double* */ a /*@ target=A::- */ --);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -60,20 +60,20 @@
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
-static field core::int* v_prefix_pp = let final self::B* #t1 = new self::B::•() in #t1.{self::B::a} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:39: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
+static field core::int* v_prefix_pp = let final self::B* #t1 = new self::B::•() in #t1.{self::B::a} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:36: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-var v_prefix_pp = (/*@ target=A::+ */ ++new /*@ type=B* */ B()
- ^" in #t1.{self::B::a}.{self::A::+}(1) as{TypeError} self::A*;
-static field core::double* v_prefix_mm = let final self::B* #t3 = new self::B::•() in #t3.{self::B::a} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:39: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
+var v_prefix_pp = (/*@target=A.+*/ ++new /*@ type=B* */ B()
+ ^" in #t1.{self::B::a}.{self::A::+}(1) as{TypeError} self::A*;
+static field core::double* v_prefix_mm = let final self::B* #t3 = new self::B::•() in #t3.{self::B::a} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:36: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-var v_prefix_mm = (/*@ target=A::- */ --new /*@ type=B* */ B()
- ^" in #t3.{self::B::a}.{self::A::-}(1) as{TypeError} self::A*;
-static field self::A* v_postfix_pp = let final self::B* #t5 = new self::B::•() in let final self::A* #t6 = #t5.{self::B::a} in let final core::int* #t7 = #t5.{self::B::a} = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:23:43: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
+var v_prefix_mm = (/*@target=A.-*/ --new /*@ type=B* */ B()
+ ^" in #t3.{self::B::a}.{self::A::-}(1) as{TypeError} self::A*;
+static field self::A* v_postfix_pp = let final self::B* #t5 = new self::B::•() in let final self::A* #t6 = #t5.{self::B::a} in let final core::int* #t7 = #t5.{self::B::a} = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:23:40: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
- /*@ type=int* */ a /*@ target=A::+ */ ++);
- ^" in #t6.{self::A::+}(1) as{TypeError} self::A* in #t6;
-static field self::A* v_postfix_mm = let final self::B* #t9 = new self::B::•() in let final self::A* #t10 = #t9.{self::B::a} in let final core::double* #t11 = #t9.{self::B::a} = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:26:46: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
+ /*@ type=int* */ a /*@target=A.+*/ ++);
+ ^" in #t6.{self::A::+}(1) as{TypeError} self::A* in #t6;
+static field self::A* v_postfix_mm = let final self::B* #t9 = new self::B::•() in let final self::A* #t10 = #t9.{self::B::a} in let final core::double* #t11 = #t9.{self::B::a} = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:26:43: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
- /*@ type=double* */ a /*@ target=A::- */ --);
- ^" in #t10.{self::A::-}(1) as{TypeError} self::A* in #t10;
+ /*@ type=double* */ a /*@target=A.-*/ --);
+ ^" in #t10.{self::A::-}(1) as{TypeError} self::A* in #t10;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart
index f94a25c..06d6032 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart
@@ -22,47 +22,42 @@
B member;
static void test(Test t) {
- t. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ -- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member;
- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::- */ --;
+ t. /*@target=Test.member*/ member = /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
+ /*@target=B.-*/ -- /*@ type=Test* */ t
+ . /*@target=Test.member*/ /*@target=Test.member*/ member;
+ /*@ type=Test* */ t. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.-*/ --;
var /*@ type=B* */ v1 =
- t. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ t. /*@target=Test.member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
/*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ . /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
/*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ . /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
/*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ . /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
/*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ -- /*@ type=Test* */ t
- . /*@target=Test::member*/ /*@target=Test::member*/ member;
+ . /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
+ var /*@ type=B* */ v6 = /*@target=B.-*/ -- /*@ type=Test* */ t
+ . /*@target=Test.member*/ /*@target=Test.member*/ member;
var /*@ type=B* */ v7 = /*@ type=Test* */ t
- . /*@ type=B* */ /*@target=Test::member*/ /*@target=Test::member*/
- /*@ type=B* */ member /*@ target=B::- */ --;
+ . /*@ type=B* */ /*@target=Test.member*/ /*@target=Test.member*/
+ /*@ type=B* */ member /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
index 230ebf4..4449b88 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
@@ -22,62 +22,62 @@
B member;
static void test(Test t) {
- /*@ type=Test* */ /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ member = /*@ typeArgs=B* */ f();
- /*@target=Test::==*/ t?.
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=Test.==*/ t?.
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- /*@target=Test::==*/ t?.
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=Test.==*/ t?.
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- /*@target=Test::==*/ t?.
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=Test.==*/ t?.
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- /*@target=Test::==*/ t?.
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=Test.==*/ t?.
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ -- /*@target=Test::==*/ t?.
- /*@target=Test::member*/ /*@target=Test::member*/ member;
+ /*@target=B.-*/ -- /*@target=Test.==*/ t?.
+ /*@target=Test.member*/ /*@target=Test.member*/ member;
- /*@target=Test::==*/ t?.
- /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::- */ --;
+ /*@target=Test.==*/ t?.
+ /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.-*/ --;
var /*@ type=B* */ v1 =
- /*@ type=Test* */ /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ -- /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ -- /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member;
- var /*@ type=B* */ v7 = /*@target=Test::==*/ t
- ?. /*@target=Test::member*/ /*@target=Test::member*/ member
- /*@ target=B::- */ --;
+ var /*@ type=B* */ v7 = /*@target=Test.==*/ t
+ ?. /*@target=Test.member*/ /*@target=Test.member*/ member
+ /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
index 623974e..1bb125b 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
@@ -13,35 +13,35 @@
int prop;
static void test(Test1 t) {
- var /*@ type=int* */ v1 = /*@ type=Test1* */ /*@target=Test1::==*/ t
- ?. /*@target=Test1::prop*/ prop = getInt();
+ var /*@ type=int* */ v1 = /*@ type=Test1* */ /*@target=Test1.==*/ t
+ ?. /*@target=Test1.prop*/ prop = getInt();
- var /*@ type=num* */ v2 = /*@ type=Test1* */ /*@target=Test1::==*/ t
- ?. /*@target=Test1::prop*/ prop = getNum();
+ var /*@ type=num* */ v2 = /*@ type=Test1* */ /*@target=Test1.==*/ t
+ ?. /*@target=Test1.prop*/ prop = getNum();
- var /*@ type=int* */ v4 = /*@target=Test1::==*/ t?.
- /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@ target=num::== */ ??= getInt();
+ var /*@ type=int* */ v4 = /*@target=Test1.==*/ t?.
+ /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = /*@target=Test1::==*/ t?.
- /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = /*@target=Test1.==*/ t?.
+ /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=int* */ v7 = /*@target=Test1::==*/ t?.
- /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@ target=num::+ */ += getInt();
+ var /*@ type=int* */ v7 = /*@target=Test1.==*/ t?.
+ /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = /*@target=Test1::==*/ t?.
- /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = /*@target=Test1.==*/ t?.
+ /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.+*/ += getNum();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++
- /*@target=Test1::==*/ t?.
- /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++
+ /*@target=Test1.==*/ t?.
+ /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop;
- var /*@ type=int* */ v11 = /*@target=Test1::==*/ t?.
- /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@ target=num::+ */ ++;
+ var /*@ type=int* */ v11 = /*@target=Test1.==*/ t?.
+ /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.+*/ ++;
}
}
@@ -49,45 +49,45 @@
num prop;
static void test(Test2 t) {
- var /*@ type=int* */ v1 = /*@ type=Test2* */ /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ prop = getInt();
+ var /*@ type=int* */ v1 = /*@ type=Test2* */ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ prop = getInt();
- var /*@ type=num* */ v2 = /*@ type=Test2* */ /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ prop = getNum();
+ var /*@ type=num* */ v2 = /*@ type=Test2* */ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ prop = getNum();
- var /*@ type=double* */ v3 = /*@ type=Test2* */ /*@target=Test2::==*/ t
- ?. /*@target=Test2::prop*/ prop = getDouble();
+ var /*@ type=double* */ v3 = /*@ type=Test2* */ /*@target=Test2.==*/ t
+ ?. /*@target=Test2.prop*/ prop = getDouble();
- var /*@ type=num* */ v4 = /*@target=Test2::==*/ t?.
- /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::== */ ??= getInt();
+ var /*@ type=num* */ v4 = /*@target=Test2.==*/ t?.
+ /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = /*@target=Test2::==*/ t?.
- /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = /*@target=Test2.==*/ t?.
+ /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = /*@target=Test2::==*/ t?.
- /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::== */ ??= getDouble();
+ var /*@ type=num* */ v6 = /*@target=Test2.==*/ t?.
+ /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getDouble();
- var /*@ type=num* */ v7 = /*@target=Test2::==*/ t?.
- /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v7 = /*@target=Test2.==*/ t?.
+ /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = /*@target=Test2::==*/ t?.
- /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = /*@target=Test2.==*/ t?.
+ /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v9 = /*@target=Test2::==*/ t?.
- /*@target=Test2::prop*/ /*@target=Test2::prop*/
- prop /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v9 = /*@target=Test2.==*/ t?.
+ /*@target=Test2.prop*/ /*@target=Test2.prop*/
+ prop /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++ /*@target=Test2::==*/
- t?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++ /*@target=Test2.==*/
+ t?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop;
- var /*@ type=num* */ v11 = /*@target=Test2::==*/
- t?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ ++;
+ var /*@ type=num* */ v11 = /*@target=Test2.==*/
+ t?. /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ ++;
}
}
@@ -95,41 +95,41 @@
double prop;
static void test3(Test3 t) {
- var /*@ type=num* */ v2 = /*@ type=Test3* */ /*@target=Test3::==*/ t
- ?. /*@target=Test3::prop*/ prop = getNum();
+ var /*@ type=num* */ v2 = /*@ type=Test3* */ /*@target=Test3.==*/ t
+ ?. /*@target=Test3.prop*/ prop = getNum();
- var /*@ type=double* */ v3 = /*@ type=Test3* */ /*@target=Test3::==*/ t
- ?. /*@target=Test3::prop*/ prop = getDouble();
+ var /*@ type=double* */ v3 = /*@ type=Test3* */ /*@target=Test3.==*/ t
+ ?. /*@target=Test3.prop*/ prop = getDouble();
- var /*@ type=num* */ v5 = /*@target=Test3::==*/ t?.
- /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = /*@target=Test3.==*/ t?.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v6 =
- /*@target=Test3::==*/ t?.
- /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=num::== */ ??= getDouble();
+ /*@target=Test3.==*/ t?.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 = /*@target=Test3::==*/ t?.
- /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 = /*@target=Test3.==*/ t?.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getInt();
- var /*@ type=double* */ v8 = /*@target=Test3::==*/ t?.
- /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 = /*@target=Test3.==*/ t?.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 =
- /*@target=Test3::==*/ t?.
- /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getDouble();
+ /*@target=Test3.==*/ t?.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++
- /*@target=Test3::==*/ t?.
- /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop;
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++
+ /*@target=Test3.==*/ t?.
+ /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop;
- var /*@ type=double* */ v11 = /*@target=Test3::==*/
- t?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ ++;
+ var /*@ type=double* */ v11 = /*@target=Test3.==*/
+ t?. /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart
index 3ba3540..0b116bc 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart
@@ -24,53 +24,53 @@
class Test extends Base {
void test() {
- super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ member = /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --super
- . /*@target=Base::member*/ /*@target=Base::member*/ member;
+ /*@target=B.-*/ --super
+ . /*@target=Base.member*/ /*@target=Base.member*/ member;
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::- */ --;
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.-*/ --;
var /*@ type=B* */ v1 =
- super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- super. /*@target=Base::member*/ /*@target=Base::member*/ member
- /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ super. /*@target=Base.member*/ /*@target=Base.member*/ member
+ /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --super
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --super
.
- /*@target=Base::member*/ /*@target=Base::member*/ member;
+ /*@target=Base.member*/ /*@target=Base.member*/ member;
var /*@ type=B* */ v7 = super
.
- /*@ type=B* */ /*@target=Base::member*/ /*@target=Base::member*/
- /*@ type=B* */ member /*@ target=B::- */ --;
+ /*@ type=B* */ /*@target=Base.member*/ /*@target=Base.member*/
+ /*@ type=B* */ member /*@target=B.-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart
index 8773a33..599d5f3 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart
@@ -18,116 +18,116 @@
class Test1 extends Base {
void test() {
var /*@ type=int* */ v1 =
- super. /*@target=Base::intProp*/ intProp = getInt();
+ super. /*@target=Base.intProp*/ intProp = getInt();
var /*@ type=num* */ v2 =
- super. /*@target=Base::intProp*/ intProp = getNum();
+ super. /*@target=Base.intProp*/ intProp = getNum();
var /*@ type=int* */ v4 =
- super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
- /*@ target=num::== */ ??= getInt();
+ super. /*@target=Base.intProp*/ /*@target=Base.intProp*/ intProp
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
- /*@ target=num::== */ ??= getNum();
+ super. /*@target=Base.intProp*/ /*@target=Base.intProp*/ intProp
+ /*@target=num.==*/ ??= getNum();
var /*@ type=int* */ v7 =
- super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
- /*@ target=num::+ */ += getInt();
+ super. /*@target=Base.intProp*/ /*@target=Base.intProp*/ intProp
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
- /*@ target=num::+ */ += getNum();
+ super. /*@target=Base.intProp*/ /*@target=Base.intProp*/ intProp
+ /*@target=num.+*/ += getNum();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
- . /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++super
+ . /*@target=Base.intProp*/ /*@target=Base.intProp*/ intProp;
var /*@ type=int* */ v11 = super
- . /*@ type=int* */ /*@target=Base::intProp*/ /*@target=Base::intProp*/
- /*@ type=int* */ intProp /*@ target=num::+ */ ++;
+ . /*@ type=int* */ /*@target=Base.intProp*/ /*@target=Base.intProp*/
+ /*@ type=int* */ intProp /*@target=num.+*/ ++;
}
}
class Test2 extends Base {
void test() {
var /*@ type=int* */ v1 =
- super. /*@target=Base::numProp*/ numProp = getInt();
+ super. /*@target=Base.numProp*/ numProp = getInt();
var /*@ type=num* */ v2 =
- super. /*@target=Base::numProp*/ numProp = getNum();
+ super. /*@target=Base.numProp*/ numProp = getNum();
var /*@ type=double* */ v3 =
- super. /*@target=Base::numProp*/ numProp = getDouble();
+ super. /*@target=Base.numProp*/ numProp = getDouble();
var /*@ type=num* */ v4 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::== */ ??= getInt();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::== */ ??= getNum();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::== */ ??= getDouble();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::+ */ += getInt();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::+ */ += getNum();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 =
- super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
- /*@ target=num::+ */ += getDouble();
+ super. /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp
+ /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
- . /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++super
+ . /*@target=Base.numProp*/ /*@target=Base.numProp*/ numProp;
var /*@ type=num* */ v11 = super
- . /*@ type=num* */ /*@target=Base::numProp*/ /*@target=Base::numProp*/
- /*@ type=num* */ numProp /*@ target=num::+ */ ++;
+ . /*@ type=num* */ /*@target=Base.numProp*/ /*@target=Base.numProp*/
+ /*@ type=num* */ numProp /*@target=num.+*/ ++;
}
}
class Test3 extends Base {
void test3() {
var /*@ type=num* */ v2 =
- super. /*@target=Base::doubleProp*/ doubleProp = getNum();
+ super. /*@target=Base.doubleProp*/ doubleProp = getNum();
var /*@ type=double* */ v3 =
- super. /*@target=Base::doubleProp*/ doubleProp = getDouble();
+ super. /*@target=Base.doubleProp*/ doubleProp = getDouble();
var /*@ type=num* */ v5 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
- /*@ target=num::== */ ??= getNum();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/ doubleProp
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v6 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
- /*@ target=num::== */ ??= getDouble();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/ doubleProp
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
- doubleProp /*@ target=double::+ */ += getInt();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/
+ doubleProp /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
- doubleProp /*@ target=double::+ */ += getNum();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/
+ doubleProp /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 = super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
- doubleProp /*@ target=double::+ */ += getDouble();
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/
+ doubleProp /*@target=double.+*/ += getDouble();
var /*@ type=double* */ v10 =
- /*@ target=double::+ */ ++super
- . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
+ /*@target=double.+*/ ++super
+ . /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/
doubleProp;
var /*@ type=double* */ v11 = super
- . /*@ type=double* */ /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
- /*@ type=double* */ doubleProp /*@ target=double::+ */ ++;
+ . /*@ type=double* */ /*@target=Base.doubleProp*/ /*@target=Base.doubleProp*/
+ /*@ type=double* */ doubleProp /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart
index 069816c..e8cd979 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart
@@ -13,26 +13,26 @@
int prop;
static void test(Test1 t) {
- var /*@ type=int* */ v1 = t. /*@target=Test1::prop*/ prop = getInt();
- var /*@ type=num* */ v2 = t. /*@target=Test1::prop*/ prop = getNum();
+ var /*@ type=int* */ v1 = t. /*@target=Test1.prop*/ prop = getInt();
+ var /*@ type=num* */ v2 = t. /*@target=Test1.prop*/ prop = getNum();
var /*@ type=int* */ v4 = /*@ type=Test1* */ t
- . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@target=num::==*/ ??= getInt();
+ . /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = /*@ type=Test1* */ t
- . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@target=num::==*/ ??= getNum();
+ . /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.==*/ ??= getNum();
var /*@ type=int* */ v7 = /*@ type=Test1* */ t
- . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@ target=num::+ */ += getInt();
+ . /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 = /*@ type=Test1* */ t
- . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
- /*@ target=num::+ */ += getNum();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++ /*@ type=Test1* */ t
- . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop;
+ . /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop
+ /*@target=num.+*/ += getNum();
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++ /*@ type=Test1* */ t
+ . /*@target=Test1.prop*/ /*@target=Test1.prop*/ prop;
var /*@ type=int* */ v11 =
/*@ type=Test1* */ t
- . /*@ type=int* */ /*@target=Test1::prop*/ /*@target=Test1::prop*/
- /*@ type=int* */ prop /*@ target=num::+ */ ++;
+ . /*@ type=int* */ /*@target=Test1.prop*/ /*@target=Test1.prop*/
+ /*@ type=int* */ prop /*@target=num.+*/ ++;
}
}
@@ -40,33 +40,33 @@
num prop;
static void test(Test2 t) {
- var /*@ type=int* */ v1 = t. /*@target=Test2::prop*/ prop = getInt();
- var /*@ type=num* */ v2 = t. /*@target=Test2::prop*/ prop = getNum();
- var /*@ type=double* */ v3 = t. /*@target=Test2::prop*/ prop = getDouble();
+ var /*@ type=int* */ v1 = t. /*@target=Test2.prop*/ prop = getInt();
+ var /*@ type=num* */ v2 = t. /*@target=Test2.prop*/ prop = getNum();
+ var /*@ type=double* */ v3 = t. /*@target=Test2.prop*/ prop = getDouble();
var /*@ type=num* */ v4 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getInt();
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getInt();
var /*@ type=num* */ v5 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getNum();
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getNum();
var /*@ type=num* */ v6 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@target=num::==*/ ??= getDouble();
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=num* */ v7 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ += getInt();
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getInt();
var /*@ type=num* */ v8 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ += getNum();
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getNum();
var /*@ type=num* */ v9 = /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
- /*@ target=num::+ */ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++ /*@ type=Test2* */ t
- . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop;
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop
+ /*@target=num.+*/ += getDouble();
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++ /*@ type=Test2* */ t
+ . /*@target=Test2.prop*/ /*@target=Test2.prop*/ prop;
var /*@ type=num* */ v11 =
/*@ type=Test2* */ t
- . /*@ type=num* */ /*@target=Test2::prop*/ /*@target=Test2::prop*/
- /*@ type=num* */ prop /*@ target=num::+ */ ++;
+ . /*@ type=num* */ /*@target=Test2.prop*/ /*@target=Test2.prop*/
+ /*@ type=num* */ prop /*@target=num.+*/ ++;
}
}
@@ -74,29 +74,29 @@
double prop;
static void test3(Test3 t) {
- var /*@ type=num* */ v2 = t. /*@target=Test3::prop*/ prop = getNum();
- var /*@ type=double* */ v3 = t. /*@target=Test3::prop*/ prop = getDouble();
+ var /*@ type=num* */ v2 = t. /*@target=Test3.prop*/ prop = getNum();
+ var /*@ type=double* */ v3 = t. /*@target=Test3.prop*/ prop = getDouble();
var /*@ type=num* */ v5 = /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@target=num::==*/ ??= getNum();
+ . /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v6 = /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@target=num::==*/ ??= getDouble();
+ . /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=num.==*/ ??= getDouble();
var /*@ type=double* */ v7 = /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getInt();
+ . /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getInt();
var /*@ type=double* */ v8 = /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getNum();
+ . /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 = /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
- /*@ target=double::+ */ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++ /*@ type=Test3* */ t
- . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop;
+ . /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop
+ /*@target=double.+*/ += getDouble();
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++ /*@ type=Test3* */ t
+ . /*@target=Test3.prop*/ /*@target=Test3.prop*/ prop;
var /*@ type=double* */ v11 =
/*@ type=Test3* */ t
- . /*@ type=double* */ /*@target=Test3::prop*/ /*@target=Test3::prop*/
- /*@ type=double* */ prop /*@ target=double::+ */ ++;
+ . /*@ type=double* */ /*@target=Test3.prop*/ /*@target=Test3.prop*/
+ /*@ type=double* */ prop /*@target=double.+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart
index 3416a62..574a106 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart
@@ -10,7 +10,7 @@
}
A a = new A();
-var b = (a. /*@target=A::f*/ f = 1);
+var b = (a. /*@target=A.f*/ f = 1);
var c = 0;
var d = (c = 1);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart
index 9021f82..3476095 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart
@@ -25,71 +25,71 @@
void test_topLevelVariable() {
topLevelVariable = /*@ typeArgs=B* */ f();
- topLevelVariable /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ topLevelVariable /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- topLevelVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ topLevelVariable /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- topLevelVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ topLevelVariable /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- topLevelVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ topLevelVariable /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --topLevelVariable;
+ /*@target=B.-*/ --topLevelVariable;
- topLevelVariable /*@ target=B::- */ --;
+ topLevelVariable /*@target=B.-*/ --;
var /*@ type=B* */ v1 = topLevelVariable = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- topLevelVariable /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ topLevelVariable /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- topLevelVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ topLevelVariable /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- topLevelVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ topLevelVariable /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- topLevelVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ topLevelVariable /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --topLevelVariable;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --topLevelVariable;
var /*@ type=B* */ v7 = /*@ type=B* */ topLevelVariable
- /*@ type=B* */ /*@ target=B::- */ --;
+ /*@ type=B* */ /*@target=B.-*/ --;
}
void test_staticVariable() {
B.staticVariable = /*@ typeArgs=B* */ f();
- B.staticVariable /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ B.staticVariable /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
- B.staticVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ B.staticVariable /*@target=B.+*/ += /*@ typeArgs=C* */ f();
- B.staticVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ B.staticVariable /*@target=B.**/ *= /*@ typeArgs=B* */ f();
- B.staticVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ B.staticVariable /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- /*@ target=B::- */ --B.staticVariable;
+ /*@target=B.-*/ --B.staticVariable;
- B.staticVariable /*@ target=B::- */ --;
+ B.staticVariable /*@target=B.-*/ --;
var /*@ type=B* */ v1 = B.staticVariable = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- B.staticVariable /*@target=A::==*/ ??= /*@ typeArgs=B* */ f();
+ B.staticVariable /*@target=A.==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- B.staticVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ B.staticVariable /*@target=B.+*/ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- B.staticVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ B.staticVariable /*@target=B.**/ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- B.staticVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ B.staticVariable /*@target=B.&*/ &= /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = /*@ target=B::- */ --B.staticVariable;
+ var /*@ type=B* */ v6 = /*@target=B.-*/ --B.staticVariable;
var /*@ type=B* */ v7 =
- B. /*@ type=B* */ staticVariable /*@ type=B* */ /*@ target=B::- */ --;
+ B. /*@ type=B* */ staticVariable /*@ type=B* */ /*@target=B.-*/ --;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart
index 4f08b48..f79bce3 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart
@@ -18,18 +18,18 @@
var /*@ type=num* */ v2 = topLevelInt = getNum();
- var /*@ type=int* */ v4 = topLevelInt /*@ target=num::== */ ??= getInt();
+ var /*@ type=int* */ v4 = topLevelInt /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = topLevelInt /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = topLevelInt /*@target=num.==*/ ??= getNum();
- var /*@ type=int* */ v7 = topLevelInt /*@ target=num::+ */ += getInt();
+ var /*@ type=int* */ v7 = topLevelInt /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = topLevelInt /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = topLevelInt /*@target=num.+*/ += getNum();
- var /*@ type=int* */ v10 = /*@ target=num::+ */ ++topLevelInt;
+ var /*@ type=int* */ v10 = /*@target=num.+*/ ++topLevelInt;
var /*@ type=int* */ v11 = /*@ type=int* */ topLevelInt
- /*@ type=int* */ /*@ target=num::+ */ ++;
+ /*@ type=int* */ /*@target=num.+*/ ++;
}
void test2() {
@@ -39,22 +39,22 @@
var /*@ type=double* */ v3 = topLevelNum = getDouble();
- var /*@ type=num* */ v4 = topLevelNum /*@ target=num::== */ ??= getInt();
+ var /*@ type=num* */ v4 = topLevelNum /*@target=num.==*/ ??= getInt();
- var /*@ type=num* */ v5 = topLevelNum /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = topLevelNum /*@target=num.==*/ ??= getNum();
- var /*@ type=num* */ v6 = topLevelNum /*@ target=num::== */ ??= getDouble();
+ var /*@ type=num* */ v6 = topLevelNum /*@target=num.==*/ ??= getDouble();
- var /*@ type=num* */ v7 = topLevelNum /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v7 = topLevelNum /*@target=num.+*/ += getInt();
- var /*@ type=num* */ v8 = topLevelNum /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v8 = topLevelNum /*@target=num.+*/ += getNum();
- var /*@ type=num* */ v9 = topLevelNum /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v9 = topLevelNum /*@target=num.+*/ += getDouble();
- var /*@ type=num* */ v10 = /*@ target=num::+ */ ++topLevelNum;
+ var /*@ type=num* */ v10 = /*@target=num.+*/ ++topLevelNum;
var /*@ type=num* */ v11 = /*@ type=num* */ topLevelNum
- /*@ type=num* */ /*@ target=num::+ */ ++;
+ /*@ type=num* */ /*@target=num.+*/ ++;
}
void test3() {
@@ -62,24 +62,22 @@
var /*@ type=double* */ v3 = topLevelDouble = getDouble();
- var /*@ type=num* */ v5 = topLevelDouble /*@ target=num::== */ ??= getNum();
+ var /*@ type=num* */ v5 = topLevelDouble /*@target=num.==*/ ??= getNum();
var /*@ type=double* */ v6 =
- topLevelDouble /*@ target=num::== */ ??= getDouble();
+ topLevelDouble /*@target=num.==*/ ??= getDouble();
- var /*@ type=double* */ v7 =
- topLevelDouble /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v7 = topLevelDouble /*@target=double.+*/ += getInt();
- var /*@ type=double* */ v8 =
- topLevelDouble /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v8 = topLevelDouble /*@target=double.+*/ += getNum();
var /*@ type=double* */ v9 =
- topLevelDouble /*@ target=double::+ */ += getDouble();
+ topLevelDouble /*@target=double.+*/ += getDouble();
- var /*@ type=double* */ v10 = /*@ target=double::+ */ ++topLevelDouble;
+ var /*@ type=double* */ v10 = /*@target=double.+*/ ++topLevelDouble;
var /*@ type=double* */ v11 = /*@ type=double* */ topLevelDouble
- /*@ type=double* */ /*@ target=double::+ */ ++;
+ /*@ type=double* */ /*@target=double.+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart
index 05da853..1d35c08 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart
@@ -19,9 +19,8 @@
class D extends C {}
var a = new A();
-var x = a. /*@target=A::b*/ b. /*@target=B::c*/ c;
-var y =
- a. /*@ type=B* */ /*@target=A::b*/ b. /*@target=B::c*/ /*@target=B::c*/ c
- /*@target=C::==*/ ??= new D();
+var x = a. /*@target=A.b*/ b. /*@target=B.c*/ c;
+var y = a. /*@ type=B* */ /*@target=A.b*/ b. /*@target=B.c*/ /*@target=B.c*/ c
+ /*@target=C.==*/ ??= new D();
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart
index 3fdcc26..2dad28c 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart
@@ -18,8 +18,8 @@
class D extends C {}
var a = new A();
-var x = a. /*@target=A::b*/ b. /*@target=B::c*/ c;
-var y = a. /*@ type=B* */ /*@target=A::b*/ b
- . /*@target=B::c*/ /*@target=B::c*/ c /*@target=C::==*/ ??= new D();
+var x = a. /*@target=A.b*/ b. /*@target=B.c*/ c;
+var y = a. /*@ type=B* */ /*@target=A.b*/ b
+ . /*@target=B.c*/ /*@target=B.c*/ c /*@target=C.==*/ ??= new D();
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
index ba79be3..c89d738 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
@@ -13,7 +13,7 @@
}
var a = new A();
-var x = /*@ returnType=invalid-type */ () => a. /*@target=A::b*/ b;
-var y = /*@ returnType=() ->* () ->* invalid-type */ () => a. /*@target=A::c*/ c;
+var x = /*@ returnType=invalid-type */ () => a. /*@target=A.b*/ b;
+var y = /*@ returnType=() ->* () ->* invalid-type */ () => a. /*@target=A.c*/ c;
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart
index a90fa93..5c8e415 100644
--- a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart
@@ -13,7 +13,7 @@
f() {}
}
-var x = new C(). /*info:USE_OF_VOID_RESULT*/ /*@target=C::f*/ f();
+var x = new C(). /*info:USE_OF_VOID_RESULT*/ /*@target=C.f*/ f();
main() {
x;
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart
index f627df4..d1f1fe7 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart
@@ -26,11 +26,11 @@
}
void g1(C c) {
- c. /*@target=C::f*/ f('hi');
+ c. /*@target=C.f*/ f('hi');
}
void g2(E e) {
- e. /*@target=I2::f*/ f('hi');
+ e. /*@target=I2.f*/ f('hi');
}
main() {
diff --git a/pkg/front_end/testcases/inference_new/null_aware_property_get.dart b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart
index 207824e..a7b2434 100644
--- a/pkg/front_end/testcases/inference_new/null_aware_property_get.dart
+++ b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart
@@ -11,6 +11,6 @@
main() {
Class c;
- num Function() f = /*@target=Class::==*/ /*@type=Class**/ c
- ?. /*@ target=Class::method */ method;
+ num Function() f = /*@target=Class.==*/ /*@type=Class**/ c
+ ?. /*@target=Class.method*/ method;
}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart
index 5b764735..71adde7 100644
--- a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart
@@ -32,28 +32,28 @@
}
void test1(G g) {
- /*@ type=G* */ g. /*@target=G::target*/ /*@target=G::target*/ target
- /*@ target=A::* */ *=
+ /*@ type=G* */ g. /*@target=G.target*/ /*@target=G.target*/ target
+ /*@target=A.**/ *=
/*@ typeArgs=D* */ f();
var /*@ type=C* */ x =
- /*@ type=G* */ g. /*@target=G::target*/ /*@target=G::target*/ target
- /*@ target=A::* */ *=
+ /*@ type=G* */ g. /*@target=G.target*/ /*@target=G.target*/ target
+ /*@target=A.**/ *=
/*@ typeArgs=D* */ f();
}
void test2(G g) {
- /*@ target=A::+ */ ++ /*@ type=G* */ g
- . /*@target=G::target*/ /*@target=G::target*/ target;
- var /*@ type=C* */ x = /*@ target=A::+ */ ++ /*@ type=G* */ g
- . /*@target=G::target*/ /*@target=G::target*/ target;
+ /*@target=A.+*/ ++ /*@ type=G* */ g
+ . /*@target=G.target*/ /*@target=G.target*/ target;
+ var /*@ type=C* */ x = /*@target=A.+*/ ++ /*@ type=G* */ g
+ . /*@target=G.target*/ /*@target=G.target*/ target;
}
void test3(G g) {
/*@ type=G* */ g
- . /*@target=G::target*/ /*@target=G::target*/ target /*@ target=A::+ */ ++;
- var /*@ type=A* */ x = /*@ type=G* */ g. /*@ type=A* */ /*@target=G::target*/
- /*@target=G::target*/ /*@ type=C* */ target
- /*@ target=A::+ */ ++;
+ . /*@target=G.target*/ /*@target=G.target*/ target /*@target=A.+*/ ++;
+ var /*@ type=A* */ x = /*@ type=G* */ g. /*@ type=A* */ /*@target=G.target*/
+ /*@target=G.target*/ /*@ type=C* */ target
+ /*@target=A.+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart
index c5af4df..cdea649 100644
--- a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart
+++ b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart
@@ -12,13 +12,13 @@
}
C c = new C();
-var field_ref = c. /*@target=C::field*/ field;
-var getter_ref = c. /*@target=C::getter*/ getter;
-var function_ref = c. /*@target=C::function*/ function;
-var field_ref_list = /*@ typeArgs=int* */ [c. /*@target=C::field*/ field];
-var getter_ref_list = /*@ typeArgs=int* */ [c. /*@target=C::getter*/ getter];
+var field_ref = c. /*@target=C.field*/ field;
+var getter_ref = c. /*@target=C.getter*/ getter;
+var function_ref = c. /*@target=C.function*/ function;
+var field_ref_list = /*@ typeArgs=int* */ [c. /*@target=C.field*/ field];
+var getter_ref_list = /*@ typeArgs=int* */ [c. /*@target=C.getter*/ getter];
var function_ref_list = /*@ typeArgs=() ->* int* */ [
- c. /*@target=C::function*/ function
+ c. /*@target=C.function*/ function
];
main() {}
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart
index 15084a1..f0b39e9 100644
--- a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart
@@ -30,19 +30,19 @@
void set target(B value) {}
void test1() {
- target /*@ target=A::* */ *= /*@ typeArgs=D* */ f();
- var /*@ type=C* */ x = target /*@ target=A::* */ *= /*@ typeArgs=D* */ f();
+ target /*@target=A.**/ *= /*@ typeArgs=D* */ f();
+ var /*@ type=C* */ x = target /*@target=A.**/ *= /*@ typeArgs=D* */ f();
}
void test2() {
- /*@ target=A::+ */ ++target;
- var /*@ type=C* */ x = /*@ target=A::+ */ ++target;
+ /*@target=A.+*/ ++target;
+ var /*@ type=C* */ x = /*@target=A.+*/ ++target;
}
void test3() {
- target /*@ target=A::+ */ ++;
+ target /*@target=A.+*/ ++;
var /*@ type=A* */ x = /*@ type=A* */ target
- /*@ type=C* */ /*@ target=A::+ */ ++;
+ /*@ type=C* */ /*@target=A.+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart b/pkg/front_end/testcases/inference_new/super_index_get.dart
index 5bf9411..105d698 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get.dart
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart
@@ -16,7 +16,7 @@
class C extends B {
int operator [](Object x) => null;
void h() {
- var /*@ type=num* */ x = super /*@target=B::[]*/ [/*@ typeArgs=int* */ f()];
+ var /*@ type=num* */ x = super /*@target=B.[]*/ [/*@ typeArgs=int* */ f()];
}
}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart
index 68b938a..0226977 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart
@@ -21,7 +21,7 @@
E<Future<U>> operator [](Object x) => null;
void h() {
var /*@ type=D<Future<C::U*>*>* */ x =
- super /*@target=B::[]*/ [/*@ typeArgs=E<Future<C::U*>*>* */ f()];
+ super /*@target=B.[]*/ [/*@ typeArgs=E<Future<C::U*>*>* */ f()];
}
}
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart
index d687e58..361da3e 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart
@@ -37,6 +37,6 @@
// bar().foo resolves to G::foo, which is inherited from E::foo, so its return
// type is B. Note that the target is annotated as G::foo, since that is the
// forwarding stub.
-var x = bar(). /*@target=G::foo*/ foo();
+var x = bar(). /*@target=G.foo*/ foo();
main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart b/pkg/front_end/testcases/late_lowering/late_annotations.dart
new file mode 100644
index 0000000..5985562
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart
@@ -0,0 +1,75 @@
+// 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.
+
+class Annotation {
+ const Annotation();
+}
+
+@Annotation()
+late int topLevelField;
+
+@Annotation()
+late final int finalTopLevelField;
+
+@Annotation()
+late final int finalTopLevelFieldWithInitializer = 0;
+
+class A {
+ @Annotation()
+ late int instanceField;
+
+ @Annotation()
+ late final int finalInstanceField;
+
+ @Annotation()
+ late final int finalInstanceFieldWithInitializer = 0;
+
+ @Annotation()
+ covariant late num covariantInstanceField;
+
+ @Annotation()
+ static late int staticField;
+
+ @Annotation()
+ static late final int finalStaticField;
+
+ @Annotation()
+ static late final int finalStaticFieldWithInitializer = 0;
+}
+
+mixin B {
+ @Annotation()
+ late int instanceField;
+
+ @Annotation()
+ late final int finalInstanceField;
+
+ @Annotation()
+ late final int finalInstanceFieldWithInitializer = 0;
+
+ @Annotation()
+ covariant late num covariantInstanceField;
+
+ @Annotation()
+ static late int staticField;
+
+ @Annotation()
+ static late final int finalStaticField;
+
+ @Annotation()
+ static late final int finalStaticFieldWithInitializer = 0;
+}
+
+extension Extension on A {
+ @Annotation()
+ static late int extensionStaticField;
+
+ @Annotation()
+ static late final int finalExtensionStaticField;
+
+ @Annotation()
+ static late final int finalExtensionStaticFieldWithInitializer = 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.outline.expect
new file mode 100644
index 0000000..4b649e0
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.outline.expect
@@ -0,0 +1,115 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Annotation extends core::Object /*hasConstConstructor*/ {
+ const constructor •() → self::Annotation
+ : super core::Object::•()
+ ;
+}
+class A extends core::Object {
+ field core::int? _#A#instanceField;
+ field core::int? _#A#finalInstanceField;
+ field core::int? _#A#finalInstanceFieldWithInitializer;
+ field core::num? _#A#covariantInstanceField;
+ static field core::int? _#staticField;
+ static field core::int? _#finalStaticField;
+ static field core::int? _#finalStaticFieldWithInitializer;
+ synthetic constructor •() → self::A
+ ;
+ @self::Annotation::•()
+ get instanceField() → core::int;
+ @self::Annotation::•()
+ set instanceField(core::int #t1) → void;
+ @self::Annotation::•()
+ get finalInstanceField() → core::int;
+ @self::Annotation::•()
+ set finalInstanceField(core::int #t2) → void;
+ @self::Annotation::•()
+ get finalInstanceFieldWithInitializer() → core::int;
+ @self::Annotation::•()
+ get covariantInstanceField() → core::num;
+ @self::Annotation::•()
+ set covariantInstanceField(covariant core::num #t3) → void;
+ @self::Annotation::•()
+ static get staticField() → core::int;
+ @self::Annotation::•()
+ static set staticField(core::int #t4) → void;
+ @self::Annotation::•()
+ static get finalStaticField() → core::int;
+ @self::Annotation::•()
+ static set finalStaticField(core::int #t5) → void;
+ @self::Annotation::•()
+ static get finalStaticFieldWithInitializer() → core::int;
+}
+abstract class B extends core::Object /*isMixinDeclaration*/ {
+ field core::int? _#B#instanceField;
+ field core::int? _#B#finalInstanceField;
+ field core::int? _#B#finalInstanceFieldWithInitializer;
+ field core::num? _#B#covariantInstanceField;
+ static field core::int? _#staticField;
+ static field core::int? _#finalStaticField;
+ static field core::int? _#finalStaticFieldWithInitializer;
+ @self::Annotation::•()
+ get instanceField() → core::int;
+ @self::Annotation::•()
+ set instanceField(core::int #t6) → void;
+ @self::Annotation::•()
+ get finalInstanceField() → core::int;
+ @self::Annotation::•()
+ set finalInstanceField(core::int #t7) → void;
+ @self::Annotation::•()
+ get finalInstanceFieldWithInitializer() → core::int;
+ @self::Annotation::•()
+ get covariantInstanceField() → core::num;
+ @self::Annotation::•()
+ set covariantInstanceField(covariant core::num #t8) → void;
+ @self::Annotation::•()
+ static get staticField() → core::int;
+ @self::Annotation::•()
+ static set staticField(core::int #t9) → void;
+ @self::Annotation::•()
+ static get finalStaticField() → core::int;
+ @self::Annotation::•()
+ static set finalStaticField(core::int #t10) → void;
+ @self::Annotation::•()
+ static get finalStaticFieldWithInitializer() → core::int;
+}
+extension Extension on self::A {
+ static field extensionStaticField = self::_#Extension|extensionStaticField;
+ static get extensionStaticField = get self::Extension|extensionStaticField;
+ static set extensionStaticField = set self::Extension|extensionStaticField;
+ static field finalExtensionStaticField = self::_#Extension|finalExtensionStaticField;
+ static get finalExtensionStaticField = get self::Extension|finalExtensionStaticField;
+ static set finalExtensionStaticField = set self::Extension|finalExtensionStaticField;
+ static field finalExtensionStaticFieldWithInitializer = self::_#Extension|finalExtensionStaticFieldWithInitializer;
+ static get finalExtensionStaticFieldWithInitializer = get self::Extension|finalExtensionStaticFieldWithInitializer;
+}
+static field core::int? _#topLevelField;
+static field core::int? _#finalTopLevelField;
+static field core::int? _#finalTopLevelFieldWithInitializer;
+static field core::int? _#Extension|extensionStaticField;
+static field core::int? _#Extension|finalExtensionStaticField;
+static field core::int? _#Extension|finalExtensionStaticFieldWithInitializer;
+@self::Annotation::•()
+static get topLevelField() → core::int;
+@self::Annotation::•()
+static set topLevelField(core::int #t11) → void;
+@self::Annotation::•()
+static get finalTopLevelField() → core::int;
+@self::Annotation::•()
+static set finalTopLevelField(core::int #t12) → void;
+@self::Annotation::•()
+static get finalTopLevelFieldWithInitializer() → core::int;
+@self::Annotation::•()
+static get Extension|extensionStaticField() → core::int;
+@self::Annotation::•()
+static set Extension|extensionStaticField(core::int #t13) → void;
+@self::Annotation::•()
+static get Extension|finalExtensionStaticField() → core::int;
+@self::Annotation::•()
+static set Extension|finalExtensionStaticField(core::int #t14) → void;
+@self::Annotation::•()
+static get Extension|finalExtensionStaticFieldWithInitializer() → core::int;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.expect
new file mode 100644
index 0000000..44d325d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.expect
@@ -0,0 +1,172 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Annotation extends core::Object /*hasConstConstructor*/ {
+ const constructor •() → self::Annotation
+ : super core::Object::•()
+ ;
+}
+class A extends core::Object {
+ field core::int? _#A#instanceField = null;
+ field core::int? _#A#finalInstanceField = null;
+ field core::int? _#A#finalInstanceFieldWithInitializer = null;
+ field core::num? _#A#covariantInstanceField = null;
+ static field core::int? _#staticField = null;
+ static field core::int? _#finalStaticField = null;
+ static field core::int? _#finalStaticFieldWithInitializer = null;
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ @#C1
+ get instanceField() → core::int
+ return let final core::int? #t1 = this.{self::A::_#A#instanceField} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'instanceField' has not been initialized.") : #t1{core::int};
+ @#C1
+ set instanceField(core::int #t2) → void
+ this.{self::A::_#A#instanceField} = #t2;
+ @#C1
+ get finalInstanceField() → core::int
+ return let final core::int? #t3 = this.{self::A::_#A#finalInstanceField} in #t3.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has not been initialized.") : #t3{core::int};
+ @#C1
+ set finalInstanceField(core::int #t4) → void
+ if(this.{self::A::_#A#finalInstanceField}.==(null))
+ this.{self::A::_#A#finalInstanceField} = #t4;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has already been initialized.");
+ @#C1
+ get finalInstanceFieldWithInitializer() → core::int
+ return let final core::int? #t5 = this.{self::A::_#A#finalInstanceFieldWithInitializer} in #t5.==(null) ?{core::int} let final core::int #t6 = 0 in this.{self::A::_#A#finalInstanceFieldWithInitializer}.==(null) ?{core::int} this.{self::A::_#A#finalInstanceFieldWithInitializer} = #t6 : throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceFieldWithInitializer' has been assigned during initialization.") : #t5{core::int};
+ @#C1
+ get covariantInstanceField() → core::num
+ return let final core::num? #t7 = this.{self::A::_#A#covariantInstanceField} in #t7.==(null) ?{core::num} throw new _in::LateInitializationErrorImpl::•("Field 'covariantInstanceField' has not been initialized.") : #t7{core::num};
+ @#C1
+ set covariantInstanceField(covariant core::num #t8) → void
+ this.{self::A::_#A#covariantInstanceField} = #t8;
+ @#C1
+ static get staticField() → core::int
+ return let final core::int? #t9 = self::A::_#staticField in #t9.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'staticField' has not been initialized.") : #t9{core::int};
+ @#C1
+ static set staticField(core::int #t10) → void
+ self::A::_#staticField = #t10;
+ @#C1
+ static get finalStaticField() → core::int
+ return let final core::int? #t11 = self::A::_#finalStaticField in #t11.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has not been initialized.") : #t11{core::int};
+ @#C1
+ static set finalStaticField(core::int #t12) → void
+ if(self::A::_#finalStaticField.==(null))
+ self::A::_#finalStaticField = #t12;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has already been initialized.");
+ @#C1
+ static get finalStaticFieldWithInitializer() → core::int
+ return let final core::int? #t13 = self::A::_#finalStaticFieldWithInitializer in #t13.==(null) ?{core::int} let final core::int #t14 = 0 in self::A::_#finalStaticFieldWithInitializer.==(null) ?{core::int} self::A::_#finalStaticFieldWithInitializer = #t14 : throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticFieldWithInitializer' has been assigned during initialization.") : #t13{core::int};
+}
+abstract class B extends core::Object /*isMixinDeclaration*/ {
+ field core::int? _#B#instanceField = null;
+ field core::int? _#B#finalInstanceField = null;
+ field core::int? _#B#finalInstanceFieldWithInitializer = null;
+ field core::num? _#B#covariantInstanceField = null;
+ static field core::int? _#staticField = null;
+ static field core::int? _#finalStaticField = null;
+ static field core::int? _#finalStaticFieldWithInitializer = null;
+ @#C1
+ get instanceField() → core::int
+ return let final core::int? #t15 = this.{self::B::_#B#instanceField} in #t15.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'instanceField' has not been initialized.") : #t15{core::int};
+ @#C1
+ set instanceField(core::int #t16) → void
+ this.{self::B::_#B#instanceField} = #t16;
+ @#C1
+ get finalInstanceField() → core::int
+ return let final core::int? #t17 = this.{self::B::_#B#finalInstanceField} in #t17.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has not been initialized.") : #t17{core::int};
+ @#C1
+ set finalInstanceField(core::int #t18) → void
+ if(this.{self::B::_#B#finalInstanceField}.==(null))
+ this.{self::B::_#B#finalInstanceField} = #t18;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has already been initialized.");
+ @#C1
+ get finalInstanceFieldWithInitializer() → core::int
+ return let final core::int? #t19 = this.{self::B::_#B#finalInstanceFieldWithInitializer} in #t19.==(null) ?{core::int} let final core::int #t20 = 0 in this.{self::B::_#B#finalInstanceFieldWithInitializer}.==(null) ?{core::int} this.{self::B::_#B#finalInstanceFieldWithInitializer} = #t20 : throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceFieldWithInitializer' has been assigned during initialization.") : #t19{core::int};
+ @#C1
+ get covariantInstanceField() → core::num
+ return let final core::num? #t21 = this.{self::B::_#B#covariantInstanceField} in #t21.==(null) ?{core::num} throw new _in::LateInitializationErrorImpl::•("Field 'covariantInstanceField' has not been initialized.") : #t21{core::num};
+ @#C1
+ set covariantInstanceField(covariant core::num #t22) → void
+ this.{self::B::_#B#covariantInstanceField} = #t22;
+ @#C1
+ static get staticField() → core::int
+ return let final core::int? #t23 = self::B::_#staticField in #t23.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'staticField' has not been initialized.") : #t23{core::int};
+ @#C1
+ static set staticField(core::int #t24) → void
+ self::B::_#staticField = #t24;
+ @#C1
+ static get finalStaticField() → core::int
+ return let final core::int? #t25 = self::B::_#finalStaticField in #t25.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has not been initialized.") : #t25{core::int};
+ @#C1
+ static set finalStaticField(core::int #t26) → void
+ if(self::B::_#finalStaticField.==(null))
+ self::B::_#finalStaticField = #t26;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has already been initialized.");
+ @#C1
+ static get finalStaticFieldWithInitializer() → core::int
+ return let final core::int? #t27 = self::B::_#finalStaticFieldWithInitializer in #t27.==(null) ?{core::int} let final core::int #t28 = 0 in self::B::_#finalStaticFieldWithInitializer.==(null) ?{core::int} self::B::_#finalStaticFieldWithInitializer = #t28 : throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticFieldWithInitializer' has been assigned during initialization.") : #t27{core::int};
+}
+extension Extension on self::A {
+ static field extensionStaticField = self::_#Extension|extensionStaticField;
+ static get extensionStaticField = get self::Extension|extensionStaticField;
+ static set extensionStaticField = set self::Extension|extensionStaticField;
+ static field finalExtensionStaticField = self::_#Extension|finalExtensionStaticField;
+ static get finalExtensionStaticField = get self::Extension|finalExtensionStaticField;
+ static set finalExtensionStaticField = set self::Extension|finalExtensionStaticField;
+ static field finalExtensionStaticFieldWithInitializer = self::_#Extension|finalExtensionStaticFieldWithInitializer;
+ static get finalExtensionStaticFieldWithInitializer = get self::Extension|finalExtensionStaticFieldWithInitializer;
+}
+static field core::int? _#topLevelField = null;
+static field core::int? _#finalTopLevelField = null;
+static field core::int? _#finalTopLevelFieldWithInitializer = null;
+static field core::int? _#Extension|extensionStaticField = null;
+static field core::int? _#Extension|finalExtensionStaticField = null;
+static field core::int? _#Extension|finalExtensionStaticFieldWithInitializer = null;
+@#C1
+static get topLevelField() → core::int
+ return let final core::int? #t29 = self::_#topLevelField in #t29.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'topLevelField' has not been initialized.") : #t29{core::int};
+@#C1
+static set topLevelField(core::int #t30) → void
+ self::_#topLevelField = #t30;
+@#C1
+static get finalTopLevelField() → core::int
+ return let final core::int? #t31 = self::_#finalTopLevelField in #t31.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelField' has not been initialized.") : #t31{core::int};
+@#C1
+static set finalTopLevelField(core::int #t32) → void
+ if(self::_#finalTopLevelField.==(null))
+ self::_#finalTopLevelField = #t32;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelField' has already been initialized.");
+@#C1
+static get finalTopLevelFieldWithInitializer() → core::int
+ return let final core::int? #t33 = self::_#finalTopLevelFieldWithInitializer in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#finalTopLevelFieldWithInitializer.==(null) ?{core::int} self::_#finalTopLevelFieldWithInitializer = #t34 : throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelFieldWithInitializer' has been assigned during initialization.") : #t33{core::int};
+@#C1
+static get Extension|extensionStaticField() → core::int
+ return let final core::int? #t35 = self::_#Extension|extensionStaticField in #t35.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'extensionStaticField' has not been initialized.") : #t35{core::int};
+@#C1
+static set Extension|extensionStaticField(core::int #t36) → void
+ self::_#Extension|extensionStaticField = #t36;
+@#C1
+static get Extension|finalExtensionStaticField() → core::int
+ return let final core::int? #t37 = self::_#Extension|finalExtensionStaticField in #t37.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticField' has not been initialized.") : #t37{core::int};
+@#C1
+static set Extension|finalExtensionStaticField(core::int #t38) → void
+ if(self::_#Extension|finalExtensionStaticField.==(null))
+ self::_#Extension|finalExtensionStaticField = #t38;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticField' has already been initialized.");
+@#C1
+static get Extension|finalExtensionStaticFieldWithInitializer() → core::int
+ return let final core::int? #t39 = self::_#Extension|finalExtensionStaticFieldWithInitializer in #t39.==(null) ?{core::int} let final core::int #t40 = 0 in self::_#Extension|finalExtensionStaticFieldWithInitializer.==(null) ?{core::int} self::_#Extension|finalExtensionStaticFieldWithInitializer = #t40 : throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticFieldWithInitializer' has been assigned during initialization.") : #t39{core::int};
+static method main() → dynamic {}
+
+constants {
+ #C1 = self::Annotation {}
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.transformed.expect
new file mode 100644
index 0000000..44d325d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.strong.transformed.expect
@@ -0,0 +1,172 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Annotation extends core::Object /*hasConstConstructor*/ {
+ const constructor •() → self::Annotation
+ : super core::Object::•()
+ ;
+}
+class A extends core::Object {
+ field core::int? _#A#instanceField = null;
+ field core::int? _#A#finalInstanceField = null;
+ field core::int? _#A#finalInstanceFieldWithInitializer = null;
+ field core::num? _#A#covariantInstanceField = null;
+ static field core::int? _#staticField = null;
+ static field core::int? _#finalStaticField = null;
+ static field core::int? _#finalStaticFieldWithInitializer = null;
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ @#C1
+ get instanceField() → core::int
+ return let final core::int? #t1 = this.{self::A::_#A#instanceField} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'instanceField' has not been initialized.") : #t1{core::int};
+ @#C1
+ set instanceField(core::int #t2) → void
+ this.{self::A::_#A#instanceField} = #t2;
+ @#C1
+ get finalInstanceField() → core::int
+ return let final core::int? #t3 = this.{self::A::_#A#finalInstanceField} in #t3.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has not been initialized.") : #t3{core::int};
+ @#C1
+ set finalInstanceField(core::int #t4) → void
+ if(this.{self::A::_#A#finalInstanceField}.==(null))
+ this.{self::A::_#A#finalInstanceField} = #t4;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has already been initialized.");
+ @#C1
+ get finalInstanceFieldWithInitializer() → core::int
+ return let final core::int? #t5 = this.{self::A::_#A#finalInstanceFieldWithInitializer} in #t5.==(null) ?{core::int} let final core::int #t6 = 0 in this.{self::A::_#A#finalInstanceFieldWithInitializer}.==(null) ?{core::int} this.{self::A::_#A#finalInstanceFieldWithInitializer} = #t6 : throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceFieldWithInitializer' has been assigned during initialization.") : #t5{core::int};
+ @#C1
+ get covariantInstanceField() → core::num
+ return let final core::num? #t7 = this.{self::A::_#A#covariantInstanceField} in #t7.==(null) ?{core::num} throw new _in::LateInitializationErrorImpl::•("Field 'covariantInstanceField' has not been initialized.") : #t7{core::num};
+ @#C1
+ set covariantInstanceField(covariant core::num #t8) → void
+ this.{self::A::_#A#covariantInstanceField} = #t8;
+ @#C1
+ static get staticField() → core::int
+ return let final core::int? #t9 = self::A::_#staticField in #t9.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'staticField' has not been initialized.") : #t9{core::int};
+ @#C1
+ static set staticField(core::int #t10) → void
+ self::A::_#staticField = #t10;
+ @#C1
+ static get finalStaticField() → core::int
+ return let final core::int? #t11 = self::A::_#finalStaticField in #t11.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has not been initialized.") : #t11{core::int};
+ @#C1
+ static set finalStaticField(core::int #t12) → void
+ if(self::A::_#finalStaticField.==(null))
+ self::A::_#finalStaticField = #t12;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has already been initialized.");
+ @#C1
+ static get finalStaticFieldWithInitializer() → core::int
+ return let final core::int? #t13 = self::A::_#finalStaticFieldWithInitializer in #t13.==(null) ?{core::int} let final core::int #t14 = 0 in self::A::_#finalStaticFieldWithInitializer.==(null) ?{core::int} self::A::_#finalStaticFieldWithInitializer = #t14 : throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticFieldWithInitializer' has been assigned during initialization.") : #t13{core::int};
+}
+abstract class B extends core::Object /*isMixinDeclaration*/ {
+ field core::int? _#B#instanceField = null;
+ field core::int? _#B#finalInstanceField = null;
+ field core::int? _#B#finalInstanceFieldWithInitializer = null;
+ field core::num? _#B#covariantInstanceField = null;
+ static field core::int? _#staticField = null;
+ static field core::int? _#finalStaticField = null;
+ static field core::int? _#finalStaticFieldWithInitializer = null;
+ @#C1
+ get instanceField() → core::int
+ return let final core::int? #t15 = this.{self::B::_#B#instanceField} in #t15.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'instanceField' has not been initialized.") : #t15{core::int};
+ @#C1
+ set instanceField(core::int #t16) → void
+ this.{self::B::_#B#instanceField} = #t16;
+ @#C1
+ get finalInstanceField() → core::int
+ return let final core::int? #t17 = this.{self::B::_#B#finalInstanceField} in #t17.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has not been initialized.") : #t17{core::int};
+ @#C1
+ set finalInstanceField(core::int #t18) → void
+ if(this.{self::B::_#B#finalInstanceField}.==(null))
+ this.{self::B::_#B#finalInstanceField} = #t18;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has already been initialized.");
+ @#C1
+ get finalInstanceFieldWithInitializer() → core::int
+ return let final core::int? #t19 = this.{self::B::_#B#finalInstanceFieldWithInitializer} in #t19.==(null) ?{core::int} let final core::int #t20 = 0 in this.{self::B::_#B#finalInstanceFieldWithInitializer}.==(null) ?{core::int} this.{self::B::_#B#finalInstanceFieldWithInitializer} = #t20 : throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceFieldWithInitializer' has been assigned during initialization.") : #t19{core::int};
+ @#C1
+ get covariantInstanceField() → core::num
+ return let final core::num? #t21 = this.{self::B::_#B#covariantInstanceField} in #t21.==(null) ?{core::num} throw new _in::LateInitializationErrorImpl::•("Field 'covariantInstanceField' has not been initialized.") : #t21{core::num};
+ @#C1
+ set covariantInstanceField(covariant core::num #t22) → void
+ this.{self::B::_#B#covariantInstanceField} = #t22;
+ @#C1
+ static get staticField() → core::int
+ return let final core::int? #t23 = self::B::_#staticField in #t23.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'staticField' has not been initialized.") : #t23{core::int};
+ @#C1
+ static set staticField(core::int #t24) → void
+ self::B::_#staticField = #t24;
+ @#C1
+ static get finalStaticField() → core::int
+ return let final core::int? #t25 = self::B::_#finalStaticField in #t25.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has not been initialized.") : #t25{core::int};
+ @#C1
+ static set finalStaticField(core::int #t26) → void
+ if(self::B::_#finalStaticField.==(null))
+ self::B::_#finalStaticField = #t26;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has already been initialized.");
+ @#C1
+ static get finalStaticFieldWithInitializer() → core::int
+ return let final core::int? #t27 = self::B::_#finalStaticFieldWithInitializer in #t27.==(null) ?{core::int} let final core::int #t28 = 0 in self::B::_#finalStaticFieldWithInitializer.==(null) ?{core::int} self::B::_#finalStaticFieldWithInitializer = #t28 : throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticFieldWithInitializer' has been assigned during initialization.") : #t27{core::int};
+}
+extension Extension on self::A {
+ static field extensionStaticField = self::_#Extension|extensionStaticField;
+ static get extensionStaticField = get self::Extension|extensionStaticField;
+ static set extensionStaticField = set self::Extension|extensionStaticField;
+ static field finalExtensionStaticField = self::_#Extension|finalExtensionStaticField;
+ static get finalExtensionStaticField = get self::Extension|finalExtensionStaticField;
+ static set finalExtensionStaticField = set self::Extension|finalExtensionStaticField;
+ static field finalExtensionStaticFieldWithInitializer = self::_#Extension|finalExtensionStaticFieldWithInitializer;
+ static get finalExtensionStaticFieldWithInitializer = get self::Extension|finalExtensionStaticFieldWithInitializer;
+}
+static field core::int? _#topLevelField = null;
+static field core::int? _#finalTopLevelField = null;
+static field core::int? _#finalTopLevelFieldWithInitializer = null;
+static field core::int? _#Extension|extensionStaticField = null;
+static field core::int? _#Extension|finalExtensionStaticField = null;
+static field core::int? _#Extension|finalExtensionStaticFieldWithInitializer = null;
+@#C1
+static get topLevelField() → core::int
+ return let final core::int? #t29 = self::_#topLevelField in #t29.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'topLevelField' has not been initialized.") : #t29{core::int};
+@#C1
+static set topLevelField(core::int #t30) → void
+ self::_#topLevelField = #t30;
+@#C1
+static get finalTopLevelField() → core::int
+ return let final core::int? #t31 = self::_#finalTopLevelField in #t31.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelField' has not been initialized.") : #t31{core::int};
+@#C1
+static set finalTopLevelField(core::int #t32) → void
+ if(self::_#finalTopLevelField.==(null))
+ self::_#finalTopLevelField = #t32;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelField' has already been initialized.");
+@#C1
+static get finalTopLevelFieldWithInitializer() → core::int
+ return let final core::int? #t33 = self::_#finalTopLevelFieldWithInitializer in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#finalTopLevelFieldWithInitializer.==(null) ?{core::int} self::_#finalTopLevelFieldWithInitializer = #t34 : throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelFieldWithInitializer' has been assigned during initialization.") : #t33{core::int};
+@#C1
+static get Extension|extensionStaticField() → core::int
+ return let final core::int? #t35 = self::_#Extension|extensionStaticField in #t35.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'extensionStaticField' has not been initialized.") : #t35{core::int};
+@#C1
+static set Extension|extensionStaticField(core::int #t36) → void
+ self::_#Extension|extensionStaticField = #t36;
+@#C1
+static get Extension|finalExtensionStaticField() → core::int
+ return let final core::int? #t37 = self::_#Extension|finalExtensionStaticField in #t37.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticField' has not been initialized.") : #t37{core::int};
+@#C1
+static set Extension|finalExtensionStaticField(core::int #t38) → void
+ if(self::_#Extension|finalExtensionStaticField.==(null))
+ self::_#Extension|finalExtensionStaticField = #t38;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticField' has already been initialized.");
+@#C1
+static get Extension|finalExtensionStaticFieldWithInitializer() → core::int
+ return let final core::int? #t39 = self::_#Extension|finalExtensionStaticFieldWithInitializer in #t39.==(null) ?{core::int} let final core::int #t40 = 0 in self::_#Extension|finalExtensionStaticFieldWithInitializer.==(null) ?{core::int} self::_#Extension|finalExtensionStaticFieldWithInitializer = #t40 : throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticFieldWithInitializer' has been assigned during initialization.") : #t39{core::int};
+static method main() → dynamic {}
+
+constants {
+ #C1 = self::Annotation {}
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.textual_outline.expect
new file mode 100644
index 0000000..a484907
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.textual_outline.expect
@@ -0,0 +1,61 @@
+class Annotation {
+ const Annotation();
+}
+@Annotation()
+late int ;
+topLevelField;
+@Annotation()
+late ;
+final int finalTopLevelField;
+@Annotation()
+late ;
+final int finalTopLevelFieldWithInitializer = 0;
+class A {
+ @Annotation()
+ late int ;
+ instanceField;
+ @Annotation()
+ late ;
+ final int finalInstanceField;
+ @Annotation()
+ late ;
+ final int finalInstanceFieldWithInitializer = 0;
+ @Annotation()
+ covariant late num ;
+ covariantInstanceField;
+ @Annotation()
+ static late int ;
+ staticField;
+ @Annotation()
+ static late ;
+ final int finalStaticField;
+ @Annotation()
+ static late ;
+ final int finalStaticFieldWithInitializer = 0;
+}
+mixin B {
+ @Annotation()
+ late int ;
+ instanceField;
+ @Annotation()
+ late ;
+ final int finalInstanceField;
+ @Annotation()
+ late ;
+ final int finalInstanceFieldWithInitializer = 0;
+ @Annotation()
+ covariant late num ;
+ covariantInstanceField;
+ @Annotation()
+ static late int ;
+ staticField;
+ @Annotation()
+ static late ;
+ final int finalStaticField;
+ @Annotation()
+ static late ;
+ final int finalStaticFieldWithInitializer = 0;
+}
+extension Extension ;
+on A (){ }
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.expect
new file mode 100644
index 0000000..44d325d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.expect
@@ -0,0 +1,172 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Annotation extends core::Object /*hasConstConstructor*/ {
+ const constructor •() → self::Annotation
+ : super core::Object::•()
+ ;
+}
+class A extends core::Object {
+ field core::int? _#A#instanceField = null;
+ field core::int? _#A#finalInstanceField = null;
+ field core::int? _#A#finalInstanceFieldWithInitializer = null;
+ field core::num? _#A#covariantInstanceField = null;
+ static field core::int? _#staticField = null;
+ static field core::int? _#finalStaticField = null;
+ static field core::int? _#finalStaticFieldWithInitializer = null;
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ @#C1
+ get instanceField() → core::int
+ return let final core::int? #t1 = this.{self::A::_#A#instanceField} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'instanceField' has not been initialized.") : #t1{core::int};
+ @#C1
+ set instanceField(core::int #t2) → void
+ this.{self::A::_#A#instanceField} = #t2;
+ @#C1
+ get finalInstanceField() → core::int
+ return let final core::int? #t3 = this.{self::A::_#A#finalInstanceField} in #t3.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has not been initialized.") : #t3{core::int};
+ @#C1
+ set finalInstanceField(core::int #t4) → void
+ if(this.{self::A::_#A#finalInstanceField}.==(null))
+ this.{self::A::_#A#finalInstanceField} = #t4;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has already been initialized.");
+ @#C1
+ get finalInstanceFieldWithInitializer() → core::int
+ return let final core::int? #t5 = this.{self::A::_#A#finalInstanceFieldWithInitializer} in #t5.==(null) ?{core::int} let final core::int #t6 = 0 in this.{self::A::_#A#finalInstanceFieldWithInitializer}.==(null) ?{core::int} this.{self::A::_#A#finalInstanceFieldWithInitializer} = #t6 : throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceFieldWithInitializer' has been assigned during initialization.") : #t5{core::int};
+ @#C1
+ get covariantInstanceField() → core::num
+ return let final core::num? #t7 = this.{self::A::_#A#covariantInstanceField} in #t7.==(null) ?{core::num} throw new _in::LateInitializationErrorImpl::•("Field 'covariantInstanceField' has not been initialized.") : #t7{core::num};
+ @#C1
+ set covariantInstanceField(covariant core::num #t8) → void
+ this.{self::A::_#A#covariantInstanceField} = #t8;
+ @#C1
+ static get staticField() → core::int
+ return let final core::int? #t9 = self::A::_#staticField in #t9.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'staticField' has not been initialized.") : #t9{core::int};
+ @#C1
+ static set staticField(core::int #t10) → void
+ self::A::_#staticField = #t10;
+ @#C1
+ static get finalStaticField() → core::int
+ return let final core::int? #t11 = self::A::_#finalStaticField in #t11.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has not been initialized.") : #t11{core::int};
+ @#C1
+ static set finalStaticField(core::int #t12) → void
+ if(self::A::_#finalStaticField.==(null))
+ self::A::_#finalStaticField = #t12;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has already been initialized.");
+ @#C1
+ static get finalStaticFieldWithInitializer() → core::int
+ return let final core::int? #t13 = self::A::_#finalStaticFieldWithInitializer in #t13.==(null) ?{core::int} let final core::int #t14 = 0 in self::A::_#finalStaticFieldWithInitializer.==(null) ?{core::int} self::A::_#finalStaticFieldWithInitializer = #t14 : throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticFieldWithInitializer' has been assigned during initialization.") : #t13{core::int};
+}
+abstract class B extends core::Object /*isMixinDeclaration*/ {
+ field core::int? _#B#instanceField = null;
+ field core::int? _#B#finalInstanceField = null;
+ field core::int? _#B#finalInstanceFieldWithInitializer = null;
+ field core::num? _#B#covariantInstanceField = null;
+ static field core::int? _#staticField = null;
+ static field core::int? _#finalStaticField = null;
+ static field core::int? _#finalStaticFieldWithInitializer = null;
+ @#C1
+ get instanceField() → core::int
+ return let final core::int? #t15 = this.{self::B::_#B#instanceField} in #t15.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'instanceField' has not been initialized.") : #t15{core::int};
+ @#C1
+ set instanceField(core::int #t16) → void
+ this.{self::B::_#B#instanceField} = #t16;
+ @#C1
+ get finalInstanceField() → core::int
+ return let final core::int? #t17 = this.{self::B::_#B#finalInstanceField} in #t17.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has not been initialized.") : #t17{core::int};
+ @#C1
+ set finalInstanceField(core::int #t18) → void
+ if(this.{self::B::_#B#finalInstanceField}.==(null))
+ this.{self::B::_#B#finalInstanceField} = #t18;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has already been initialized.");
+ @#C1
+ get finalInstanceFieldWithInitializer() → core::int
+ return let final core::int? #t19 = this.{self::B::_#B#finalInstanceFieldWithInitializer} in #t19.==(null) ?{core::int} let final core::int #t20 = 0 in this.{self::B::_#B#finalInstanceFieldWithInitializer}.==(null) ?{core::int} this.{self::B::_#B#finalInstanceFieldWithInitializer} = #t20 : throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceFieldWithInitializer' has been assigned during initialization.") : #t19{core::int};
+ @#C1
+ get covariantInstanceField() → core::num
+ return let final core::num? #t21 = this.{self::B::_#B#covariantInstanceField} in #t21.==(null) ?{core::num} throw new _in::LateInitializationErrorImpl::•("Field 'covariantInstanceField' has not been initialized.") : #t21{core::num};
+ @#C1
+ set covariantInstanceField(covariant core::num #t22) → void
+ this.{self::B::_#B#covariantInstanceField} = #t22;
+ @#C1
+ static get staticField() → core::int
+ return let final core::int? #t23 = self::B::_#staticField in #t23.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'staticField' has not been initialized.") : #t23{core::int};
+ @#C1
+ static set staticField(core::int #t24) → void
+ self::B::_#staticField = #t24;
+ @#C1
+ static get finalStaticField() → core::int
+ return let final core::int? #t25 = self::B::_#finalStaticField in #t25.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has not been initialized.") : #t25{core::int};
+ @#C1
+ static set finalStaticField(core::int #t26) → void
+ if(self::B::_#finalStaticField.==(null))
+ self::B::_#finalStaticField = #t26;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has already been initialized.");
+ @#C1
+ static get finalStaticFieldWithInitializer() → core::int
+ return let final core::int? #t27 = self::B::_#finalStaticFieldWithInitializer in #t27.==(null) ?{core::int} let final core::int #t28 = 0 in self::B::_#finalStaticFieldWithInitializer.==(null) ?{core::int} self::B::_#finalStaticFieldWithInitializer = #t28 : throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticFieldWithInitializer' has been assigned during initialization.") : #t27{core::int};
+}
+extension Extension on self::A {
+ static field extensionStaticField = self::_#Extension|extensionStaticField;
+ static get extensionStaticField = get self::Extension|extensionStaticField;
+ static set extensionStaticField = set self::Extension|extensionStaticField;
+ static field finalExtensionStaticField = self::_#Extension|finalExtensionStaticField;
+ static get finalExtensionStaticField = get self::Extension|finalExtensionStaticField;
+ static set finalExtensionStaticField = set self::Extension|finalExtensionStaticField;
+ static field finalExtensionStaticFieldWithInitializer = self::_#Extension|finalExtensionStaticFieldWithInitializer;
+ static get finalExtensionStaticFieldWithInitializer = get self::Extension|finalExtensionStaticFieldWithInitializer;
+}
+static field core::int? _#topLevelField = null;
+static field core::int? _#finalTopLevelField = null;
+static field core::int? _#finalTopLevelFieldWithInitializer = null;
+static field core::int? _#Extension|extensionStaticField = null;
+static field core::int? _#Extension|finalExtensionStaticField = null;
+static field core::int? _#Extension|finalExtensionStaticFieldWithInitializer = null;
+@#C1
+static get topLevelField() → core::int
+ return let final core::int? #t29 = self::_#topLevelField in #t29.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'topLevelField' has not been initialized.") : #t29{core::int};
+@#C1
+static set topLevelField(core::int #t30) → void
+ self::_#topLevelField = #t30;
+@#C1
+static get finalTopLevelField() → core::int
+ return let final core::int? #t31 = self::_#finalTopLevelField in #t31.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelField' has not been initialized.") : #t31{core::int};
+@#C1
+static set finalTopLevelField(core::int #t32) → void
+ if(self::_#finalTopLevelField.==(null))
+ self::_#finalTopLevelField = #t32;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelField' has already been initialized.");
+@#C1
+static get finalTopLevelFieldWithInitializer() → core::int
+ return let final core::int? #t33 = self::_#finalTopLevelFieldWithInitializer in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#finalTopLevelFieldWithInitializer.==(null) ?{core::int} self::_#finalTopLevelFieldWithInitializer = #t34 : throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelFieldWithInitializer' has been assigned during initialization.") : #t33{core::int};
+@#C1
+static get Extension|extensionStaticField() → core::int
+ return let final core::int? #t35 = self::_#Extension|extensionStaticField in #t35.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'extensionStaticField' has not been initialized.") : #t35{core::int};
+@#C1
+static set Extension|extensionStaticField(core::int #t36) → void
+ self::_#Extension|extensionStaticField = #t36;
+@#C1
+static get Extension|finalExtensionStaticField() → core::int
+ return let final core::int? #t37 = self::_#Extension|finalExtensionStaticField in #t37.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticField' has not been initialized.") : #t37{core::int};
+@#C1
+static set Extension|finalExtensionStaticField(core::int #t38) → void
+ if(self::_#Extension|finalExtensionStaticField.==(null))
+ self::_#Extension|finalExtensionStaticField = #t38;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticField' has already been initialized.");
+@#C1
+static get Extension|finalExtensionStaticFieldWithInitializer() → core::int
+ return let final core::int? #t39 = self::_#Extension|finalExtensionStaticFieldWithInitializer in #t39.==(null) ?{core::int} let final core::int #t40 = 0 in self::_#Extension|finalExtensionStaticFieldWithInitializer.==(null) ?{core::int} self::_#Extension|finalExtensionStaticFieldWithInitializer = #t40 : throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticFieldWithInitializer' has been assigned during initialization.") : #t39{core::int};
+static method main() → dynamic {}
+
+constants {
+ #C1 = self::Annotation {}
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.transformed.expect
new file mode 100644
index 0000000..44d325d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.weak.transformed.expect
@@ -0,0 +1,172 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+class Annotation extends core::Object /*hasConstConstructor*/ {
+ const constructor •() → self::Annotation
+ : super core::Object::•()
+ ;
+}
+class A extends core::Object {
+ field core::int? _#A#instanceField = null;
+ field core::int? _#A#finalInstanceField = null;
+ field core::int? _#A#finalInstanceFieldWithInitializer = null;
+ field core::num? _#A#covariantInstanceField = null;
+ static field core::int? _#staticField = null;
+ static field core::int? _#finalStaticField = null;
+ static field core::int? _#finalStaticFieldWithInitializer = null;
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ @#C1
+ get instanceField() → core::int
+ return let final core::int? #t1 = this.{self::A::_#A#instanceField} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'instanceField' has not been initialized.") : #t1{core::int};
+ @#C1
+ set instanceField(core::int #t2) → void
+ this.{self::A::_#A#instanceField} = #t2;
+ @#C1
+ get finalInstanceField() → core::int
+ return let final core::int? #t3 = this.{self::A::_#A#finalInstanceField} in #t3.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has not been initialized.") : #t3{core::int};
+ @#C1
+ set finalInstanceField(core::int #t4) → void
+ if(this.{self::A::_#A#finalInstanceField}.==(null))
+ this.{self::A::_#A#finalInstanceField} = #t4;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has already been initialized.");
+ @#C1
+ get finalInstanceFieldWithInitializer() → core::int
+ return let final core::int? #t5 = this.{self::A::_#A#finalInstanceFieldWithInitializer} in #t5.==(null) ?{core::int} let final core::int #t6 = 0 in this.{self::A::_#A#finalInstanceFieldWithInitializer}.==(null) ?{core::int} this.{self::A::_#A#finalInstanceFieldWithInitializer} = #t6 : throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceFieldWithInitializer' has been assigned during initialization.") : #t5{core::int};
+ @#C1
+ get covariantInstanceField() → core::num
+ return let final core::num? #t7 = this.{self::A::_#A#covariantInstanceField} in #t7.==(null) ?{core::num} throw new _in::LateInitializationErrorImpl::•("Field 'covariantInstanceField' has not been initialized.") : #t7{core::num};
+ @#C1
+ set covariantInstanceField(covariant core::num #t8) → void
+ this.{self::A::_#A#covariantInstanceField} = #t8;
+ @#C1
+ static get staticField() → core::int
+ return let final core::int? #t9 = self::A::_#staticField in #t9.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'staticField' has not been initialized.") : #t9{core::int};
+ @#C1
+ static set staticField(core::int #t10) → void
+ self::A::_#staticField = #t10;
+ @#C1
+ static get finalStaticField() → core::int
+ return let final core::int? #t11 = self::A::_#finalStaticField in #t11.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has not been initialized.") : #t11{core::int};
+ @#C1
+ static set finalStaticField(core::int #t12) → void
+ if(self::A::_#finalStaticField.==(null))
+ self::A::_#finalStaticField = #t12;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has already been initialized.");
+ @#C1
+ static get finalStaticFieldWithInitializer() → core::int
+ return let final core::int? #t13 = self::A::_#finalStaticFieldWithInitializer in #t13.==(null) ?{core::int} let final core::int #t14 = 0 in self::A::_#finalStaticFieldWithInitializer.==(null) ?{core::int} self::A::_#finalStaticFieldWithInitializer = #t14 : throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticFieldWithInitializer' has been assigned during initialization.") : #t13{core::int};
+}
+abstract class B extends core::Object /*isMixinDeclaration*/ {
+ field core::int? _#B#instanceField = null;
+ field core::int? _#B#finalInstanceField = null;
+ field core::int? _#B#finalInstanceFieldWithInitializer = null;
+ field core::num? _#B#covariantInstanceField = null;
+ static field core::int? _#staticField = null;
+ static field core::int? _#finalStaticField = null;
+ static field core::int? _#finalStaticFieldWithInitializer = null;
+ @#C1
+ get instanceField() → core::int
+ return let final core::int? #t15 = this.{self::B::_#B#instanceField} in #t15.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'instanceField' has not been initialized.") : #t15{core::int};
+ @#C1
+ set instanceField(core::int #t16) → void
+ this.{self::B::_#B#instanceField} = #t16;
+ @#C1
+ get finalInstanceField() → core::int
+ return let final core::int? #t17 = this.{self::B::_#B#finalInstanceField} in #t17.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has not been initialized.") : #t17{core::int};
+ @#C1
+ set finalInstanceField(core::int #t18) → void
+ if(this.{self::B::_#B#finalInstanceField}.==(null))
+ this.{self::B::_#B#finalInstanceField} = #t18;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceField' has already been initialized.");
+ @#C1
+ get finalInstanceFieldWithInitializer() → core::int
+ return let final core::int? #t19 = this.{self::B::_#B#finalInstanceFieldWithInitializer} in #t19.==(null) ?{core::int} let final core::int #t20 = 0 in this.{self::B::_#B#finalInstanceFieldWithInitializer}.==(null) ?{core::int} this.{self::B::_#B#finalInstanceFieldWithInitializer} = #t20 : throw new _in::LateInitializationErrorImpl::•("Field 'finalInstanceFieldWithInitializer' has been assigned during initialization.") : #t19{core::int};
+ @#C1
+ get covariantInstanceField() → core::num
+ return let final core::num? #t21 = this.{self::B::_#B#covariantInstanceField} in #t21.==(null) ?{core::num} throw new _in::LateInitializationErrorImpl::•("Field 'covariantInstanceField' has not been initialized.") : #t21{core::num};
+ @#C1
+ set covariantInstanceField(covariant core::num #t22) → void
+ this.{self::B::_#B#covariantInstanceField} = #t22;
+ @#C1
+ static get staticField() → core::int
+ return let final core::int? #t23 = self::B::_#staticField in #t23.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'staticField' has not been initialized.") : #t23{core::int};
+ @#C1
+ static set staticField(core::int #t24) → void
+ self::B::_#staticField = #t24;
+ @#C1
+ static get finalStaticField() → core::int
+ return let final core::int? #t25 = self::B::_#finalStaticField in #t25.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has not been initialized.") : #t25{core::int};
+ @#C1
+ static set finalStaticField(core::int #t26) → void
+ if(self::B::_#finalStaticField.==(null))
+ self::B::_#finalStaticField = #t26;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticField' has already been initialized.");
+ @#C1
+ static get finalStaticFieldWithInitializer() → core::int
+ return let final core::int? #t27 = self::B::_#finalStaticFieldWithInitializer in #t27.==(null) ?{core::int} let final core::int #t28 = 0 in self::B::_#finalStaticFieldWithInitializer.==(null) ?{core::int} self::B::_#finalStaticFieldWithInitializer = #t28 : throw new _in::LateInitializationErrorImpl::•("Field 'finalStaticFieldWithInitializer' has been assigned during initialization.") : #t27{core::int};
+}
+extension Extension on self::A {
+ static field extensionStaticField = self::_#Extension|extensionStaticField;
+ static get extensionStaticField = get self::Extension|extensionStaticField;
+ static set extensionStaticField = set self::Extension|extensionStaticField;
+ static field finalExtensionStaticField = self::_#Extension|finalExtensionStaticField;
+ static get finalExtensionStaticField = get self::Extension|finalExtensionStaticField;
+ static set finalExtensionStaticField = set self::Extension|finalExtensionStaticField;
+ static field finalExtensionStaticFieldWithInitializer = self::_#Extension|finalExtensionStaticFieldWithInitializer;
+ static get finalExtensionStaticFieldWithInitializer = get self::Extension|finalExtensionStaticFieldWithInitializer;
+}
+static field core::int? _#topLevelField = null;
+static field core::int? _#finalTopLevelField = null;
+static field core::int? _#finalTopLevelFieldWithInitializer = null;
+static field core::int? _#Extension|extensionStaticField = null;
+static field core::int? _#Extension|finalExtensionStaticField = null;
+static field core::int? _#Extension|finalExtensionStaticFieldWithInitializer = null;
+@#C1
+static get topLevelField() → core::int
+ return let final core::int? #t29 = self::_#topLevelField in #t29.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'topLevelField' has not been initialized.") : #t29{core::int};
+@#C1
+static set topLevelField(core::int #t30) → void
+ self::_#topLevelField = #t30;
+@#C1
+static get finalTopLevelField() → core::int
+ return let final core::int? #t31 = self::_#finalTopLevelField in #t31.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelField' has not been initialized.") : #t31{core::int};
+@#C1
+static set finalTopLevelField(core::int #t32) → void
+ if(self::_#finalTopLevelField.==(null))
+ self::_#finalTopLevelField = #t32;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelField' has already been initialized.");
+@#C1
+static get finalTopLevelFieldWithInitializer() → core::int
+ return let final core::int? #t33 = self::_#finalTopLevelFieldWithInitializer in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#finalTopLevelFieldWithInitializer.==(null) ?{core::int} self::_#finalTopLevelFieldWithInitializer = #t34 : throw new _in::LateInitializationErrorImpl::•("Field 'finalTopLevelFieldWithInitializer' has been assigned during initialization.") : #t33{core::int};
+@#C1
+static get Extension|extensionStaticField() → core::int
+ return let final core::int? #t35 = self::_#Extension|extensionStaticField in #t35.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'extensionStaticField' has not been initialized.") : #t35{core::int};
+@#C1
+static set Extension|extensionStaticField(core::int #t36) → void
+ self::_#Extension|extensionStaticField = #t36;
+@#C1
+static get Extension|finalExtensionStaticField() → core::int
+ return let final core::int? #t37 = self::_#Extension|finalExtensionStaticField in #t37.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticField' has not been initialized.") : #t37{core::int};
+@#C1
+static set Extension|finalExtensionStaticField(core::int #t38) → void
+ if(self::_#Extension|finalExtensionStaticField.==(null))
+ self::_#Extension|finalExtensionStaticField = #t38;
+ else
+ throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticField' has already been initialized.");
+@#C1
+static get Extension|finalExtensionStaticFieldWithInitializer() → core::int
+ return let final core::int? #t39 = self::_#Extension|finalExtensionStaticFieldWithInitializer in #t39.==(null) ?{core::int} let final core::int #t40 = 0 in self::_#Extension|finalExtensionStaticFieldWithInitializer.==(null) ?{core::int} self::_#Extension|finalExtensionStaticFieldWithInitializer = #t40 : throw new _in::LateInitializationErrorImpl::•("Field 'finalExtensionStaticFieldWithInitializer' has been assigned during initialization.") : #t39{core::int};
+static method main() → dynamic {}
+
+constants {
+ #C1 = self::Annotation {}
+}
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
index 519d73f..cd697a5 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
@@ -207,7 +207,7 @@
function #s1#get() → core::String
return let final core::String? #t11 = s1 in #t11.==(null) ?{core::String} s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
late String s1 = await hest(); // Error.
- ^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String : #t11{core::String};
+ ^^^^^" : #t11{core::String};
function #s1#set(core::String #t12) → dynamic
return s1 = #t12;
core::String? s2;
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
index 519d73f..cd697a5 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
@@ -207,7 +207,7 @@
function #s1#get() → core::String
return let final core::String? #t11 = s1 in #t11.==(null) ?{core::String} s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
late String s1 = await hest(); // Error.
- ^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String : #t11{core::String};
+ ^^^^^" : #t11{core::String};
function #s1#set(core::String #t12) → dynamic
return s1 = #t12;
core::String? s2;
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
index 9c3d453..25a4dd1 100644
--- a/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.strong.transformed.expect
@@ -994,7 +994,7 @@
dynamicVar = xPotentiallyNullArg;
dynamicVar = yNonNullArg;
dynamicVar = yPotentiallyNullArg;
- core::Object objectVar = dynamicArg as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object;
+ core::Object objectVar = let dynamic #t1 = dynamicArg in #t1.==(null) ?{core::Object} #t1 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object : #t1{core::Object};
objectVar = objectArg;
objectVar = numArg;
objectVar = intArg;
@@ -1014,10 +1014,10 @@
core::Function functionVar = dynamicArg as{TypeError,ForDynamic,ForNonNullableByDefault} core::Function;
functionVar = functionArg;
functionVar = toVoidArg;
- functionVar = let final self::Tearoffable #t1 = tearoffableArg in #t1.==(null) ?{() → void} null : #t1.{self::Tearoffable::call};
+ functionVar = let final self::Tearoffable #t2 = tearoffableArg in #t2.==(null) ?{() → void} null : #t2.{self::Tearoffable::call};
() → void toVoidVar = dynamicArg as{TypeError,ForDynamic,ForNonNullableByDefault} () → void;
toVoidVar = toVoidArg;
- toVoidVar = let final self::Tearoffable #t2 = tearoffableArg in #t2.==(null) ?{() → void} null : #t2.{self::Tearoffable::call};
+ toVoidVar = let final self::Tearoffable #t3 = tearoffableArg in #t3.==(null) ?{() → void} null : #t3.{self::Tearoffable::call};
self::Tearoffable tearoffableVar = dynamicArg as{TypeError,ForDynamic,ForNonNullableByDefault} self::Tearoffable;
tearoffableVar = tearoffableArg;
self::ok::XnonNull xNonNullVar = dynamicArg as{TypeError,ForDynamic,ForNonNullableByDefault} self::ok::XnonNull;
@@ -1032,758 +1032,758 @@
yPotentiallyNullVar = yPotentiallyNullArg;
}
static method error<XnonNull extends core::Object = core::Object, YnonNull extends self::error::XnonNull = core::Object, XpotentiallyNull extends core::Object? = core::Object?, YpotentiallyNull extends self::error::XpotentiallyNull% = core::Object?>(core::Object objectArg, core::Object? objectNullableArg, core::num numArg, core::num? numNullableArg, core::int intArg, core::int? intNullableArg, core::double doubleArg, core::double? doubleNullableArg, core::Function functionArg, core::Function? functionNullableArg, () → void toVoidArg, () →? void toVoidNullableArg, self::Tearoffable tearoffableArg, self::Tearoffable? tearoffableNullableArg, self::error::XnonNull xNonNullArg, self::error::XnonNull? xNonNullNullableArg, self::error::XpotentiallyNull% xPotentiallyNullArg, self::error::XpotentiallyNull? xPotentiallyNullNullableArg, self::error::YnonNull yNonNullArg, self::error::YnonNull? yNonNullNullableArg, self::error::YpotentiallyNull% yPotentiallyNullArg, self::error::YpotentiallyNull? yPotentiallyNullNullableArg) → dynamic {
- core::Object objectVar = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:114:22: Error: A value of type 'Object?' can't be assigned to a variable of type 'Object'.
+ core::Object objectVar = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:114:22: Error: A value of type 'Object?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
Object objectVar = objectNullableArg;
- ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:115:15: Error: A value of type 'num?' can't be assigned to a variable of type 'Object'.
+ ^" in let core::Object? #t5 = objectNullableArg in #t5.==(null) ?{core::Object} #t5 as{TypeError,ForNonNullableByDefault} core::Object : #t5{core::Object};
+ objectVar = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:115:15: Error: A value of type 'num?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = numNullableArg;
- ^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:116:15: Error: A value of type 'int?' can't be assigned to a variable of type 'Object'.
+ ^" in let core::num? #t7 = numNullableArg in #t7.==(null) ?{core::Object} #t7 as{TypeError,ForNonNullableByDefault} core::Object : #t7{core::Object};
+ objectVar = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:116:15: Error: A value of type 'int?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = intNullableArg;
- ^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:117:15: Error: A value of type 'double?' can't be assigned to a variable of type 'Object'.
+ ^" in let core::int? #t9 = intNullableArg in #t9.==(null) ?{core::Object} #t9 as{TypeError,ForNonNullableByDefault} core::Object : #t9{core::Object};
+ objectVar = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:117:15: Error: A value of type 'double?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = doubleNullableArg;
- ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:118:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'Object'.
+ ^" in let core::double? #t11 = doubleNullableArg in #t11.==(null) ?{core::Object} #t11 as{TypeError,ForNonNullableByDefault} core::Object : #t11{core::Object};
+ objectVar = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:118:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'Object'.
- 'Function' is from 'dart:core'.
- 'Object' is from 'dart:core'.
objectVar = functionNullableArg;
- ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:119:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Object'.
+ ^" in let core::Function? #t13 = functionNullableArg in #t13.==(null) ?{core::Object} #t13 as{TypeError,ForNonNullableByDefault} core::Object : #t13{core::Object};
+ objectVar = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:119:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = toVoidNullableArg;
- ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:120:15: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Object'.
+ ^" in let () →? void #t15 = toVoidNullableArg in #t15.==(null) ?{core::Object} #t15 as{TypeError,ForNonNullableByDefault} core::Object : #t15{core::Object};
+ objectVar = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:120:15: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Object'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
- 'Object' is from 'dart:core'.
objectVar = tearoffableNullableArg;
- ^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:121:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Object'.
+ ^" in let self::Tearoffable? #t17 = tearoffableNullableArg in #t17.==(null) ?{core::Object} #t17 as{TypeError,ForNonNullableByDefault} core::Object : #t17{core::Object};
+ objectVar = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:121:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = xNonNullNullableArg;
- ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:122:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Object'.
+ ^" in let self::error::XnonNull? #t19 = xNonNullNullableArg in #t19.==(null) ?{core::Object} #t19 as{TypeError,ForNonNullableByDefault} core::Object : #t19{core::Object};
+ objectVar = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:122:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = xPotentiallyNullArg;
- ^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:123:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Object'.
+ ^" in let self::error::XpotentiallyNull% #t21 = xPotentiallyNullArg in #t21.==(null) ?{core::Object} #t21 as{TypeError,ForNonNullableByDefault} core::Object : #t21{core::Object};
+ objectVar = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:123:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = xPotentiallyNullNullableArg;
- ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:124:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Object'.
+ ^" in let self::error::XpotentiallyNull? #t23 = xPotentiallyNullNullableArg in #t23.==(null) ?{core::Object} #t23 as{TypeError,ForNonNullableByDefault} core::Object : #t23{core::Object};
+ objectVar = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:124:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = yNonNullNullableArg;
- ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:125:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Object'.
+ ^" in let self::error::YnonNull? #t25 = yNonNullNullableArg in #t25.==(null) ?{core::Object} #t25 as{TypeError,ForNonNullableByDefault} core::Object : #t25{core::Object};
+ objectVar = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:125:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = yPotentiallyNullArg;
- ^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::Object;
- objectVar = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:126:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Object'.
+ ^" in let self::error::YpotentiallyNull% #t27 = yPotentiallyNullArg in #t27.==(null) ?{core::Object} #t27 as{TypeError,ForNonNullableByDefault} core::Object : #t27{core::Object};
+ objectVar = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:126:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = yPotentiallyNullNullableArg;
- ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
- core::num numVar = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:128:16: Error: A value of type 'Object' can't be assigned to a variable of type 'num'.
+ ^" in let self::error::YpotentiallyNull? #t29 = yPotentiallyNullNullableArg in #t29.==(null) ?{core::Object} #t29 as{TypeError,ForNonNullableByDefault} core::Object : #t29{core::Object};
+ core::num numVar = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:128:16: Error: A value of type 'Object' can't be assigned to a variable of type 'num'.
- 'Object' is from 'dart:core'.
num numVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:129:12: Error: A value of type 'Object?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:129:12: Error: A value of type 'Object?' can't be assigned to a variable of type 'num'.
- 'Object' is from 'dart:core'.
numVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:130:12: Error: A value of type 'num?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:130:12: Error: A value of type 'num?' can't be assigned to a variable of type 'num'.
numVar = numNullableArg;
- ^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:131:12: Error: A value of type 'int?' can't be assigned to a variable of type 'num'.
+ ^" in let core::num? #t33 = numNullableArg in #t33.==(null) ?{core::num} #t33 as{TypeError,ForNonNullableByDefault} core::num : #t33{core::num};
+ numVar = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:131:12: Error: A value of type 'int?' can't be assigned to a variable of type 'num'.
numVar = intNullableArg;
- ^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:132:12: Error: A value of type 'double?' can't be assigned to a variable of type 'num'.
+ ^" in let core::int? #t35 = intNullableArg in #t35.==(null) ?{core::num} #t35 as{TypeError,ForNonNullableByDefault} core::num : #t35{core::num};
+ numVar = let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:132:12: Error: A value of type 'double?' can't be assigned to a variable of type 'num'.
numVar = doubleNullableArg;
- ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:133:12: Error: A value of type 'Function' can't be assigned to a variable of type 'num'.
+ ^" in let core::double? #t37 = doubleNullableArg in #t37.==(null) ?{core::num} #t37 as{TypeError,ForNonNullableByDefault} core::num : #t37{core::num};
+ numVar = let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:133:12: Error: A value of type 'Function' can't be assigned to a variable of type 'num'.
- 'Function' is from 'dart:core'.
numVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:134:12: Error: A value of type 'Function?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:134:12: Error: A value of type 'Function?' can't be assigned to a variable of type 'num'.
- 'Function' is from 'dart:core'.
numVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:135:12: Error: A value of type 'void Function()' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:135:12: Error: A value of type 'void Function()' can't be assigned to a variable of type 'num'.
numVar = toVoidArg;
^" in toVoidArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:136:12: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:136:12: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'num'.
numVar = toVoidNullableArg;
^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:137:12: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:137:12: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'num'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
numVar = tearoffableArg;
^" in tearoffableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:138:12: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:138:12: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'num'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
numVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:139:12: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:139:12: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'num'.
numVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:140:12: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:140:12: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'num'.
numVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t29 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:141:12: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:141:12: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'num'.
numVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:142:12: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:142:12: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'num'.
numVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:143:12: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t48 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:143:12: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'num'.
numVar = yNonNullArg;
^" in yNonNullArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:144:12: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t49 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:144:12: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'num'.
numVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:145:12: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:145:12: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'num'.
numVar = yPotentiallyNullArg;
^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::num;
- numVar = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:146:12: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'num'.
+ numVar = let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:146:12: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'num'.
numVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::num;
- core::int intVar = let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:148:16: Error: A value of type 'Object' can't be assigned to a variable of type 'int'.
+ core::int intVar = let final<BottomType> #t52 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:148:16: Error: A value of type 'Object' can't be assigned to a variable of type 'int'.
- 'Object' is from 'dart:core'.
int intVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:149:12: Error: A value of type 'Object?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t53 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:149:12: Error: A value of type 'Object?' can't be assigned to a variable of type 'int'.
- 'Object' is from 'dart:core'.
intVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t37 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:150:12: Error: A value of type 'num' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t54 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:150:12: Error: A value of type 'num' can't be assigned to a variable of type 'int'.
intVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t38 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:151:12: Error: A value of type 'num?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t55 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:151:12: Error: A value of type 'num?' can't be assigned to a variable of type 'int'.
intVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:152:12: Error: A value of type 'int?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t56 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:152:12: Error: A value of type 'int?' can't be assigned to a variable of type 'int'.
intVar = intNullableArg;
- ^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:153:12: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ ^" in let core::int? #t57 = intNullableArg in #t57.==(null) ?{core::int} #t57 as{TypeError,ForNonNullableByDefault} core::int : #t57{core::int};
+ intVar = let final<BottomType> #t58 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:153:12: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
intVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:154:12: Error: A value of type 'double?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t59 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:154:12: Error: A value of type 'double?' can't be assigned to a variable of type 'int'.
intVar = doubleNullableArg;
^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:155:12: Error: A value of type 'Function' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t60 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:155:12: Error: A value of type 'Function' can't be assigned to a variable of type 'int'.
- 'Function' is from 'dart:core'.
intVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:156:12: Error: A value of type 'Function?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t61 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:156:12: Error: A value of type 'Function?' can't be assigned to a variable of type 'int'.
- 'Function' is from 'dart:core'.
intVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:157:12: Error: A value of type 'void Function()' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t62 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:157:12: Error: A value of type 'void Function()' can't be assigned to a variable of type 'int'.
intVar = toVoidArg;
^" in toVoidArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t45 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:158:12: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t63 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:158:12: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'int'.
intVar = toVoidNullableArg;
^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t46 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:159:12: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:159:12: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'int'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
intVar = tearoffableArg;
^" in tearoffableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:160:12: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t65 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:160:12: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'int'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
intVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t48 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:161:12: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t66 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:161:12: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'int'.
intVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t49 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:162:12: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t67 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:162:12: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'int'.
intVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:163:12: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t68 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:163:12: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'int'.
intVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t51 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:164:12: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t69 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:164:12: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'int'.
intVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t52 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:165:12: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t70 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:165:12: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'int'.
intVar = yNonNullArg;
^" in yNonNullArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t53 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:166:12: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t71 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:166:12: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'int'.
intVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t54 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:167:12: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t72 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:167:12: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'int'.
intVar = yPotentiallyNullArg;
^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::int;
- intVar = let final<BottomType> #t55 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:168:12: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'int'.
+ intVar = let final<BottomType> #t73 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:168:12: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'int'.
intVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::int;
- core::double doubleVar = let final<BottomType> #t56 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:170:22: Error: A value of type 'Object' can't be assigned to a variable of type 'double'.
+ core::double doubleVar = let final<BottomType> #t74 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:170:22: Error: A value of type 'Object' can't be assigned to a variable of type 'double'.
- 'Object' is from 'dart:core'.
double doubleVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:171:15: Error: A value of type 'Object?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t75 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:171:15: Error: A value of type 'Object?' can't be assigned to a variable of type 'double'.
- 'Object' is from 'dart:core'.
doubleVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t58 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:172:15: Error: A value of type 'num' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t76 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:172:15: Error: A value of type 'num' can't be assigned to a variable of type 'double'.
doubleVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t59 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:173:15: Error: A value of type 'num?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t77 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:173:15: Error: A value of type 'num?' can't be assigned to a variable of type 'double'.
doubleVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t60 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:174:15: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t78 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:174:15: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
doubleVar = intArg;
^" in intArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t61 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:175:15: Error: A value of type 'int?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:175:15: Error: A value of type 'int?' can't be assigned to a variable of type 'double'.
doubleVar = intNullableArg;
^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t62 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:176:15: Error: A value of type 'double?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t80 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:176:15: Error: A value of type 'double?' can't be assigned to a variable of type 'double'.
doubleVar = doubleNullableArg;
- ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t63 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:177:15: Error: A value of type 'Function' can't be assigned to a variable of type 'double'.
+ ^" in let core::double? #t81 = doubleNullableArg in #t81.==(null) ?{core::double} #t81 as{TypeError,ForNonNullableByDefault} core::double : #t81{core::double};
+ doubleVar = let final<BottomType> #t82 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:177:15: Error: A value of type 'Function' can't be assigned to a variable of type 'double'.
- 'Function' is from 'dart:core'.
doubleVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:178:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t83 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:178:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'double'.
- 'Function' is from 'dart:core'.
doubleVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t65 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:179:15: Error: A value of type 'void Function()' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t84 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:179:15: Error: A value of type 'void Function()' can't be assigned to a variable of type 'double'.
doubleVar = toVoidArg;
^" in toVoidArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t66 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:180:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t85 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:180:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'double'.
doubleVar = toVoidNullableArg;
^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t67 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:181:15: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:181:15: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'double'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
doubleVar = tearoffableArg;
^" in tearoffableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t68 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:182:15: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t87 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:182:15: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'double'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
doubleVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t69 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:183:15: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t88 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:183:15: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'double'.
doubleVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t70 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:184:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:184:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'double'.
doubleVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t71 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:185:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t90 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:185:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'double'.
doubleVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t72 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:186:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t91 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:186:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'double'.
doubleVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t73 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:187:15: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t92 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:187:15: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'double'.
doubleVar = yNonNullArg;
^" in yNonNullArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t74 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:188:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t93 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:188:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'double'.
doubleVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t75 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:189:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:189:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'double'.
doubleVar = yPotentiallyNullArg;
^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::double;
- doubleVar = let final<BottomType> #t76 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:190:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'double'.
+ doubleVar = let final<BottomType> #t95 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:190:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'double'.
doubleVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::double;
- core::Function functionVar = let final<BottomType> #t77 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:192:26: Error: A value of type 'Object' can't be assigned to a variable of type 'Function'.
+ core::Function functionVar = let final<BottomType> #t96 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:192:26: Error: A value of type 'Object' can't be assigned to a variable of type 'Function'.
- 'Object' is from 'dart:core'.
- 'Function' is from 'dart:core'.
Function functionVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t78 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:193:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t97 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:193:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'Function'.
- 'Object' is from 'dart:core'.
- 'Function' is from 'dart:core'.
functionVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:194:17: Error: A value of type 'num' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t98 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:194:17: Error: A value of type 'num' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t80 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:195:17: Error: A value of type 'num?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t99 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:195:17: Error: A value of type 'num?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t81 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:196:17: Error: A value of type 'int' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:196:17: Error: A value of type 'int' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = intArg;
^" in intArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t82 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:197:17: Error: A value of type 'int?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t101 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:197:17: Error: A value of type 'int?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = intNullableArg;
^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t83 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:198:17: Error: A value of type 'double' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t102 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:198:17: Error: A value of type 'double' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t84 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:199:17: Error: A value of type 'double?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:199:17: Error: A value of type 'double?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = doubleNullableArg;
^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t85 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:200:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:200:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = functionNullableArg;
- ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:201:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Function'.
+ ^" in let core::Function? #t105 = functionNullableArg in #t105.==(null) ?{core::Function} #t105 as{TypeError,ForNonNullableByDefault} core::Function : #t105{core::Function};
+ functionVar = let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:201:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = toVoidNullableArg;
- ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t87 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:202:17: Error: Can't tear off method 'call' from a potentially null value.
+ ^" in let () →? void #t107 = toVoidNullableArg in #t107.==(null) ?{core::Function} #t107 as{TypeError,ForNonNullableByDefault} core::Function : #t107{core::Function};
+ functionVar = let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:202:17: Error: Can't tear off method 'call' from a potentially null value.
functionVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError} core::Function;
- functionVar = let final<BottomType> #t88 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:203:17: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t109 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:203:17: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:204:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t110 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:204:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t90 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:205:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t111 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:205:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t91 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:206:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t112 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:206:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t92 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:207:17: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t113 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:207:17: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = yNonNullArg;
^" in yNonNullArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t93 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:208:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t114 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:208:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:209:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t115 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:209:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = yPotentiallyNullArg;
^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::Function;
- functionVar = let final<BottomType> #t95 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:210:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Function'.
+ functionVar = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:210:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
- () → void toVoidVar = let final<BottomType> #t96 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:212:31: Error: A value of type 'Object' can't be assigned to a variable of type 'void Function()'.
+ () → void toVoidVar = let final<BottomType> #t117 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:212:31: Error: A value of type 'Object' can't be assigned to a variable of type 'void Function()'.
- 'Object' is from 'dart:core'.
void Function() toVoidVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t97 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:213:15: Error: A value of type 'Object?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:213:15: Error: A value of type 'Object?' can't be assigned to a variable of type 'void Function()'.
- 'Object' is from 'dart:core'.
toVoidVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t98 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:214:15: Error: A value of type 'num' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:214:15: Error: A value of type 'num' can't be assigned to a variable of type 'void Function()'.
toVoidVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t99 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:215:15: Error: A value of type 'num?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t120 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:215:15: Error: A value of type 'num?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t100 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:216:15: Error: A value of type 'int' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:216:15: Error: A value of type 'int' can't be assigned to a variable of type 'void Function()'.
toVoidVar = intArg;
^" in intArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t101 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:217:15: Error: A value of type 'int?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:217:15: Error: A value of type 'int?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = intNullableArg;
^" in intNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t102 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:218:15: Error: A value of type 'double' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t123 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:218:15: Error: A value of type 'double' can't be assigned to a variable of type 'void Function()'.
toVoidVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:219:15: Error: A value of type 'double?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t124 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:219:15: Error: A value of type 'double?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = doubleNullableArg;
^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t104 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:220:15: Error: A value of type 'Function' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t125 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:220:15: Error: A value of type 'Function' can't be assigned to a variable of type 'void Function()'.
- 'Function' is from 'dart:core'.
toVoidVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t105 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:221:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t126 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:221:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'void Function()'.
- 'Function' is from 'dart:core'.
toVoidVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:222:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t127 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:222:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = toVoidNullableArg;
- ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t107 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:223:15: Error: Can't tear off method 'call' from a potentially null value.
+ ^" in let () →? void #t128 = toVoidNullableArg in #t128.==(null) ?{() → void} #t128 as{TypeError,ForNonNullableByDefault} () → void : #t128{() → void};
+ toVoidVar = let final<BottomType> #t129 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:223:15: Error: Can't tear off method 'call' from a potentially null value.
toVoidVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError} () → void;
- toVoidVar = let final<BottomType> #t108 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:224:15: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t130 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:224:15: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'void Function()'.
toVoidVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t109 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:225:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t131 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:225:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t110 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:226:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t132 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:226:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'void Function()'.
toVoidVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t111 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:227:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t133 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:227:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t112 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:228:15: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t134 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:228:15: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'void Function()'.
toVoidVar = yNonNullArg;
^" in yNonNullArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t113 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:229:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t135 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:229:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t114 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:230:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t136 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:230:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'void Function()'.
toVoidVar = yPotentiallyNullArg;
^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} () → void;
- toVoidVar = let final<BottomType> #t115 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:231:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'void Function()'.
+ toVoidVar = let final<BottomType> #t137 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:231:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} () → void;
- self::Tearoffable tearoffableVar = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:233:32: Error: A value of type 'Object' can't be assigned to a variable of type 'Tearoffable'.
+ self::Tearoffable tearoffableVar = let final<BottomType> #t138 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:233:32: Error: A value of type 'Object' can't be assigned to a variable of type 'Tearoffable'.
- 'Object' is from 'dart:core'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
Tearoffable tearoffableVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t117 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:234:20: Error: A value of type 'Object?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t139 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:234:20: Error: A value of type 'Object?' can't be assigned to a variable of type 'Tearoffable'.
- 'Object' is from 'dart:core'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t118 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:235:20: Error: A value of type 'num' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t140 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:235:20: Error: A value of type 'num' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t119 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:236:20: Error: A value of type 'num?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:236:20: Error: A value of type 'num?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t120 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:237:20: Error: A value of type 'int' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t142 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:237:20: Error: A value of type 'int' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = intArg;
^" in intArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t121 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:238:20: Error: A value of type 'int?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:238:20: Error: A value of type 'int?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = intNullableArg;
^" in intNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:239:20: Error: A value of type 'double' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t144 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:239:20: Error: A value of type 'double' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t123 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:240:20: Error: A value of type 'double?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:240:20: Error: A value of type 'double?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = doubleNullableArg;
^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t124 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:241:20: Error: A value of type 'Function' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t146 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:241:20: Error: A value of type 'Function' can't be assigned to a variable of type 'Tearoffable'.
- 'Function' is from 'dart:core'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t125 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:242:20: Error: A value of type 'Function?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t147 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:242:20: Error: A value of type 'Function?' can't be assigned to a variable of type 'Tearoffable'.
- 'Function' is from 'dart:core'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t126 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:243:20: Error: A value of type 'void Function()' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:243:20: Error: A value of type 'void Function()' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = toVoidArg;
^" in toVoidArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t127 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:244:20: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t149 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:244:20: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = toVoidNullableArg;
^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t128 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:245:20: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t150 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:245:20: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = tearoffableNullableArg;
- ^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t129 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:246:20: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Tearoffable'.
+ ^" in let self::Tearoffable? #t151 = tearoffableNullableArg in #t151.==(null) ?{self::Tearoffable} #t151 as{TypeError,ForNonNullableByDefault} self::Tearoffable : #t151{self::Tearoffable};
+ tearoffableVar = let final<BottomType> #t152 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:246:20: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t130 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:247:20: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t153 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:247:20: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t131 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:248:20: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t154 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:248:20: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t132 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:249:20: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t155 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:249:20: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t133 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:250:20: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t156 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:250:20: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = yNonNullArg;
^" in yNonNullArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t134 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:251:20: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t157 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:251:20: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t135 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:252:20: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t158 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:252:20: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = yPotentiallyNullArg;
^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- tearoffableVar = let final<BottomType> #t136 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:253:20: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Tearoffable'.
+ tearoffableVar = let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:253:20: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
- self::error::XnonNull xNonNullVar = let final<BottomType> #t137 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:255:26: Error: A value of type 'Object' can't be assigned to a variable of type 'XnonNull'.
+ self::error::XnonNull xNonNullVar = let final<BottomType> #t160 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:255:26: Error: A value of type 'Object' can't be assigned to a variable of type 'XnonNull'.
- 'Object' is from 'dart:core'.
XnonNull xNonNullVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t138 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:256:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t161 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:256:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'XnonNull'.
- 'Object' is from 'dart:core'.
xNonNullVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t139 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:257:17: Error: A value of type 'num' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:257:17: Error: A value of type 'num' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t140 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:258:17: Error: A value of type 'num?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t163 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:258:17: Error: A value of type 'num?' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:259:17: Error: A value of type 'int' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t164 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:259:17: Error: A value of type 'int' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = intArg;
^" in intArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t142 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:260:17: Error: A value of type 'int?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t165 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:260:17: Error: A value of type 'int?' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = intNullableArg;
^" in intNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:261:17: Error: A value of type 'double' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t166 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:261:17: Error: A value of type 'double' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t144 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:262:17: Error: A value of type 'double?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t167 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:262:17: Error: A value of type 'double?' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = doubleNullableArg;
^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:263:17: Error: A value of type 'Function' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t168 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:263:17: Error: A value of type 'Function' can't be assigned to a variable of type 'XnonNull'.
- 'Function' is from 'dart:core'.
xNonNullVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t146 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:264:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t169 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:264:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'XnonNull'.
- 'Function' is from 'dart:core'.
xNonNullVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t147 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:265:17: Error: A value of type 'void Function()' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t170 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:265:17: Error: A value of type 'void Function()' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = toVoidArg;
^" in toVoidArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:266:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:266:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = toVoidNullableArg;
^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t149 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:267:17: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t172 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:267:17: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'XnonNull'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
xNonNullVar = tearoffableArg;
^" in tearoffableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t150 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:268:17: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:268:17: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'XnonNull'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
xNonNullVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:269:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t174 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:269:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t152 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:270:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:270:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t153 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:271:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t176 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:271:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t154 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:272:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t177 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:272:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t155 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:273:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:273:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = yPotentiallyNullArg;
^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xNonNullVar = let final<BottomType> #t156 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:274:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'XnonNull'.
+ xNonNullVar = let final<BottomType> #t179 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:274:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'XnonNull'.
xNonNullVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- self::error::XpotentiallyNull% xPotentiallyNullVar = let final<BottomType> #t157 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:276:42: Error: A value of type 'Object' can't be assigned to a variable of type 'XpotentiallyNull'.
+ self::error::XpotentiallyNull% xPotentiallyNullVar = let final<BottomType> #t180 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:276:42: Error: A value of type 'Object' can't be assigned to a variable of type 'XpotentiallyNull'.
- 'Object' is from 'dart:core'.
XpotentiallyNull xPotentiallyNullVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t158 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:277:25: Error: A value of type 'Object?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:277:25: Error: A value of type 'Object?' can't be assigned to a variable of type 'XpotentiallyNull'.
- 'Object' is from 'dart:core'.
xPotentiallyNullVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:278:25: Error: A value of type 'num' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t182 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:278:25: Error: A value of type 'num' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t160 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:279:25: Error: A value of type 'num?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t183 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:279:25: Error: A value of type 'num?' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t161 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:280:25: Error: A value of type 'int' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:280:25: Error: A value of type 'int' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = intArg;
^" in intArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:281:25: Error: A value of type 'int?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t185 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:281:25: Error: A value of type 'int?' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = intNullableArg;
^" in intNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t163 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:282:25: Error: A value of type 'double' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t186 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:282:25: Error: A value of type 'double' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t164 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:283:25: Error: A value of type 'double?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t187 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:283:25: Error: A value of type 'double?' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = doubleNullableArg;
^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t165 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:284:25: Error: A value of type 'Function' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t188 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:284:25: Error: A value of type 'Function' can't be assigned to a variable of type 'XpotentiallyNull'.
- 'Function' is from 'dart:core'.
xPotentiallyNullVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t166 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:285:25: Error: A value of type 'Function?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t189 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:285:25: Error: A value of type 'Function?' can't be assigned to a variable of type 'XpotentiallyNull'.
- 'Function' is from 'dart:core'.
xPotentiallyNullVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t167 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:286:25: Error: A value of type 'void Function()' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t190 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:286:25: Error: A value of type 'void Function()' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = toVoidArg;
^" in toVoidArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t168 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:287:25: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t191 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:287:25: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = toVoidNullableArg;
^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t169 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:288:25: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t192 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:288:25: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'XpotentiallyNull'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
xPotentiallyNullVar = tearoffableArg;
^" in tearoffableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t170 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:289:25: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t193 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:289:25: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'XpotentiallyNull'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
xPotentiallyNullVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:290:25: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t194 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:290:25: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t172 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:291:25: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t195 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:291:25: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:292:25: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t196 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:292:25: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t174 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:293:25: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t197 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:293:25: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = yNonNullArg;
^" in yNonNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:294:25: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t198 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:294:25: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- xPotentiallyNullVar = let final<BottomType> #t176 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:295:25: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
+ xPotentiallyNullVar = let final<BottomType> #t199 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:295:25: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'XpotentiallyNull'.
xPotentiallyNullVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- self::error::YnonNull yNonNullVar = let final<BottomType> #t177 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:297:26: Error: A value of type 'Object' can't be assigned to a variable of type 'YnonNull'.
+ self::error::YnonNull yNonNullVar = let final<BottomType> #t200 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:297:26: Error: A value of type 'Object' can't be assigned to a variable of type 'YnonNull'.
- 'Object' is from 'dart:core'.
YnonNull yNonNullVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:298:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t201 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:298:17: Error: A value of type 'Object?' can't be assigned to a variable of type 'YnonNull'.
- 'Object' is from 'dart:core'.
yNonNullVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t179 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:299:17: Error: A value of type 'num' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:299:17: Error: A value of type 'num' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t180 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:300:17: Error: A value of type 'num?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t203 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:300:17: Error: A value of type 'num?' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:301:17: Error: A value of type 'int' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t204 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:301:17: Error: A value of type 'int' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = intArg;
^" in intArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t182 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:302:17: Error: A value of type 'int?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t205 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:302:17: Error: A value of type 'int?' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = intNullableArg;
^" in intNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t183 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:303:17: Error: A value of type 'double' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:303:17: Error: A value of type 'double' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:304:17: Error: A value of type 'double?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t207 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:304:17: Error: A value of type 'double?' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = doubleNullableArg;
^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t185 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:305:17: Error: A value of type 'Function' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t208 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:305:17: Error: A value of type 'Function' can't be assigned to a variable of type 'YnonNull'.
- 'Function' is from 'dart:core'.
yNonNullVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t186 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:306:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t209 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:306:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'YnonNull'.
- 'Function' is from 'dart:core'.
yNonNullVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t187 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:307:17: Error: A value of type 'void Function()' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:307:17: Error: A value of type 'void Function()' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = toVoidArg;
^" in toVoidArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t188 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:308:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t211 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:308:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = toVoidNullableArg;
^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t189 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:309:17: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t212 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:309:17: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'YnonNull'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
yNonNullVar = tearoffableArg;
^" in tearoffableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t190 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:310:17: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t213 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:310:17: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'YnonNull'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
yNonNullVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t191 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:311:17: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t214 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:311:17: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t192 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:312:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:312:17: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t193 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:313:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t216 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:313:17: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t194 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:314:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t217 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:314:17: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t195 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:315:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t218 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:315:17: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t196 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:316:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t219 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:316:17: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = yPotentiallyNullArg;
^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yNonNullVar = let final<BottomType> #t197 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:317:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'YnonNull'.
+ yNonNullVar = let final<BottomType> #t220 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:317:17: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'YnonNull'.
yNonNullVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- self::error::YpotentiallyNull% yPotentiallyNullVar = let final<BottomType> #t198 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:319:42: Error: A value of type 'Object' can't be assigned to a variable of type 'YpotentiallyNull'.
+ self::error::YpotentiallyNull% yPotentiallyNullVar = let final<BottomType> #t221 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:319:42: Error: A value of type 'Object' can't be assigned to a variable of type 'YpotentiallyNull'.
- 'Object' is from 'dart:core'.
YpotentiallyNull yPotentiallyNullVar = objectArg;
^" in objectArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t199 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:320:25: Error: A value of type 'Object?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t222 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:320:25: Error: A value of type 'Object?' can't be assigned to a variable of type 'YpotentiallyNull'.
- 'Object' is from 'dart:core'.
yPotentiallyNullVar = objectNullableArg;
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t200 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:321:25: Error: A value of type 'num' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t223 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:321:25: Error: A value of type 'num' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = numArg;
^" in numArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t201 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:322:25: Error: A value of type 'num?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t224 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:322:25: Error: A value of type 'num?' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = numNullableArg;
^" in numNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:323:25: Error: A value of type 'int' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t225 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:323:25: Error: A value of type 'int' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = intArg;
^" in intArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t203 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:324:25: Error: A value of type 'int?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t226 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:324:25: Error: A value of type 'int?' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = intNullableArg;
^" in intNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t204 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:325:25: Error: A value of type 'double' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t227 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:325:25: Error: A value of type 'double' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t205 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:326:25: Error: A value of type 'double?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t228 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:326:25: Error: A value of type 'double?' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = doubleNullableArg;
^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:327:25: Error: A value of type 'Function' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t229 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:327:25: Error: A value of type 'Function' can't be assigned to a variable of type 'YpotentiallyNull'.
- 'Function' is from 'dart:core'.
yPotentiallyNullVar = functionArg;
^" in functionArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t207 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:328:25: Error: A value of type 'Function?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t230 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:328:25: Error: A value of type 'Function?' can't be assigned to a variable of type 'YpotentiallyNull'.
- 'Function' is from 'dart:core'.
yPotentiallyNullVar = functionNullableArg;
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t208 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:329:25: Error: A value of type 'void Function()' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t231 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:329:25: Error: A value of type 'void Function()' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = toVoidArg;
^" in toVoidArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t209 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:330:25: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t232 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:330:25: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = toVoidNullableArg;
^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:331:25: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t233 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:331:25: Error: A value of type 'Tearoffable' can't be assigned to a variable of type 'YpotentiallyNull'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
yPotentiallyNullVar = tearoffableArg;
^" in tearoffableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t211 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:332:25: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t234 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:332:25: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'YpotentiallyNull'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
yPotentiallyNullVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t212 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:333:25: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t235 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:333:25: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = xNonNullArg;
^" in xNonNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t213 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:334:25: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t236 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:334:25: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = xNonNullNullableArg;
^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t214 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:335:25: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t237 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:335:25: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = xPotentiallyNullArg;
^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:336:25: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t238 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:336:25: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = xPotentiallyNullNullableArg;
^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t216 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:337:25: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t239 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:337:25: Error: A value of type 'YnonNull' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = yNonNullArg;
^" in yNonNullArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t217 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:338:25: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t240 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:338:25: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = yNonNullNullableArg;
^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
- yPotentiallyNullVar = let final<BottomType> #t218 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:339:25: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
+ yPotentiallyNullVar = let final<BottomType> #t241 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:339:25: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'YpotentiallyNull'.
yPotentiallyNullVar = yPotentiallyNullNullableArg;
^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} <BottomType>;
}
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/assignability.dart.weak.transformed.expect
index 9c3d453..c141b93 100644
--- a/pkg/front_end/testcases/nnbd/assignability.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.weak.transformed.expect
@@ -994,7 +994,7 @@
dynamicVar = xPotentiallyNullArg;
dynamicVar = yNonNullArg;
dynamicVar = yPotentiallyNullArg;
- core::Object objectVar = dynamicArg as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object;
+ core::Object objectVar = dynamicArg;
objectVar = objectArg;
objectVar = numArg;
objectVar = intArg;
@@ -1035,57 +1035,57 @@
core::Object objectVar = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:114:22: Error: A value of type 'Object?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
Object objectVar = objectNullableArg;
- ^" in objectNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in objectNullableArg;
objectVar = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:115:15: Error: A value of type 'num?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = numNullableArg;
- ^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in numNullableArg;
objectVar = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:116:15: Error: A value of type 'int?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = intNullableArg;
- ^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in intNullableArg;
objectVar = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:117:15: Error: A value of type 'double?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = doubleNullableArg;
- ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in doubleNullableArg;
objectVar = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:118:15: Error: A value of type 'Function?' can't be assigned to a variable of type 'Object'.
- 'Function' is from 'dart:core'.
- 'Object' is from 'dart:core'.
objectVar = functionNullableArg;
- ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in functionNullableArg;
objectVar = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:119:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = toVoidNullableArg;
- ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in toVoidNullableArg;
objectVar = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:120:15: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Object'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
- 'Object' is from 'dart:core'.
objectVar = tearoffableNullableArg;
- ^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in tearoffableNullableArg;
objectVar = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:121:15: Error: A value of type 'XnonNull?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = xNonNullNullableArg;
- ^" in xNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in xNonNullNullableArg;
objectVar = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:122:15: Error: A value of type 'XpotentiallyNull' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = xPotentiallyNullArg;
- ^" in xPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in xPotentiallyNullArg;
objectVar = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:123:15: Error: A value of type 'XpotentiallyNull?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = xPotentiallyNullNullableArg;
- ^" in xPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in xPotentiallyNullNullableArg;
objectVar = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:124:15: Error: A value of type 'YnonNull?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = yNonNullNullableArg;
- ^" in yNonNullNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in yNonNullNullableArg;
objectVar = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:125:15: Error: A value of type 'YpotentiallyNull' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = yPotentiallyNullArg;
- ^" in yPotentiallyNullArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in yPotentiallyNullArg;
objectVar = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:126:15: Error: A value of type 'YpotentiallyNull?' can't be assigned to a variable of type 'Object'.
- 'Object' is from 'dart:core'.
objectVar = yPotentiallyNullNullableArg;
- ^" in yPotentiallyNullNullableArg as{TypeError,ForNonNullableByDefault} core::Object;
+ ^" in yPotentiallyNullNullableArg;
core::num numVar = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:128:16: Error: A value of type 'Object' can't be assigned to a variable of type 'num'.
- 'Object' is from 'dart:core'.
num numVar = objectArg;
@@ -1096,13 +1096,13 @@
^" in objectNullableArg as{TypeError,ForNonNullableByDefault} core::num;
numVar = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:130:12: Error: A value of type 'num?' can't be assigned to a variable of type 'num'.
numVar = numNullableArg;
- ^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::num;
+ ^" in numNullableArg;
numVar = let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:131:12: Error: A value of type 'int?' can't be assigned to a variable of type 'num'.
numVar = intNullableArg;
- ^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::num;
+ ^" in intNullableArg;
numVar = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:132:12: Error: A value of type 'double?' can't be assigned to a variable of type 'num'.
numVar = doubleNullableArg;
- ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} core::num;
+ ^" in doubleNullableArg;
numVar = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:133:12: Error: A value of type 'Function' can't be assigned to a variable of type 'num'.
- 'Function' is from 'dart:core'.
numVar = functionArg;
@@ -1165,7 +1165,7 @@
^" in numNullableArg as{TypeError,ForNonNullableByDefault} core::int;
intVar = let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:152:12: Error: A value of type 'int?' can't be assigned to a variable of type 'int'.
intVar = intNullableArg;
- ^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::int;
+ ^" in intNullableArg;
intVar = let final<BottomType> #t40 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:153:12: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
intVar = doubleArg;
^" in doubleArg as{TypeError,ForNonNullableByDefault} core::int;
@@ -1240,7 +1240,7 @@
^" in intNullableArg as{TypeError,ForNonNullableByDefault} core::double;
doubleVar = let final<BottomType> #t62 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:176:15: Error: A value of type 'double?' can't be assigned to a variable of type 'double'.
doubleVar = doubleNullableArg;
- ^" in doubleNullableArg as{TypeError,ForNonNullableByDefault} core::double;
+ ^" in doubleNullableArg;
doubleVar = let final<BottomType> #t63 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:177:15: Error: A value of type 'Function' can't be assigned to a variable of type 'double'.
- 'Function' is from 'dart:core'.
doubleVar = functionArg;
@@ -1324,11 +1324,11 @@
functionVar = let final<BottomType> #t85 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:200:17: Error: A value of type 'Function?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = functionNullableArg;
- ^" in functionNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
+ ^" in functionNullableArg;
functionVar = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:201:17: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'Function'.
- 'Function' is from 'dart:core'.
functionVar = toVoidNullableArg;
- ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} core::Function;
+ ^" in toVoidNullableArg;
functionVar = let final<BottomType> #t87 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:202:17: Error: Can't tear off method 'call' from a potentially null value.
functionVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError} core::Function;
@@ -1400,7 +1400,7 @@
^" in functionNullableArg as{TypeError,ForNonNullableByDefault} () → void;
toVoidVar = let final<BottomType> #t106 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:222:15: Error: A value of type 'void Function()?' can't be assigned to a variable of type 'void Function()'.
toVoidVar = toVoidNullableArg;
- ^" in toVoidNullableArg as{TypeError,ForNonNullableByDefault} () → void;
+ ^" in toVoidNullableArg;
toVoidVar = let final<BottomType> #t107 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:223:15: Error: Can't tear off method 'call' from a potentially null value.
toVoidVar = tearoffableNullableArg;
^" in tearoffableNullableArg as{TypeError} () → void;
@@ -1483,7 +1483,7 @@
tearoffableVar = let final<BottomType> #t128 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:245:20: Error: A value of type 'Tearoffable?' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = tearoffableNullableArg;
- ^" in tearoffableNullableArg as{TypeError,ForNonNullableByDefault} self::Tearoffable;
+ ^" in tearoffableNullableArg;
tearoffableVar = let final<BottomType> #t129 = invalid-expression "pkg/front_end/testcases/nnbd/assignability.dart:246:20: Error: A value of type 'XnonNull' can't be assigned to a variable of type 'Tearoffable'.
- 'Tearoffable' is from 'pkg/front_end/testcases/nnbd/assignability.dart'.
tearoffableVar = xNonNullArg;
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart b/pkg/front_end/testcases/nnbd/constant_null_is.dart
new file mode 100644
index 0000000..bdbd2fd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart
@@ -0,0 +1,94 @@
+// 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';
+
+final bool isWeakMode = const <Null>[] is List<Object>;
+
+const c0 = null is int?;
+const c1 = null is int;
+const c2 = null is Null;
+const c3 = null is Never?;
+const c4 = null is Never;
+const c5 = null is FutureOr<int?>;
+const c6 = null is FutureOr<int>;
+const c7 = null is FutureOr<int>?;
+const c8 = null is FutureOr<Null>;
+const c9 = null is FutureOr<Null>?;
+const c10 = null is FutureOr<Never>;
+const c11 = null is FutureOr<Never?>;
+const c12 = null is FutureOr<Never>?;
+const e1 = const Class<int>.constructor1(null);
+const e2 = const Class<int?>.constructor1(null);
+const e3 = const Class<Null>.constructor1(null);
+const e4 = const Class<int>.constructor2(null);
+const e5 = const Class<int?>.constructor2(null);
+const e6 = const Class<Null>.constructor2(null);
+const e7 = const Class<int>.constructor3(null);
+const e8 = const Class<int?>.constructor3(null);
+const e9 = const Class<Null>.constructor3(null);
+const e10 = const Class<int>.constructor4(null);
+const e11 = const Class<int?>.constructor4(null);
+const e12 = const Class<Null>.constructor4(null);
+
+class Class<T> {
+ final bool field;
+
+ const Class.constructor1(value) : field = value is T;
+ const Class.constructor2(value) : field = value is T?;
+ const Class.constructor3(value) : field = value is Class<T>;
+ const Class.constructor4(value) : field = value is Class<T>?;
+}
+
+main() {
+ expect(null is int?, c0, "null is int?");
+ expect(null is int, c1, "null is int");
+ expect(null is Null, c2, "null is Null");
+ expect(null is Never?, c3, "null is Never?");
+ expect(null is Never, c4, "null is Never");
+ expect(null is FutureOr<int?>, c5, "null is FutureOr<int?>");
+ expect(null is FutureOr<int>, c6, "null is FutureOr<int>");
+ expect(null is FutureOr<int>?, c7, "null is FutureOr<int>?");
+ expect(null is FutureOr<Null>, c8, "null is FutureOr<Null>");
+ expect(null is FutureOr<Null>?, c9, "null is FutureOr<Null>?");
+ expect(null is FutureOr<Never>, c10, "null is FutureOr<Never>");
+ expect(null is FutureOr<Never?>, c11, "null is FutureOr<Never?>");
+ expect(null is FutureOr<Never>?, c12, "null is FutureOr<Never>?");
+ expect(new Class<int>.constructor1(null).field, e1.field,
+ "Class<int>.constructor1(null).field");
+ expect(true, new Class<int?>.constructor1(null).field,
+ "new Class<int?>.constructor1(null).field");
+ // const Class<int?> is evaluated as const Class<int*> in weak mode:
+ expect(!isWeakMode, e2.field, "const Class<int?>.constructor1(null).field");
+ expect(new Class<Null>.constructor1(null).field, e3.field,
+ "Class<Null>.constructor1(null).field");
+ expect(new Class<int>.constructor2(null).field, e4.field,
+ "Class<int>.constructor2(null).field");
+ expect(true, new Class<int?>.constructor2(null).field,
+ "new Class<int?>.constructor2(null).field");
+ // const Class<int?> is evaluated as const Class<int*> in weak mode:
+ expect(new Class<int?>.constructor2(null).field, e5.field,
+ "Class<int?>.constructor2(null).field");
+ expect(new Class<Null>.constructor2(null).field, e6.field,
+ "Class<Null>.constructor2(null).field");
+ expect(new Class<int>.constructor3(null).field, e7.field,
+ "Class<int>.constructor3(null).field");
+ expect(new Class<int?>.constructor3(null).field, e8.field,
+ "Class<int?>.constructor3(null).field");
+ expect(new Class<int?>.constructor3(null).field, e8.field,
+ "Class<int?>.constructor3(null).field");
+ expect(new Class<Null>.constructor3(null).field, e9.field,
+ "Class<Null>.constructor3(null).field");
+ expect(new Class<int>.constructor4(null).field, e10.field,
+ "Class<int>.constructor4(null).field");
+ expect(new Class<int?>.constructor4(null).field, e11.field,
+ "Class<int?>.constructor4(null).field");
+ expect(new Class<Null>.constructor4(null).field, e12.field,
+ "Class<Null>.constructor4(null).field");
+}
+
+expect(expected, actual, String message) {
+ if (expected != actual)
+ throw 'Expected $expected, actual $actual for $message';
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.outline.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.outline.expect
new file mode 100644
index 0000000..6c26486
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.outline.expect
@@ -0,0 +1,52 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ final field core::bool field;
+ const constructor constructor1(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+ ;
+ const constructor constructor2(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T?, super core::Object::•()
+ ;
+ const constructor constructor3(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>, super core::Object::•()
+ ;
+ const constructor constructor4(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>?, super core::Object::•()
+ ;
+}
+static final field core::bool isWeakMode;
+static const field core::bool c0 = null is{ForNonNullableByDefault} core::int?;
+static const field core::bool c1 = null is{ForNonNullableByDefault} core::int;
+static const field core::bool c2 = null is{ForNonNullableByDefault} core::Null?;
+static const field core::bool c3 = null is{ForNonNullableByDefault} Never?;
+static const field core::bool c4 = null is{ForNonNullableByDefault} Never;
+static const field core::bool c5 = null is{ForNonNullableByDefault} asy::FutureOr<core::int?>;
+static const field core::bool c6 = null is{ForNonNullableByDefault} asy::FutureOr<core::int>;
+static const field core::bool c7 = null is{ForNonNullableByDefault} asy::FutureOr<core::int>?;
+static const field core::bool c8 = null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>;
+static const field core::bool c9 = null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?;
+static const field core::bool c10 = null is{ForNonNullableByDefault} asy::FutureOr<Never>;
+static const field core::bool c11 = null is{ForNonNullableByDefault} asy::FutureOr<Never?>;
+static const field core::bool c12 = null is{ForNonNullableByDefault} asy::FutureOr<Never>?;
+static const field self::Class<core::int> e1 = const self::Class::constructor1<core::int>(null);
+static const field self::Class<core::int?> e2 = const self::Class::constructor1<core::int?>(null);
+static const field self::Class<core::Null?> e3 = const self::Class::constructor1<core::Null?>(null);
+static const field self::Class<core::int> e4 = const self::Class::constructor2<core::int>(null);
+static const field self::Class<core::int?> e5 = const self::Class::constructor2<core::int?>(null);
+static const field self::Class<core::Null?> e6 = const self::Class::constructor2<core::Null?>(null);
+static const field self::Class<core::int> e7 = const self::Class::constructor3<core::int>(null);
+static const field self::Class<core::int?> e8 = const self::Class::constructor3<core::int?>(null);
+static const field self::Class<core::Null?> e9 = const self::Class::constructor3<core::Null?>(null);
+static const field self::Class<core::int> e10 = const self::Class::constructor4<core::int>(null);
+static const field self::Class<core::int?> e11 = const self::Class::constructor4<core::int?>(null);
+static const field self::Class<core::Null?> e12 = const self::Class::constructor4<core::Null?>(null);
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.expect
new file mode 100644
index 0000000..0584096
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.expect
@@ -0,0 +1,94 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ final field core::bool field;
+ const constructor constructor1(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+ ;
+ const constructor constructor2(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T?, super core::Object::•()
+ ;
+ const constructor constructor3(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>, super core::Object::•()
+ ;
+ const constructor constructor4(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>?, super core::Object::•()
+ ;
+}
+static final field core::bool isWeakMode = (#C1) is{ForNonNullableByDefault} core::List<core::Object>;
+static const field core::bool c0 = #C2;
+static const field core::bool c1 = #C3;
+static const field core::bool c2 = #C2;
+static const field core::bool c3 = #C2;
+static const field core::bool c4 = #C3;
+static const field core::bool c5 = #C2;
+static const field core::bool c6 = #C3;
+static const field core::bool c7 = #C2;
+static const field core::bool c8 = #C2;
+static const field core::bool c9 = #C2;
+static const field core::bool c10 = #C3;
+static const field core::bool c11 = #C2;
+static const field core::bool c12 = #C2;
+static const field self::Class<core::int> e1 = #C4;
+static const field self::Class<core::int?> e2 = #C5;
+static const field self::Class<core::Null?> e3 = #C6;
+static const field self::Class<core::int> e4 = #C7;
+static const field self::Class<core::int?> e5 = #C5;
+static const field self::Class<core::Null?> e6 = #C6;
+static const field self::Class<core::int> e7 = #C4;
+static const field self::Class<core::int?> e8 = #C8;
+static const field self::Class<core::Null?> e9 = #C9;
+static const field self::Class<core::int> e10 = #C7;
+static const field self::Class<core::int?> e11 = #C5;
+static const field self::Class<core::Null?> e12 = #C6;
+static method main() → dynamic {
+ self::expect(null is{ForNonNullableByDefault} core::int?, #C2, "null is int?");
+ self::expect(null is{ForNonNullableByDefault} core::int, #C3, "null is int");
+ self::expect(null is{ForNonNullableByDefault} core::Null?, #C2, "null is Null");
+ self::expect(null is{ForNonNullableByDefault} Never?, #C2, "null is Never?");
+ self::expect(null is{ForNonNullableByDefault} Never, #C3, "null is Never");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C2, "null is FutureOr<int?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C3, "null is FutureOr<int>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C2, "null is FutureOr<int>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C2, "null is FutureOr<Null>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C2, "null is FutureOr<Null>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C3, "null is FutureOr<Never>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C2, "null is FutureOr<Never?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C2, "null is FutureOr<Never>?");
+ self::expect(new self::Class::constructor1<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor1(null).field");
+ self::expect(true, new self::Class::constructor1<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor1(null).field");
+ self::expect(!self::isWeakMode, (#C5).{self::Class::field}, "const Class<int?>.constructor1(null).field");
+ self::expect(new self::Class::constructor1<core::Null?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<Null>.constructor1(null).field");
+ self::expect(new self::Class::constructor2<core::int>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<int>.constructor2(null).field");
+ self::expect(true, new self::Class::constructor2<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::int?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::Null?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<Null>.constructor2(null).field");
+ self::expect(new self::Class::constructor3<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C8).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C8).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::Null?>(null).{self::Class::field}, (#C9).{self::Class::field}, "Class<Null>.constructor3(null).field");
+ self::expect(new self::Class::constructor4<core::int>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<int>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::int?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<int?>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::Null?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<Null>.constructor4(null).field");
+}
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual} for ${message}";
+}
+
+constants {
+ #C1 = <core::Null?>[]
+ #C2 = true
+ #C3 = false
+ #C4 = self::Class<core::int> {field:#C3}
+ #C5 = self::Class<core::int?> {field:#C2}
+ #C6 = self::Class<core::Null?> {field:#C2}
+ #C7 = self::Class<core::int> {field:#C2}
+ #C8 = self::Class<core::int?> {field:#C3}
+ #C9 = self::Class<core::Null?> {field:#C3}
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.transformed.expect
new file mode 100644
index 0000000..0584096
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.strong.transformed.expect
@@ -0,0 +1,94 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ final field core::bool field;
+ const constructor constructor1(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+ ;
+ const constructor constructor2(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T?, super core::Object::•()
+ ;
+ const constructor constructor3(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>, super core::Object::•()
+ ;
+ const constructor constructor4(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>?, super core::Object::•()
+ ;
+}
+static final field core::bool isWeakMode = (#C1) is{ForNonNullableByDefault} core::List<core::Object>;
+static const field core::bool c0 = #C2;
+static const field core::bool c1 = #C3;
+static const field core::bool c2 = #C2;
+static const field core::bool c3 = #C2;
+static const field core::bool c4 = #C3;
+static const field core::bool c5 = #C2;
+static const field core::bool c6 = #C3;
+static const field core::bool c7 = #C2;
+static const field core::bool c8 = #C2;
+static const field core::bool c9 = #C2;
+static const field core::bool c10 = #C3;
+static const field core::bool c11 = #C2;
+static const field core::bool c12 = #C2;
+static const field self::Class<core::int> e1 = #C4;
+static const field self::Class<core::int?> e2 = #C5;
+static const field self::Class<core::Null?> e3 = #C6;
+static const field self::Class<core::int> e4 = #C7;
+static const field self::Class<core::int?> e5 = #C5;
+static const field self::Class<core::Null?> e6 = #C6;
+static const field self::Class<core::int> e7 = #C4;
+static const field self::Class<core::int?> e8 = #C8;
+static const field self::Class<core::Null?> e9 = #C9;
+static const field self::Class<core::int> e10 = #C7;
+static const field self::Class<core::int?> e11 = #C5;
+static const field self::Class<core::Null?> e12 = #C6;
+static method main() → dynamic {
+ self::expect(null is{ForNonNullableByDefault} core::int?, #C2, "null is int?");
+ self::expect(null is{ForNonNullableByDefault} core::int, #C3, "null is int");
+ self::expect(null is{ForNonNullableByDefault} core::Null?, #C2, "null is Null");
+ self::expect(null is{ForNonNullableByDefault} Never?, #C2, "null is Never?");
+ self::expect(null is{ForNonNullableByDefault} Never, #C3, "null is Never");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C2, "null is FutureOr<int?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C3, "null is FutureOr<int>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C2, "null is FutureOr<int>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C2, "null is FutureOr<Null>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C2, "null is FutureOr<Null>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C3, "null is FutureOr<Never>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C2, "null is FutureOr<Never?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C2, "null is FutureOr<Never>?");
+ self::expect(new self::Class::constructor1<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor1(null).field");
+ self::expect(true, new self::Class::constructor1<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor1(null).field");
+ self::expect(!self::isWeakMode, (#C5).{self::Class::field}, "const Class<int?>.constructor1(null).field");
+ self::expect(new self::Class::constructor1<core::Null?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<Null>.constructor1(null).field");
+ self::expect(new self::Class::constructor2<core::int>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<int>.constructor2(null).field");
+ self::expect(true, new self::Class::constructor2<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::int?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::Null?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<Null>.constructor2(null).field");
+ self::expect(new self::Class::constructor3<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C8).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C8).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::Null?>(null).{self::Class::field}, (#C9).{self::Class::field}, "Class<Null>.constructor3(null).field");
+ self::expect(new self::Class::constructor4<core::int>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<int>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::int?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<int?>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::Null?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<Null>.constructor4(null).field");
+}
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual} for ${message}";
+}
+
+constants {
+ #C1 = <core::Null?>[]
+ #C2 = true
+ #C3 = false
+ #C4 = self::Class<core::int> {field:#C3}
+ #C5 = self::Class<core::int?> {field:#C2}
+ #C6 = self::Class<core::Null?> {field:#C2}
+ #C7 = self::Class<core::int> {field:#C2}
+ #C8 = self::Class<core::int?> {field:#C3}
+ #C9 = self::Class<core::Null?> {field:#C3}
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect
new file mode 100644
index 0000000..fcfd9f0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect
@@ -0,0 +1,39 @@
+import 'dart:async';
+
+final bool isWeakMode = const <Null>[] is List<Object>;
+const c0 = null is int?;
+const c1 = null is int;
+const c2 = null is Null;
+const c3 = null is Never?;
+const c4 = null is Never;
+const c5 = null is FutureOr<int?>;
+const c6 = null is FutureOr<int>;
+const c7 = null is FutureOr<int>?;
+const c8 = null is FutureOr<Null>;
+const c9 = null is FutureOr<Null>?;
+const c10 = null is FutureOr<Never>;
+const c11 = null is FutureOr<Never?>;
+const c12 = null is FutureOr<Never>?;
+const e1 = const Class<int>.constructor1(null);
+const e2 = const Class<int?>.constructor1(null);
+const e3 = const Class<Null>.constructor1(null);
+const e4 = const Class<int>.constructor2(null);
+const e5 = const Class<int?>.constructor2(null);
+const e6 = const Class<Null>.constructor2(null);
+const e7 = const Class<int>.constructor3(null);
+const e8 = const Class<int?>.constructor3(null);
+const e9 = const Class<Null>.constructor3(null);
+const e10 = const Class<int>.constructor4(null);
+const e11 = const Class<int?>.constructor4(null);
+const e12 = const Class<Null>.constructor4(null);
+
+class Class<T> {
+ final bool field;
+ const Class.constructor1(value) : field = value is T;
+ const Class.constructor2(value) : field = value is T?;
+ const Class.constructor3(value) : field = value is Class<T>;
+ const Class.constructor4(value) : field = value is Class<T>?;
+}
+
+main() {}
+expect(expected, actual, String message) {}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c072a2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect
@@ -0,0 +1,38 @@
+import 'dart:async';
+
+class Class<T> {
+ const Class.constructor1(value) : field = value is T;
+ const Class.constructor2(value) : field = value is T?;
+ const Class.constructor3(value) : field = value is Class<T>;
+ const Class.constructor4(value) : field = value is Class<T>?;
+ final bool field;
+}
+
+const c0 = null is int?;
+const c1 = null is int;
+const c10 = null is FutureOr<Never>;
+const c11 = null is FutureOr<Never?>;
+const c12 = null is FutureOr<Never>?;
+const c2 = null is Null;
+const c3 = null is Never?;
+const c4 = null is Never;
+const c5 = null is FutureOr<int?>;
+const c6 = null is FutureOr<int>;
+const c7 = null is FutureOr<int>?;
+const c8 = null is FutureOr<Null>;
+const c9 = null is FutureOr<Null>?;
+const e1 = const Class<int>.constructor1(null);
+const e10 = const Class<int>.constructor4(null);
+const e11 = const Class<int?>.constructor4(null);
+const e12 = const Class<Null>.constructor4(null);
+const e2 = const Class<int?>.constructor1(null);
+const e3 = const Class<Null>.constructor1(null);
+const e4 = const Class<int>.constructor2(null);
+const e5 = const Class<int?>.constructor2(null);
+const e6 = const Class<Null>.constructor2(null);
+const e7 = const Class<int>.constructor3(null);
+const e8 = const Class<int?>.constructor3(null);
+const e9 = const Class<Null>.constructor3(null);
+expect(expected, actual, String message) {}
+final bool isWeakMode = const <Null>[] is List<Object>;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.expect
new file mode 100644
index 0000000..525b38f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.expect
@@ -0,0 +1,92 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ final field core::bool field;
+ const constructor constructor1(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+ ;
+ const constructor constructor2(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T?, super core::Object::•()
+ ;
+ const constructor constructor3(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>, super core::Object::•()
+ ;
+ const constructor constructor4(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>?, super core::Object::•()
+ ;
+}
+static final field core::bool isWeakMode = (#C1) is{ForNonNullableByDefault} core::List<core::Object>;
+static const field core::bool c0 = #C2;
+static const field core::bool c1 = #C3;
+static const field core::bool c2 = #C2;
+static const field core::bool c3 = #C2;
+static const field core::bool c4 = #C3;
+static const field core::bool c5 = #C2;
+static const field core::bool c6 = #C3;
+static const field core::bool c7 = #C2;
+static const field core::bool c8 = #C2;
+static const field core::bool c9 = #C2;
+static const field core::bool c10 = #C3;
+static const field core::bool c11 = #C2;
+static const field core::bool c12 = #C2;
+static const field self::Class<core::int> e1 = #C4;
+static const field self::Class<core::int?> e2 = #C4;
+static const field self::Class<core::Null?> e3 = #C5;
+static const field self::Class<core::int> e4 = #C6;
+static const field self::Class<core::int?> e5 = #C6;
+static const field self::Class<core::Null?> e6 = #C5;
+static const field self::Class<core::int> e7 = #C4;
+static const field self::Class<core::int?> e8 = #C4;
+static const field self::Class<core::Null?> e9 = #C7;
+static const field self::Class<core::int> e10 = #C6;
+static const field self::Class<core::int?> e11 = #C6;
+static const field self::Class<core::Null?> e12 = #C5;
+static method main() → dynamic {
+ self::expect(null is{ForNonNullableByDefault} core::int?, #C2, "null is int?");
+ self::expect(null is{ForNonNullableByDefault} core::int, #C3, "null is int");
+ self::expect(null is{ForNonNullableByDefault} core::Null?, #C2, "null is Null");
+ self::expect(null is{ForNonNullableByDefault} Never?, #C2, "null is Never?");
+ self::expect(null is{ForNonNullableByDefault} Never, #C3, "null is Never");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C2, "null is FutureOr<int?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C3, "null is FutureOr<int>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C2, "null is FutureOr<int>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C2, "null is FutureOr<Null>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C2, "null is FutureOr<Null>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C3, "null is FutureOr<Never>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C2, "null is FutureOr<Never?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C2, "null is FutureOr<Never>?");
+ self::expect(new self::Class::constructor1<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor1(null).field");
+ self::expect(true, new self::Class::constructor1<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor1(null).field");
+ self::expect(!self::isWeakMode, (#C4).{self::Class::field}, "const Class<int?>.constructor1(null).field");
+ self::expect(new self::Class::constructor1<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor1(null).field");
+ self::expect(new self::Class::constructor2<core::int>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor2(null).field");
+ self::expect(true, new self::Class::constructor2<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::int?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor2(null).field");
+ self::expect(new self::Class::constructor3<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::Null?>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<Null>.constructor3(null).field");
+ self::expect(new self::Class::constructor4<core::int>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::int?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int?>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor4(null).field");
+}
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual} for ${message}";
+}
+
+constants {
+ #C1 = <core::Null?>[]
+ #C2 = true
+ #C3 = false
+ #C4 = self::Class<core::int*> {field:#C3}
+ #C5 = self::Class<core::Null?> {field:#C2}
+ #C6 = self::Class<core::int*> {field:#C2}
+ #C7 = self::Class<core::Null?> {field:#C3}
+}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.transformed.expect
new file mode 100644
index 0000000..525b38f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.weak.transformed.expect
@@ -0,0 +1,92 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ final field core::bool field;
+ const constructor constructor1(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+ ;
+ const constructor constructor2(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T?, super core::Object::•()
+ ;
+ const constructor constructor3(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>, super core::Object::•()
+ ;
+ const constructor constructor4(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>?, super core::Object::•()
+ ;
+}
+static final field core::bool isWeakMode = (#C1) is{ForNonNullableByDefault} core::List<core::Object>;
+static const field core::bool c0 = #C2;
+static const field core::bool c1 = #C3;
+static const field core::bool c2 = #C2;
+static const field core::bool c3 = #C2;
+static const field core::bool c4 = #C3;
+static const field core::bool c5 = #C2;
+static const field core::bool c6 = #C3;
+static const field core::bool c7 = #C2;
+static const field core::bool c8 = #C2;
+static const field core::bool c9 = #C2;
+static const field core::bool c10 = #C3;
+static const field core::bool c11 = #C2;
+static const field core::bool c12 = #C2;
+static const field self::Class<core::int> e1 = #C4;
+static const field self::Class<core::int?> e2 = #C4;
+static const field self::Class<core::Null?> e3 = #C5;
+static const field self::Class<core::int> e4 = #C6;
+static const field self::Class<core::int?> e5 = #C6;
+static const field self::Class<core::Null?> e6 = #C5;
+static const field self::Class<core::int> e7 = #C4;
+static const field self::Class<core::int?> e8 = #C4;
+static const field self::Class<core::Null?> e9 = #C7;
+static const field self::Class<core::int> e10 = #C6;
+static const field self::Class<core::int?> e11 = #C6;
+static const field self::Class<core::Null?> e12 = #C5;
+static method main() → dynamic {
+ self::expect(null is{ForNonNullableByDefault} core::int?, #C2, "null is int?");
+ self::expect(null is{ForNonNullableByDefault} core::int, #C3, "null is int");
+ self::expect(null is{ForNonNullableByDefault} core::Null?, #C2, "null is Null");
+ self::expect(null is{ForNonNullableByDefault} Never?, #C2, "null is Never?");
+ self::expect(null is{ForNonNullableByDefault} Never, #C3, "null is Never");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C2, "null is FutureOr<int?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C3, "null is FutureOr<int>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C2, "null is FutureOr<int>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C2, "null is FutureOr<Null>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C2, "null is FutureOr<Null>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C3, "null is FutureOr<Never>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C2, "null is FutureOr<Never?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C2, "null is FutureOr<Never>?");
+ self::expect(new self::Class::constructor1<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor1(null).field");
+ self::expect(true, new self::Class::constructor1<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor1(null).field");
+ self::expect(!self::isWeakMode, (#C4).{self::Class::field}, "const Class<int?>.constructor1(null).field");
+ self::expect(new self::Class::constructor1<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor1(null).field");
+ self::expect(new self::Class::constructor2<core::int>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor2(null).field");
+ self::expect(true, new self::Class::constructor2<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::int?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor2(null).field");
+ self::expect(new self::Class::constructor3<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::Null?>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<Null>.constructor3(null).field");
+ self::expect(new self::Class::constructor4<core::int>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::int?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int?>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor4(null).field");
+}
+static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual} for ${message}";
+}
+
+constants {
+ #C1 = <core::Null?>[]
+ #C2 = true
+ #C3 = false
+ #C4 = self::Class<core::int*> {field:#C3}
+ #C5 = self::Class<core::Null?> {field:#C2}
+ #C6 = self::Class<core::int*> {field:#C2}
+ #C7 = self::Class<core::Null?> {field:#C3}
+}
diff --git a/pkg/front_end/testcases/nnbd/external_fields.dart.outline.expect b/pkg/front_end/testcases/nnbd/external_fields.dart.outline.expect
index 3cce0af..b475be4 100644
--- a/pkg/front_end/testcases/nnbd/external_fields.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/external_fields.dart.outline.expect
@@ -12,14 +12,17 @@
;
@self::Annotation::•()
external get instanceField() → core::int;
+ @self::Annotation::•()
external set instanceField(core::int #t1) → void;
@self::Annotation::•()
external get finalInstanceField() → core::int;
@self::Annotation::•()
external get covariantInstanceField() → core::num;
+ @self::Annotation::•()
external set covariantInstanceField(covariant core::num #t2) → void;
@self::Annotation::•()
external static get staticField() → core::int;
+ @self::Annotation::•()
external static set staticField(core::int #t3) → void;
@self::Annotation::•()
external static get finalStaticField() → core::int;
@@ -35,14 +38,17 @@
abstract class B extends core::Object /*isMixinDeclaration*/ {
@self::Annotation::•()
external get instanceField() → core::int;
+ @self::Annotation::•()
external set instanceField(core::int #t7) → void;
@self::Annotation::•()
external get finalInstanceField() → core::int;
@self::Annotation::•()
external get covariantInstanceField() → core::num;
+ @self::Annotation::•()
external set covariantInstanceField(covariant core::num #t8) → void;
@self::Annotation::•()
external static get staticField() → core::int;
+ @self::Annotation::•()
external static set staticField(core::int #t9) → void;
@self::Annotation::•()
external static get finalStaticField() → core::int;
@@ -85,6 +91,7 @@
}
@self::Annotation::•()
external static get topLevelField() → core::int;
+@self::Annotation::•()
external static set topLevelField(core::int #t17) → void;
@self::Annotation::•()
external static get finalTopLevelField() → core::int;
@@ -93,11 +100,13 @@
external static get untypedFinalTopLevelField() → dynamic;
@self::Annotation::•()
external static get Extension|extensionInstanceField() → core::int;
+@self::Annotation::•()
external static set Extension|extensionInstanceField(core::int #t19) → void;
@self::Annotation::•()
external static get Extension|finalExtensionInstanceField() → core::int;
@self::Annotation::•()
external static get Extension|extensionStaticField() → core::int;
+@self::Annotation::•()
external static set Extension|extensionStaticField(core::int #t20) → void;
@self::Annotation::•()
external static get Extension|finalExtensionStaticField() → core::int;
diff --git a/pkg/front_end/testcases/nnbd/external_fields.dart.strong.expect b/pkg/front_end/testcases/nnbd/external_fields.dart.strong.expect
index 6c72fc2..8f52a91 100644
--- a/pkg/front_end/testcases/nnbd/external_fields.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/external_fields.dart.strong.expect
@@ -13,14 +13,17 @@
;
@#C1
external get instanceField() → core::int;
+ @#C1
external set instanceField(core::int #t1) → void;
@#C1
external get finalInstanceField() → core::int;
@#C1
external get covariantInstanceField() → core::num;
+ @#C1
external set covariantInstanceField(covariant core::num #t2) → void;
@#C1
external static get staticField() → core::int;
+ @#C1
external static set staticField(core::int #t3) → void;
@#C1
external static get finalStaticField() → core::int;
@@ -36,14 +39,17 @@
abstract class B extends core::Object /*isMixinDeclaration*/ {
@#C1
external get instanceField() → core::int;
+ @#C1
external set instanceField(core::int #t7) → void;
@#C1
external get finalInstanceField() → core::int;
@#C1
external get covariantInstanceField() → core::num;
+ @#C1
external set covariantInstanceField(covariant core::num #t8) → void;
@#C1
external static get staticField() → core::int;
+ @#C1
external static set staticField(core::int #t9) → void;
@#C1
external static get finalStaticField() → core::int;
@@ -87,6 +93,7 @@
}
@#C1
external static get topLevelField() → core::int;
+@#C1
external static set topLevelField(core::int #t17) → void;
@#C1
external static get finalTopLevelField() → core::int;
@@ -95,11 +102,13 @@
external static get untypedFinalTopLevelField() → dynamic;
@#C1
external static get Extension|extensionInstanceField() → core::int;
+@#C1
external static set Extension|extensionInstanceField(core::int #t19) → void;
@#C1
external static get Extension|finalExtensionInstanceField() → core::int;
@#C1
external static get Extension|extensionStaticField() → core::int;
+@#C1
external static set Extension|extensionStaticField(core::int #t20) → void;
@#C1
external static get Extension|finalExtensionStaticField() → core::int;
diff --git a/pkg/front_end/testcases/nnbd/external_fields.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/external_fields.dart.strong.transformed.expect
index 6c72fc2..8f52a91 100644
--- a/pkg/front_end/testcases/nnbd/external_fields.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/external_fields.dart.strong.transformed.expect
@@ -13,14 +13,17 @@
;
@#C1
external get instanceField() → core::int;
+ @#C1
external set instanceField(core::int #t1) → void;
@#C1
external get finalInstanceField() → core::int;
@#C1
external get covariantInstanceField() → core::num;
+ @#C1
external set covariantInstanceField(covariant core::num #t2) → void;
@#C1
external static get staticField() → core::int;
+ @#C1
external static set staticField(core::int #t3) → void;
@#C1
external static get finalStaticField() → core::int;
@@ -36,14 +39,17 @@
abstract class B extends core::Object /*isMixinDeclaration*/ {
@#C1
external get instanceField() → core::int;
+ @#C1
external set instanceField(core::int #t7) → void;
@#C1
external get finalInstanceField() → core::int;
@#C1
external get covariantInstanceField() → core::num;
+ @#C1
external set covariantInstanceField(covariant core::num #t8) → void;
@#C1
external static get staticField() → core::int;
+ @#C1
external static set staticField(core::int #t9) → void;
@#C1
external static get finalStaticField() → core::int;
@@ -87,6 +93,7 @@
}
@#C1
external static get topLevelField() → core::int;
+@#C1
external static set topLevelField(core::int #t17) → void;
@#C1
external static get finalTopLevelField() → core::int;
@@ -95,11 +102,13 @@
external static get untypedFinalTopLevelField() → dynamic;
@#C1
external static get Extension|extensionInstanceField() → core::int;
+@#C1
external static set Extension|extensionInstanceField(core::int #t19) → void;
@#C1
external static get Extension|finalExtensionInstanceField() → core::int;
@#C1
external static get Extension|extensionStaticField() → core::int;
+@#C1
external static set Extension|extensionStaticField(core::int #t20) → void;
@#C1
external static get Extension|finalExtensionStaticField() → core::int;
diff --git a/pkg/front_end/testcases/nnbd/external_fields.dart.weak.expect b/pkg/front_end/testcases/nnbd/external_fields.dart.weak.expect
index 6c72fc2..8f52a91 100644
--- a/pkg/front_end/testcases/nnbd/external_fields.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/external_fields.dart.weak.expect
@@ -13,14 +13,17 @@
;
@#C1
external get instanceField() → core::int;
+ @#C1
external set instanceField(core::int #t1) → void;
@#C1
external get finalInstanceField() → core::int;
@#C1
external get covariantInstanceField() → core::num;
+ @#C1
external set covariantInstanceField(covariant core::num #t2) → void;
@#C1
external static get staticField() → core::int;
+ @#C1
external static set staticField(core::int #t3) → void;
@#C1
external static get finalStaticField() → core::int;
@@ -36,14 +39,17 @@
abstract class B extends core::Object /*isMixinDeclaration*/ {
@#C1
external get instanceField() → core::int;
+ @#C1
external set instanceField(core::int #t7) → void;
@#C1
external get finalInstanceField() → core::int;
@#C1
external get covariantInstanceField() → core::num;
+ @#C1
external set covariantInstanceField(covariant core::num #t8) → void;
@#C1
external static get staticField() → core::int;
+ @#C1
external static set staticField(core::int #t9) → void;
@#C1
external static get finalStaticField() → core::int;
@@ -87,6 +93,7 @@
}
@#C1
external static get topLevelField() → core::int;
+@#C1
external static set topLevelField(core::int #t17) → void;
@#C1
external static get finalTopLevelField() → core::int;
@@ -95,11 +102,13 @@
external static get untypedFinalTopLevelField() → dynamic;
@#C1
external static get Extension|extensionInstanceField() → core::int;
+@#C1
external static set Extension|extensionInstanceField(core::int #t19) → void;
@#C1
external static get Extension|finalExtensionInstanceField() → core::int;
@#C1
external static get Extension|extensionStaticField() → core::int;
+@#C1
external static set Extension|extensionStaticField(core::int #t20) → void;
@#C1
external static get Extension|finalExtensionStaticField() → core::int;
diff --git a/pkg/front_end/testcases/nnbd/external_fields.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/external_fields.dart.weak.transformed.expect
index 6c72fc2..8f52a91 100644
--- a/pkg/front_end/testcases/nnbd/external_fields.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/external_fields.dart.weak.transformed.expect
@@ -13,14 +13,17 @@
;
@#C1
external get instanceField() → core::int;
+ @#C1
external set instanceField(core::int #t1) → void;
@#C1
external get finalInstanceField() → core::int;
@#C1
external get covariantInstanceField() → core::num;
+ @#C1
external set covariantInstanceField(covariant core::num #t2) → void;
@#C1
external static get staticField() → core::int;
+ @#C1
external static set staticField(core::int #t3) → void;
@#C1
external static get finalStaticField() → core::int;
@@ -36,14 +39,17 @@
abstract class B extends core::Object /*isMixinDeclaration*/ {
@#C1
external get instanceField() → core::int;
+ @#C1
external set instanceField(core::int #t7) → void;
@#C1
external get finalInstanceField() → core::int;
@#C1
external get covariantInstanceField() → core::num;
+ @#C1
external set covariantInstanceField(covariant core::num #t8) → void;
@#C1
external static get staticField() → core::int;
+ @#C1
external static set staticField(core::int #t9) → void;
@#C1
external static get finalStaticField() → core::int;
@@ -87,6 +93,7 @@
}
@#C1
external static get topLevelField() → core::int;
+@#C1
external static set topLevelField(core::int #t17) → void;
@#C1
external static get finalTopLevelField() → core::int;
@@ -95,11 +102,13 @@
external static get untypedFinalTopLevelField() → dynamic;
@#C1
external static get Extension|extensionInstanceField() → core::int;
+@#C1
external static set Extension|extensionInstanceField(core::int #t19) → void;
@#C1
external static get Extension|finalExtensionInstanceField() → core::int;
@#C1
external static get Extension|extensionStaticField() → core::int;
+@#C1
external static set Extension|extensionStaticField(core::int #t20) → void;
@#C1
external static get Extension|finalExtensionStaticField() → core::int;
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
index 2872aa5..b470efa 100644
--- a/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/forin.dart.strong.transformed.expect
@@ -56,112 +56,112 @@
core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:9:17: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'Iterable' is from 'dart:core'.
for (int x in i2) x;
- ^" in i2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+ ^" in let core::Iterable<core::int>? #t2 = i2 in #t2.==(null) ?{core::Iterable<dynamic>} #t2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t2{core::Iterable<dynamic>}).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
x;
}
}
block {
- final core::List<core::int> #t2 = <core::int>[];
+ final core::List<core::int> #t3 = <core::int>[];
{
- core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:10:18: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+ core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:10:18: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'Iterable' is from 'dart:core'.
[for (int x in i2) x];
- ^" in i2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+ ^" in let core::Iterable<core::int>? #t5 = i2 in #t5.==(null) ?{core::Iterable<dynamic>} #t5 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t5{core::Iterable<dynamic>}).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
- #t2.{core::List::add}(x);
+ #t3.{core::List::add}(x);
}
}
- } =>#t2;
+ } =>#t3;
{
- core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:12:17: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+ core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:12:17: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'List' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
for (int x in l2) x;
- ^" in l2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+ ^" in let core::List<core::int>? #t7 = l2 in #t7.==(null) ?{core::Iterable<dynamic>} #t7 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t7{core::Iterable<dynamic>}).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
x;
}
}
block {
- final core::List<core::int> #t5 = <core::int>[];
+ final core::List<core::int> #t8 = <core::int>[];
{
- core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:13:18: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+ core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:13:18: Error: The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'List' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
[for (int x in l2) x];
- ^" in l2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+ ^" in let core::List<core::int>? #t10 = l2 in #t10.==(null) ?{core::Iterable<dynamic>} #t10 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic> : #t10{core::Iterable<dynamic>}).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
- #t5.{core::List::add}(x);
+ #t8.{core::List::add}(x);
}
}
- } =>#t5;
+ } =>#t8;
{
- core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:15:17: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+ core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:15:17: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'Object' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
for (int x in o1) x;
^" in o1 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final dynamic #t8 = :sync-for-iterator.{core::Iterator::current};
+ final dynamic #t12 = :sync-for-iterator.{core::Iterator::current};
{
- core::int x = #t8 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+ core::int x = #t12 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
x;
}
}
}
block {
- final core::List<core::int> #t9 = <core::int>[];
+ final core::List<core::int> #t13 = <core::int>[];
{
- core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:16:18: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
+ core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:16:18: Error: The type 'Object' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'Object' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
[for (int x in o1) x];
^" in o1 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final dynamic #t11 = :sync-for-iterator.{core::Iterator::current};
+ final dynamic #t15 = :sync-for-iterator.{core::Iterator::current};
{
- core::int x = #t11 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
- #t9.{core::List::add}(x);
+ core::int x = #t15 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+ #t13.{core::List::add}(x);
}
}
}
- } =>#t9;
+ } =>#t13;
{
- core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:18:17: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+ core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:18:17: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'Object' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
for (int x in o2) x;
^" in o2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final dynamic #t13 = :sync-for-iterator.{core::Iterator::current};
+ final dynamic #t17 = :sync-for-iterator.{core::Iterator::current};
{
- core::int x = #t13 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+ core::int x = #t17 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
x;
}
}
}
block {
- final core::List<core::int> #t14 = <core::int>[];
+ final core::List<core::int> #t18 = <core::int>[];
{
- core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:19:18: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
+ core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:19:18: Error: The type 'Object?' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'Object' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
[for (int x in o2) x];
^" in o2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final dynamic #t16 = :sync-for-iterator.{core::Iterator::current};
+ final dynamic #t20 = :sync-for-iterator.{core::Iterator::current};
{
- core::int x = #t16 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
- #t14.{core::List::add}(x);
+ core::int x = #t20 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+ #t18.{core::List::add}(x);
}
}
}
- } =>#t14;
+ } =>#t18;
}
static method ok(core::Iterable<core::int> i1, core::List<core::int> l1, dynamic d) → dynamic {
{
@@ -172,15 +172,15 @@
}
}
block {
- final core::List<core::int> #t17 = <core::int>[];
+ final core::List<core::int> #t21 = <core::int>[];
{
core::Iterator<core::int> :sync-for-iterator = i1.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
- #t17.{core::List::add}(x);
+ #t21.{core::List::add}(x);
}
}
- } =>#t17;
+ } =>#t21;
{
core::Iterator<core::int> :sync-for-iterator = l1.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
@@ -189,37 +189,37 @@
}
}
block {
- final core::List<core::int> #t18 = <core::int>[];
+ final core::List<core::int> #t22 = <core::int>[];
{
core::Iterator<core::int> :sync-for-iterator = l1.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
- #t18.{core::List::add}(x);
+ #t22.{core::List::add}(x);
}
}
- } =>#t18;
+ } =>#t22;
{
core::Iterator<dynamic> :sync-for-iterator = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final dynamic #t19 = :sync-for-iterator.{core::Iterator::current};
+ final dynamic #t23 = :sync-for-iterator.{core::Iterator::current};
{
- core::int x = #t19 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+ core::int x = #t23 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
x;
}
}
}
block {
- final core::List<core::int> #t20 = <core::int>[];
+ final core::List<core::int> #t24 = <core::int>[];
{
core::Iterator<dynamic> :sync-for-iterator = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final dynamic #t21 = :sync-for-iterator.{core::Iterator::current};
+ final dynamic #t25 = :sync-for-iterator.{core::Iterator::current};
{
- core::int x = #t21 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
- #t20.{core::List::add}(x);
+ core::int x = #t25 as{TypeError,ForDynamic,ForNonNullableByDefault} core::int;
+ #t24.{core::List::add}(x);
}
}
}
- } =>#t20;
+ } =>#t24;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/forin.dart.weak.transformed.expect
index 2872aa5..3882876 100644
--- a/pkg/front_end/testcases/nnbd/forin.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/forin.dart.weak.transformed.expect
@@ -56,7 +56,7 @@
core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:9:17: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'Iterable' is from 'dart:core'.
for (int x in i2) x;
- ^" in i2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+ ^" in i2).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
x;
@@ -68,7 +68,7 @@
core::Iterator<dynamic> :sync-for-iterator = (let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/forin.dart:10:18: Error: The type 'Iterable<int>?' used in the 'for' loop must implement 'Iterable<dynamic>'.
- 'Iterable' is from 'dart:core'.
[for (int x in i2) x];
- ^" in i2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+ ^" in i2).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
#t2.{core::List::add}(x);
@@ -80,7 +80,7 @@
- 'List' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
for (int x in l2) x;
- ^" in l2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+ ^" in l2).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
x;
@@ -93,7 +93,7 @@
- 'List' is from 'dart:core'.
- 'Iterable' is from 'dart:core'.
[for (int x in l2) x];
- ^" in l2 as{TypeError,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator};
+ ^" in l2).{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
core::int x = :sync-for-iterator.{core::Iterator::current};
#t5.{core::List::add}(x);
diff --git a/pkg/front_end/testcases/nnbd/issue40600.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue40600.dart.strong.transformed.expect
index df7df7b..fc3b7ae 100644
--- a/pkg/front_end/testcases/nnbd/issue40600.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue40600.dart.strong.transformed.expect
@@ -18,7 +18,7 @@
;
method foo([generic-covariant-impl asy::FutureOr<self::A::X%>? x = #C1]) → dynamic {
if(x is{ForNonNullableByDefault} asy::Future<self::A::X%>) {
- this.{self::A::b}.{self::B::bar}(x{asy::Future<self::A::X%>} as{ForNonNullableByDefault} asy::FutureOr<self::A::X%>);
+ this.{self::A::b}.{self::B::bar}(x{asy::Future<self::A::X%>});
}
}
}
diff --git a/pkg/front_end/testcases/nnbd/issue40600.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue40600.dart.weak.transformed.expect
index df7df7b..fc3b7ae 100644
--- a/pkg/front_end/testcases/nnbd/issue40600.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue40600.dart.weak.transformed.expect
@@ -18,7 +18,7 @@
;
method foo([generic-covariant-impl asy::FutureOr<self::A::X%>? x = #C1]) → dynamic {
if(x is{ForNonNullableByDefault} asy::Future<self::A::X%>) {
- this.{self::A::b}.{self::B::bar}(x{asy::Future<self::A::X%>} as{ForNonNullableByDefault} asy::FutureOr<self::A::X%>);
+ this.{self::A::b}.{self::B::bar}(x{asy::Future<self::A::X%>});
}
}
}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
index df8f463..673da56 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
@@ -122,7 +122,7 @@
^" in self::s13.call();
static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
final s15 = throw null;
- ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
+ ^";
static method main() → void {}
constants {
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
index df8f463..673da56 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
@@ -122,7 +122,7 @@
^" in self::s13.call();
static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
final s15 = throw null;
- ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
+ ^";
static method main() → void {}
constants {
diff --git a/pkg/front_end/testcases/nnbd/issue41657.dart b/pkg/front_end/testcases/nnbd/issue41657.dart
new file mode 100644
index 0000000..49d994e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41657.dart
@@ -0,0 +1,21 @@
+// 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.
+
+final isLegacySubtyping1a = <Null>[] is List<int>;
+const isLegacySubtyping1b = <Null>[] is List<int>;
+final isLegacySubtyping2a = <int?>[] is List<int>;
+const isLegacySubtyping2b = <int?>[] is List<int>;
+//final assertLegacySubtyping2 = <Null>[] as List<int>;
+const assertLegacySubtyping1 = <Null>[] as List<int>;
+//final assertLegacySubtyping2 = <int?>[] as List<int>;
+const assertLegacySubtyping2 = <int?>[] as List<int>;
+
+void main() {
+ expect(isLegacySubtyping1a, isLegacySubtyping1b);
+ expect(isLegacySubtyping2a, isLegacySubtyping2b);
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw "Expected $expected, actual $actual";
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41657.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41657.dart.outline.expect
new file mode 100644
index 0000000..a9091d4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41657.dart.outline.expect
@@ -0,0 +1,14 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static final field core::bool isLegacySubtyping1a;
+static const field core::bool isLegacySubtyping1b = const <core::Null?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static final field core::bool isLegacySubtyping2a;
+static const field core::bool isLegacySubtyping2b = const <core::int?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::List<core::int> assertLegacySubtyping1 = const <core::Null?>[] as{ForNonNullableByDefault} core::List<core::int>;
+static const field core::List<core::int> assertLegacySubtyping2 = const <core::int?>[] as{ForNonNullableByDefault} core::List<core::int>;
+static method main() → void
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41657.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41657.dart.strong.expect
new file mode 100644
index 0000000..f69417a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41657.dart.strong.expect
@@ -0,0 +1,49 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/issue41657.dart:10:41: Error: Constant evaluation error:
+// const assertLegacySubtyping1 = <Null>[] as List<int>;
+// ^
+// pkg/front_end/testcases/nnbd/issue41657.dart:10:41: Context: Expected constant '<Null>[]' to be of type 'List<int>', but was of type 'List<Null>'.
+// - 'List' is from 'dart:core'.
+// const assertLegacySubtyping1 = <Null>[] as List<int>;
+// ^
+// pkg/front_end/testcases/nnbd/issue41657.dart:10:7: Context: While analyzing:
+// const assertLegacySubtyping1 = <Null>[] as List<int>;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41657.dart:12:41: Error: Constant evaluation error:
+// const assertLegacySubtyping2 = <int?>[] as List<int>;
+// ^
+// pkg/front_end/testcases/nnbd/issue41657.dart:12:41: Context: Expected constant '<int?>[]' to be of type 'List<int>', but was of type 'List<int?>'.
+// - 'List' is from 'dart:core'.
+// const assertLegacySubtyping2 = <int?>[] as List<int>;
+// ^
+// pkg/front_end/testcases/nnbd/issue41657.dart:12:7: Context: While analyzing:
+// const assertLegacySubtyping2 = <int?>[] as List<int>;
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static final field core::bool isLegacySubtyping1a = <core::Null?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping1b = #C1;
+static final field core::bool isLegacySubtyping2a = <core::int?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping2b = #C1;
+static const field core::List<core::int> assertLegacySubtyping1 = invalid-expression "Expected constant '<Null>[]' to be of type 'List<int>', but was of type 'List<Null>'.
+ - 'List' is from 'dart:core'.";
+static const field core::List<core::int> assertLegacySubtyping2 = invalid-expression "Expected constant '<int?>[]' to be of type 'List<int>', but was of type 'List<int?>'.
+ - 'List' is from 'dart:core'.";
+static method main() → void {
+ self::expect(self::isLegacySubtyping1a, #C1);
+ self::expect(self::isLegacySubtyping2a, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41657.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41657.dart.strong.transformed.expect
new file mode 100644
index 0000000..f69417a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41657.dart.strong.transformed.expect
@@ -0,0 +1,49 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/nnbd/issue41657.dart:10:41: Error: Constant evaluation error:
+// const assertLegacySubtyping1 = <Null>[] as List<int>;
+// ^
+// pkg/front_end/testcases/nnbd/issue41657.dart:10:41: Context: Expected constant '<Null>[]' to be of type 'List<int>', but was of type 'List<Null>'.
+// - 'List' is from 'dart:core'.
+// const assertLegacySubtyping1 = <Null>[] as List<int>;
+// ^
+// pkg/front_end/testcases/nnbd/issue41657.dart:10:7: Context: While analyzing:
+// const assertLegacySubtyping1 = <Null>[] as List<int>;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41657.dart:12:41: Error: Constant evaluation error:
+// const assertLegacySubtyping2 = <int?>[] as List<int>;
+// ^
+// pkg/front_end/testcases/nnbd/issue41657.dart:12:41: Context: Expected constant '<int?>[]' to be of type 'List<int>', but was of type 'List<int?>'.
+// - 'List' is from 'dart:core'.
+// const assertLegacySubtyping2 = <int?>[] as List<int>;
+// ^
+// pkg/front_end/testcases/nnbd/issue41657.dart:12:7: Context: While analyzing:
+// const assertLegacySubtyping2 = <int?>[] as List<int>;
+// ^
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static final field core::bool isLegacySubtyping1a = <core::Null?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping1b = #C1;
+static final field core::bool isLegacySubtyping2a = <core::int?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping2b = #C1;
+static const field core::List<core::int> assertLegacySubtyping1 = invalid-expression "Expected constant '<Null>[]' to be of type 'List<int>', but was of type 'List<Null>'.
+ - 'List' is from 'dart:core'.";
+static const field core::List<core::int> assertLegacySubtyping2 = invalid-expression "Expected constant '<int?>[]' to be of type 'List<int>', but was of type 'List<int?>'.
+ - 'List' is from 'dart:core'.";
+static method main() → void {
+ self::expect(self::isLegacySubtyping1a, #C1);
+ self::expect(self::isLegacySubtyping2a, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41657.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41657.dart.textual_outline.expect
new file mode 100644
index 0000000..5a0dff1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41657.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+final isLegacySubtyping1a = <Null>[] is List<int>;
+const isLegacySubtyping1b = <Null>[] is List<int>;
+final isLegacySubtyping2a = <int?>[] is List<int>;
+const isLegacySubtyping2b = <int?>[] is List<int>;
+const assertLegacySubtyping1 = <Null>[] as List<int>;
+const assertLegacySubtyping2 = <int?>[] as List<int>;
+void main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41657.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41657.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1cb1b49
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41657.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+const assertLegacySubtyping1 = <Null>[] as List<int>;
+const assertLegacySubtyping2 = <int?>[] as List<int>;
+const isLegacySubtyping1b = <Null>[] is List<int>;
+const isLegacySubtyping2b = <int?>[] is List<int>;
+expect(expected, actual) {}
+final isLegacySubtyping1a = <Null>[] is List<int>;
+final isLegacySubtyping2a = <int?>[] is List<int>;
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41657.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41657.dart.weak.expect
new file mode 100644
index 0000000..2a7e74f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41657.dart.weak.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static final field core::bool isLegacySubtyping1a = <core::Null?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping1b = #C1;
+static final field core::bool isLegacySubtyping2a = <core::int?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping2b = #C1;
+static const field core::List<core::int> assertLegacySubtyping1 = #C2;
+static const field core::List<core::int> assertLegacySubtyping2 = #C3;
+static method main() → void {
+ self::expect(self::isLegacySubtyping1a, #C1);
+ self::expect(self::isLegacySubtyping2a, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = true
+ #C2 = <core::Null?>[]
+ #C3 = <core::int*>[]
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41657.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41657.dart.weak.transformed.expect
new file mode 100644
index 0000000..2a7e74f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41657.dart.weak.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static final field core::bool isLegacySubtyping1a = <core::Null?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping1b = #C1;
+static final field core::bool isLegacySubtyping2a = <core::int?>[] is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping2b = #C1;
+static const field core::List<core::int> assertLegacySubtyping1 = #C2;
+static const field core::List<core::int> assertLegacySubtyping2 = #C3;
+static method main() → void {
+ self::expect(self::isLegacySubtyping1a, #C1);
+ self::expect(self::isLegacySubtyping2a, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = true
+ #C2 = <core::Null?>[]
+ #C3 = <core::int*>[]
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
index 79e8633..93245c26 100644
--- a/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
@@ -33,7 +33,7 @@
- 'Null/*1*/' is from 'dart:core'.
- 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
Null x = null;
- ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+ ^" in let core::Null? #t2 = null in #t2.==(null) ?{self::Null} #t2 as{TypeError,ForNonNullableByDefault} self::Null : #t2{self::Null};
invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
- 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect
index 79e8633..69120e0 100644
--- a/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect
@@ -33,7 +33,7 @@
- 'Null/*1*/' is from 'dart:core'.
- 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
Null x = null;
- ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+ ^" in null;
invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
- 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
index dabee80..8763bcb 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
@@ -193,7 +193,7 @@
function #s1#initializer() → core::String
return invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
late String s1 = await hest();
- ^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+ ^^^^^";
late core::String s1 = #s1#initializer.call();
function #s2#initializer() → core::String
return "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
index dabee80..8763bcb 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
@@ -193,7 +193,7 @@
function #s1#initializer() → core::String
return invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
late String s1 = await hest();
- ^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
+ ^^^^^";
late core::String s1 = #s1#initializer.call();
function #s2#initializer() → core::String
return "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
diff --git a/pkg/front_end/testcases/nnbd/never_calls.dart b/pkg/front_end/testcases/nnbd/never_calls.dart
new file mode 100644
index 0000000..3cf3cf4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_calls.dart
@@ -0,0 +1,39 @@
+// 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.
+
+propertyGet(Never never) {
+ var v1 = never.foo;
+ var v2 = never.hashCode;
+ var v3 = never.runtimeType;
+ var v4 = never.toString;
+ var v5 = never.noSuchMethod;
+}
+
+propertySet(Never never) {
+ var v1 = never.foo = 42;
+}
+
+methodInvocation(Never never, Invocation invocation) {
+ var v1 = never.foo();
+ var v2 = never.hashCode();
+ var v3 = never.runtimeType();
+ var v4 = never.toString();
+ var v5 = never.toString(foo: 42);
+ var v6 = never.noSuchMethod(invocation);
+ var v7 = never.noSuchMethod(42);
+}
+
+equals(Never never) {
+ var v1 = never == null;
+ var v2 = never == never;
+}
+
+operator(Never never) {
+ var v1 = never + never;
+ var v2 = -never;
+ var v3 = never[never];
+ var v4 = never[never] = never;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_calls.dart.outline.expect b/pkg/front_end/testcases/nnbd/never_calls.dart.outline.expect
new file mode 100644
index 0000000..54f9124
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_calls.dart.outline.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method propertyGet(Never never) → dynamic
+ ;
+static method propertySet(Never never) → dynamic
+ ;
+static method methodInvocation(Never never, core::Invocation invocation) → dynamic
+ ;
+static method equals(Never never) → dynamic
+ ;
+static method operator(Never never) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/never_calls.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_calls.dart.strong.expect
new file mode 100644
index 0000000..33ac05b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_calls.dart.strong.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method propertyGet(Never never) → dynamic {
+ Never v1 = never.foo;
+ Never v2 = never.hashCode;
+ Never v3 = never.runtimeType;
+ Never v4 = never.toString;
+ Never v5 = never.noSuchMethod;
+}
+static method propertySet(Never never) → dynamic {
+ core::int v1 = never.foo = 42;
+}
+static method methodInvocation(Never never, core::Invocation invocation) → dynamic {
+ Never v1 = never.foo();
+ Never v2 = never.hashCode();
+ Never v3 = never.runtimeType();
+ Never v4 = never.toString();
+ Never v5 = never.toString(foo: 42);
+ Never v6 = never.noSuchMethod(invocation);
+ Never v7 = never.noSuchMethod(42);
+}
+static method equals(Never never) → dynamic {
+ Never v1 = never.==(null);
+ Never v2 = never.==(never);
+}
+static method operator(Never never) → dynamic {
+ Never v1 = never.+(never);
+ Never v2 = never.unary-();
+ Never v3 = never.[](never);
+ Never v4 = let final Never #t1 = never in let final Never #t2 = never in let final Never #t3 = never in let final void #t4 = #t1.[]=(#t2, #t3) in #t3;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/never_calls.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/never_calls.dart.strong.transformed.expect
new file mode 100644
index 0000000..33ac05b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_calls.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method propertyGet(Never never) → dynamic {
+ Never v1 = never.foo;
+ Never v2 = never.hashCode;
+ Never v3 = never.runtimeType;
+ Never v4 = never.toString;
+ Never v5 = never.noSuchMethod;
+}
+static method propertySet(Never never) → dynamic {
+ core::int v1 = never.foo = 42;
+}
+static method methodInvocation(Never never, core::Invocation invocation) → dynamic {
+ Never v1 = never.foo();
+ Never v2 = never.hashCode();
+ Never v3 = never.runtimeType();
+ Never v4 = never.toString();
+ Never v5 = never.toString(foo: 42);
+ Never v6 = never.noSuchMethod(invocation);
+ Never v7 = never.noSuchMethod(42);
+}
+static method equals(Never never) → dynamic {
+ Never v1 = never.==(null);
+ Never v2 = never.==(never);
+}
+static method operator(Never never) → dynamic {
+ Never v1 = never.+(never);
+ Never v2 = never.unary-();
+ Never v3 = never.[](never);
+ Never v4 = let final Never #t1 = never in let final Never #t2 = never in let final Never #t3 = never in let final void #t4 = #t1.[]=(#t2, #t3) in #t3;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/never_calls.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_calls.dart.weak.expect
new file mode 100644
index 0000000..33ac05b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_calls.dart.weak.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method propertyGet(Never never) → dynamic {
+ Never v1 = never.foo;
+ Never v2 = never.hashCode;
+ Never v3 = never.runtimeType;
+ Never v4 = never.toString;
+ Never v5 = never.noSuchMethod;
+}
+static method propertySet(Never never) → dynamic {
+ core::int v1 = never.foo = 42;
+}
+static method methodInvocation(Never never, core::Invocation invocation) → dynamic {
+ Never v1 = never.foo();
+ Never v2 = never.hashCode();
+ Never v3 = never.runtimeType();
+ Never v4 = never.toString();
+ Never v5 = never.toString(foo: 42);
+ Never v6 = never.noSuchMethod(invocation);
+ Never v7 = never.noSuchMethod(42);
+}
+static method equals(Never never) → dynamic {
+ Never v1 = never.==(null);
+ Never v2 = never.==(never);
+}
+static method operator(Never never) → dynamic {
+ Never v1 = never.+(never);
+ Never v2 = never.unary-();
+ Never v3 = never.[](never);
+ Never v4 = let final Never #t1 = never in let final Never #t2 = never in let final Never #t3 = never in let final void #t4 = #t1.[]=(#t2, #t3) in #t3;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/never_calls.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_calls.dart.weak.transformed.expect
new file mode 100644
index 0000000..33ac05b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_calls.dart.weak.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method propertyGet(Never never) → dynamic {
+ Never v1 = never.foo;
+ Never v2 = never.hashCode;
+ Never v3 = never.runtimeType;
+ Never v4 = never.toString;
+ Never v5 = never.noSuchMethod;
+}
+static method propertySet(Never never) → dynamic {
+ core::int v1 = never.foo = 42;
+}
+static method methodInvocation(Never never, core::Invocation invocation) → dynamic {
+ Never v1 = never.foo();
+ Never v2 = never.hashCode();
+ Never v3 = never.runtimeType();
+ Never v4 = never.toString();
+ Never v5 = never.toString(foo: 42);
+ Never v6 = never.noSuchMethod(invocation);
+ Never v7 = never.noSuchMethod(42);
+}
+static method equals(Never never) → dynamic {
+ Never v1 = never.==(null);
+ Never v2 = never.==(never);
+}
+static method operator(Never never) → dynamic {
+ Never v1 = never.+(never);
+ Never v2 = never.unary-();
+ Never v3 = never.[](never);
+ Never v4 = let final Never #t1 = never in let final Never #t2 = never in let final Never #t3 = never in let final void #t4 = #t1.[]=(#t2, #t3) in #t3;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/never_equals.dart b/pkg/front_end/testcases/nnbd/never_equals.dart
new file mode 100644
index 0000000..61d8a68
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_equals.dart
@@ -0,0 +1,10 @@
+// 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.
+
+test(Never nonNullableNever, Never? nullableNever) {
+ var v1 = nonNullableNever == nonNullableNever;
+ var v2 = nullableNever == nullableNever;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_equals.dart.outline.expect b/pkg/front_end/testcases/nnbd/never_equals.dart.outline.expect
new file mode 100644
index 0000000..501c05d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_equals.dart.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method test(Never nonNullableNever, Never? nullableNever) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/never_equals.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_equals.dart.strong.expect
new file mode 100644
index 0000000..eafd607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_equals.dart.strong.expect
@@ -0,0 +1,9 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test(Never nonNullableNever, Never? nullableNever) → dynamic {
+ Never v1 = nonNullableNever.==(nonNullableNever);
+ core::bool v2 = nullableNever.{core::Object::==}(nullableNever);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/never_equals.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/never_equals.dart.strong.transformed.expect
new file mode 100644
index 0000000..eafd607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_equals.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test(Never nonNullableNever, Never? nullableNever) → dynamic {
+ Never v1 = nonNullableNever.==(nonNullableNever);
+ core::bool v2 = nullableNever.{core::Object::==}(nullableNever);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/never_equals.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_equals.dart.weak.expect
new file mode 100644
index 0000000..eafd607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_equals.dart.weak.expect
@@ -0,0 +1,9 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test(Never nonNullableNever, Never? nullableNever) → dynamic {
+ Never v1 = nonNullableNever.==(nonNullableNever);
+ core::bool v2 = nullableNever.{core::Object::==}(nullableNever);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/never_equals.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_equals.dart.weak.transformed.expect
new file mode 100644
index 0000000..eafd607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_equals.dart.weak.transformed.expect
@@ -0,0 +1,9 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method test(Never nonNullableNever, Never? nullableNever) → dynamic {
+ Never v1 = nonNullableNever.==(nonNullableNever);
+ core::bool v2 = nullableNever.{core::Object::==}(nullableNever);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
index 40260d9..1eb7ae3 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
@@ -106,11 +106,11 @@
y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y++; // Error.
- ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ ^";
y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y += 1; // Error.
- ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ ^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
y[42]; // Error.
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
index 40260d9..1eb7ae3 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
@@ -106,11 +106,11 @@
y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:34:4: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y++; // Error.
- ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ ^";
y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:35:5: Error: The operator '+' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '+' operator.
y += 1; // Error.
- ^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
+ ^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:36:4: Error: The operator '[]' isn't defined for the class 'Never'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
y[42]; // Error.
diff --git a/pkg/front_end/testcases/nnbd/redundant_type_casts.dart b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart
new file mode 100644
index 0000000..cb53291
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart
@@ -0,0 +1,10 @@
+// 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.
+
+class A<T> {
+ T? _current;
+ T get current => _current as T;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.outline.expect b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.outline.expect
new file mode 100644
index 0000000..82c894b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ generic-covariant-impl field self::A::T? _current;
+ synthetic constructor •() → self::A<self::A::T%>
+ ;
+ get current() → self::A::T%
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.expect b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.expect
new file mode 100644
index 0000000..255b675
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ generic-covariant-impl field self::A::T? _current = null;
+ synthetic constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ get current() → self::A::T%
+ return this.{self::A::_current} as{ForNonNullableByDefault} self::A::T%;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.transformed.expect
new file mode 100644
index 0000000..fbff745
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ generic-covariant-impl field self::A::T? _current = null;
+ synthetic constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ get current() → self::A::T%
+ return let self::A::T? #t1 = this.{self::A::_current} in #t1.==(null) ?{self::A::T%} #t1 as{ForNonNullableByDefault} self::A::T% : #t1{self::A::T%};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.weak.expect b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.weak.expect
new file mode 100644
index 0000000..255b675
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.weak.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ generic-covariant-impl field self::A::T? _current = null;
+ synthetic constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ get current() → self::A::T%
+ return this.{self::A::_current} as{ForNonNullableByDefault} self::A::T%;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.weak.transformed.expect
new file mode 100644
index 0000000..4c4e247
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/redundant_type_casts.dart.weak.transformed.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ generic-covariant-impl field self::A::T? _current = null;
+ synthetic constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ get current() → self::A::T%
+ return this.{self::A::_current};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index 502b2b9..10abd90 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -84,16 +84,16 @@
core::print("foo");
return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} core::String;
+ ^" in let core::Null? #t3 = null in #t3.==(null) ?{core::String} #t3 as{TypeError,ForNonNullableByDefault} core::String : #t3{core::String};
}
static method returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} core::String;
+ ^" in let core::Null? #t5 = null in #t5.==(null) ?{core::String} #t5 as{TypeError,ForNonNullableByDefault} core::String : #t5{core::String};
}
- return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:16:8: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:16:8: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnMixed(bool b) /*error*/ {
^" in null;
}
@@ -157,7 +157,7 @@
try {
#L3:
{
- :return_value = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:27:15: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
+ :return_value = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:27:15: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
FutureOr<int> returnAsync3() async {} // error
^" in null;
break #L3;
@@ -337,7 +337,7 @@
default:
{}
}
- return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
@@ -345,24 +345,24 @@
static method localFunctions() → dynamic {
function returnImplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnImplicit() /* error */ {
^" in null;
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} core::String;
+ ^" in let core::Null? #t11 = null in #t11.==(null) ?{core::String} #t11 as{TypeError,ForNonNullableByDefault} core::String : #t11{core::String};
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} core::String;
+ ^" in let core::Null? #t13 = null in #t13.==(null) ?{core::String} #t13 as{TypeError,ForNonNullableByDefault} core::String : #t13{core::String};
}
- return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnMixed(bool b) /* error */ {
^" in null;
}
@@ -426,7 +426,7 @@
try {
#L15:
{
- :return_value = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
+ :return_value = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
FutureOr<int> returnAsync3() async {} // error
^" in null;
break #L15;
@@ -606,7 +606,7 @@
default:
{}
}
- return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
@@ -615,7 +615,7 @@
core::int local1 = (() → core::int {
if(b)
return 0;
- return let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:117:16: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
+ return let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:117:16: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
var local1 = () /* error */ {
^" in null;
}).call();
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
index d39e1d5..418e161 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
@@ -84,14 +84,14 @@
core::print("foo");
return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} core::String;
+ ^" in null;
}
static method returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} core::String;
+ ^" in null;
}
return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:16:8: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnMixed(bool b) /*error*/ {
@@ -353,14 +353,14 @@
core::print("foo");
return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} core::String;
+ ^" in null;
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} core::String;
+ ^" in null;
}
return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnMixed(bool b) /* error */ {
diff --git a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.strong.transformed.expect
index 19bd0eb..32d138d 100644
--- a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.strong.transformed.expect
@@ -57,36 +57,36 @@
static method foo<T extends self::C? = self::C?>(self::C? c, self::foo::T% t, self::foo::T? nt) → dynamic {
self::functionContext(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:14:24: Error: Can't tear off method 'call' from a potentially null value.
functionContext(null as C?); // Error.
- ^" in (null as{ForNonNullableByDefault} self::C?) as{TypeError} () → core::int);
- self::nullableFunctionContext(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:15:32: Error: Can't tear off method 'call' from a potentially null value.
+ ^" in let core::Null? #t2 = null in #t2.==(null) ?{() → core::int} #t2 as{TypeError} () → core::int : #t2{() → core::int});
+ self::nullableFunctionContext(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:15:32: Error: Can't tear off method 'call' from a potentially null value.
nullableFunctionContext(null as C?); // Error.
- ^" in (null as{ForNonNullableByDefault} self::C?) as{TypeError} () →? core::int);
- self::functionContext(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:16:19: Error: Can't tear off method 'call' from a potentially null value.
+ ^" in null);
+ self::functionContext(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:16:19: Error: Can't tear off method 'call' from a potentially null value.
functionContext(c); // Error.
^" in c as{TypeError} () → core::int);
- self::nullableFunctionContext(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:17:27: Error: Can't tear off method 'call' from a potentially null value.
+ self::nullableFunctionContext(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:17:27: Error: Can't tear off method 'call' from a potentially null value.
nullableFunctionContext(c); // Error.
^" in c as{TypeError} () →? core::int);
- self::functionContext(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:18:19: Error: The argument type 'T' can't be assigned to the parameter type 'int Function()'.
+ self::functionContext(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:18:19: Error: The argument type 'T' can't be assigned to the parameter type 'int Function()'.
functionContext(t); // Error.
^" in t as{TypeError,ForNonNullableByDefault} () → core::int);
- self::nullableFunctionContext(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:19:27: Error: The argument type 'T' can't be assigned to the parameter type 'int Function()?'.
+ self::nullableFunctionContext(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:19:27: Error: The argument type 'T' can't be assigned to the parameter type 'int Function()?'.
nullableFunctionContext(t); // Error.
^" in t as{TypeError,ForNonNullableByDefault} () →? core::int);
- self::functionContext(let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:20:19: Error: The argument type 'T?' can't be assigned to the parameter type 'int Function()'.
+ self::functionContext(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:20:19: Error: The argument type 'T?' can't be assigned to the parameter type 'int Function()'.
functionContext(nt); // Error.
^" in nt as{TypeError,ForNonNullableByDefault} () → core::int);
- self::nullableFunctionContext(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:21:27: Error: The argument type 'T?' can't be assigned to the parameter type 'int Function()?'.
+ self::nullableFunctionContext(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:21:27: Error: The argument type 'T?' can't be assigned to the parameter type 'int Function()?'.
nullableFunctionContext(nt); // Error.
^" in nt as{TypeError,ForNonNullableByDefault} () →? core::int);
}
static method bar<T extends self::C = self::C>(self::C c, self::bar::T t) → dynamic {
- self::functionContext(let final self::C #t9 = c in #t9.==(null) ?{() → core::int} null : #t9.{self::C::call});
- self::nullableFunctionContext(let final self::C #t10 = c in #t10.==(null) ?{() → core::int} null : #t10.{self::C::call});
- self::functionContext(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:27:19: Error: The argument type 'T' can't be assigned to the parameter type 'int Function()'.
+ self::functionContext(let final self::C #t10 = c in #t10.==(null) ?{() → core::int} null : #t10.{self::C::call});
+ self::nullableFunctionContext(let final self::C #t11 = c in #t11.==(null) ?{() → core::int} null : #t11.{self::C::call});
+ self::functionContext(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:27:19: Error: The argument type 'T' can't be assigned to the parameter type 'int Function()'.
functionContext(t); // Shouldn't result in a compile-time error.
^" in t as{TypeError,ForNonNullableByDefault} () → core::int);
- self::nullableFunctionContext(let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:28:27: Error: The argument type 'T' can't be assigned to the parameter type 'int Function()?'.
+ self::nullableFunctionContext(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:28:27: Error: The argument type 'T' can't be assigned to the parameter type 'int Function()?'.
nullableFunctionContext(t); // Shouldn't result in a compile-time error.
^" in t as{TypeError,ForNonNullableByDefault} () →? core::int);
}
diff --git a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.weak.transformed.expect
index 19bd0eb..ba18f39 100644
--- a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.weak.transformed.expect
@@ -57,10 +57,10 @@
static method foo<T extends self::C? = self::C?>(self::C? c, self::foo::T% t, self::foo::T? nt) → dynamic {
self::functionContext(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:14:24: Error: Can't tear off method 'call' from a potentially null value.
functionContext(null as C?); // Error.
- ^" in (null as{ForNonNullableByDefault} self::C?) as{TypeError} () → core::int);
+ ^" in null);
self::nullableFunctionContext(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:15:32: Error: Can't tear off method 'call' from a potentially null value.
nullableFunctionContext(null as C?); // Error.
- ^" in (null as{ForNonNullableByDefault} self::C?) as{TypeError} () →? core::int);
+ ^" in null);
self::functionContext(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart:16:19: Error: Can't tear off method 'call' from a potentially null value.
functionContext(c); // Error.
^" in c as{TypeError} () → core::int);
diff --git a/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart
new file mode 100644
index 0000000..df91fb9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// @dart=2.6
+
+import 'call_opt_in_through_opt_out_lib.dart';
+
+test() {
+ applyTakesNever(takesNever);
+ applyTakesNever(takesNull);
+ applyTakesNull(takesNever);
+ applyTakesNull(takesNull);
+ applyTakesNeverNamed(f: takesNever);
+ applyTakesNeverNamed(f: takesNull);
+ applyTakesNullNamed(f: takesNever);
+ applyTakesNullNamed(f: takesNull);
+
+ applyTakesNonNullable(takesNonNullable);
+ applyTakesNonNullable(takesNullable);
+ applyTakesNullable(takesNonNullable);
+ applyTakesNullable(takesNullable);
+ applyTakesNonNullableNamed(f: takesNonNullable);
+ applyTakesNonNullableNamed(f: takesNullable);
+ applyTakesNullableNamed(f: takesNonNullable);
+ applyTakesNullableNamed(f: takesNullable);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..e2f2808
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'call_opt_in_through_opt_out_lib.dart';
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6830a79
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'call_opt_in_through_opt_out_lib.dart';
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.weak.expect
new file mode 100644
index 0000000..3725acd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.weak.expect
@@ -0,0 +1,51 @@
+library;
+import self as self;
+import "call_opt_in_through_opt_out_lib.dart" as cal;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///call_opt_in_through_opt_out_lib.dart";
+
+static method test() → dynamic {
+ cal::applyTakesNever(#C1);
+ cal::applyTakesNever(#C2);
+ cal::applyTakesNull(#C1);
+ cal::applyTakesNull(#C2);
+ cal::applyTakesNeverNamed(f: #C1);
+ cal::applyTakesNeverNamed(f: #C2);
+ cal::applyTakesNullNamed(f: #C1);
+ cal::applyTakesNullNamed(f: #C2);
+ cal::applyTakesNonNullable(#C3);
+ cal::applyTakesNonNullable(#C4);
+ cal::applyTakesNullable(#C3);
+ cal::applyTakesNullable(#C4);
+ cal::applyTakesNonNullableNamed(f: #C3);
+ cal::applyTakesNonNullableNamed(f: #C4);
+ cal::applyTakesNullableNamed(f: #C3);
+ cal::applyTakesNullableNamed(f: #C4);
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as cal;
+import "dart:core" as core;
+
+static method takesNull(core::Null? n) → void {}
+static method takesNever(Never n) → void {}
+static method applyTakesNull((core::Null?) → void f) → dynamic {}
+static method applyTakesNever((Never) → void f) → dynamic {}
+static method applyTakesNullNamed({required (core::Null?) → void f = #C5}) → dynamic {}
+static method applyTakesNeverNamed({required (Never) → void f = #C5}) → dynamic {}
+static method takesNullable(core::int? i) → void {}
+static method takesNonNullable(core::int i) → void {}
+static method applyTakesNullable((core::int?) → void f) → dynamic {}
+static method applyTakesNonNullable((core::int) → void f) → dynamic {}
+static method applyTakesNullableNamed({required (core::int?) → void f = #C5}) → dynamic {}
+static method applyTakesNonNullableNamed({required (core::int) → void f = #C5}) → dynamic {}
+
+constants {
+ #C1 = tearoff cal::takesNever
+ #C2 = tearoff cal::takesNull
+ #C3 = tearoff cal::takesNonNullable
+ #C4 = tearoff cal::takesNullable
+ #C5 = null
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.weak.transformed.expect
new file mode 100644
index 0000000..3725acd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out.dart.weak.transformed.expect
@@ -0,0 +1,51 @@
+library;
+import self as self;
+import "call_opt_in_through_opt_out_lib.dart" as cal;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///call_opt_in_through_opt_out_lib.dart";
+
+static method test() → dynamic {
+ cal::applyTakesNever(#C1);
+ cal::applyTakesNever(#C2);
+ cal::applyTakesNull(#C1);
+ cal::applyTakesNull(#C2);
+ cal::applyTakesNeverNamed(f: #C1);
+ cal::applyTakesNeverNamed(f: #C2);
+ cal::applyTakesNullNamed(f: #C1);
+ cal::applyTakesNullNamed(f: #C2);
+ cal::applyTakesNonNullable(#C3);
+ cal::applyTakesNonNullable(#C4);
+ cal::applyTakesNullable(#C3);
+ cal::applyTakesNullable(#C4);
+ cal::applyTakesNonNullableNamed(f: #C3);
+ cal::applyTakesNonNullableNamed(f: #C4);
+ cal::applyTakesNullableNamed(f: #C3);
+ cal::applyTakesNullableNamed(f: #C4);
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as cal;
+import "dart:core" as core;
+
+static method takesNull(core::Null? n) → void {}
+static method takesNever(Never n) → void {}
+static method applyTakesNull((core::Null?) → void f) → dynamic {}
+static method applyTakesNever((Never) → void f) → dynamic {}
+static method applyTakesNullNamed({required (core::Null?) → void f = #C5}) → dynamic {}
+static method applyTakesNeverNamed({required (Never) → void f = #C5}) → dynamic {}
+static method takesNullable(core::int? i) → void {}
+static method takesNonNullable(core::int i) → void {}
+static method applyTakesNullable((core::int?) → void f) → dynamic {}
+static method applyTakesNonNullable((core::int) → void f) → dynamic {}
+static method applyTakesNullableNamed({required (core::int?) → void f = #C5}) → dynamic {}
+static method applyTakesNonNullableNamed({required (core::int) → void f = #C5}) → dynamic {}
+
+constants {
+ #C1 = tearoff cal::takesNever
+ #C2 = tearoff cal::takesNull
+ #C3 = tearoff cal::takesNonNullable
+ #C4 = tearoff cal::takesNullable
+ #C5 = null
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out_lib.dart b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out_lib.dart
new file mode 100644
index 0000000..74b0c2f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/call_opt_in_through_opt_out_lib.dart
@@ -0,0 +1,17 @@
+// 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.
+
+void takesNull(Null n) {}
+void takesNever(Never n) {}
+applyTakesNull(void Function(Null) f) {}
+applyTakesNever(void Function(Never) f) {}
+applyTakesNullNamed({required void Function(Null) f}) {}
+applyTakesNeverNamed({required void Function(Never) f}) {}
+
+void takesNullable(int? i) {}
+void takesNonNullable(int i) {}
+applyTakesNullable(void Function(int?) f) {}
+applyTakesNonNullable(void Function(int) f) {}
+applyTakesNullableNamed({required void Function(int?) f}) {}
+applyTakesNonNullableNamed({required void Function(int) f}) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart
index fa999f7..b061200 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart
@@ -5,6 +5,8 @@
import 'dart:async';
import 'constant_null_is_lib.dart';
+final bool isWeakMode = const <Null>[] is List<Object>;
+
const c0 = null is int?;
const c1 = null is int;
const c2 = null is Null;
@@ -18,6 +20,27 @@
const c10 = null is FutureOr<Never>;
const c11 = null is FutureOr<Never?>;
const c12 = null is FutureOr<Never>?;
+const e1 = const Class<int>.constructor1(null);
+const e2 = const Class<int?>.constructor1(null);
+const e3 = const Class<Null>.constructor1(null);
+const e4 = const Class<int>.constructor2(null);
+const e5 = const Class<int?>.constructor2(null);
+const e6 = const Class<Null>.constructor2(null);
+const e7 = const Class<int>.constructor3(null);
+const e8 = const Class<int?>.constructor3(null);
+const e9 = const Class<Null>.constructor3(null);
+const e10 = const Class<int>.constructor4(null);
+const e11 = const Class<int?>.constructor4(null);
+const e12 = const Class<Null>.constructor4(null);
+
+class Class<T> {
+ final bool field;
+
+ const Class.constructor1(value) : field = value is T;
+ const Class.constructor2(value) : field = value is T?;
+ const Class.constructor3(value) : field = value is Class<T>;
+ const Class.constructor4(value) : field = value is Class<T>?;
+}
main() {
expect(null is int?, c0, "null is int?");
@@ -33,6 +56,37 @@
expect(null is FutureOr<Never>, c10, "null is FutureOr<Never>");
expect(null is FutureOr<Never?>, c11, "null is FutureOr<Never?>");
expect(null is FutureOr<Never>?, c12, "null is FutureOr<Never>?");
+ expect(new Class<int>.constructor1(null).field, e1.field,
+ "Class<int>.constructor1(null).field");
+ expect(true, new Class<int?>.constructor1(null).field,
+ "new Class<int?>.constructor1(null).field");
+ // const Class<int?> is evaluated as const Class<int*> in weak mode:
+ expect(!isWeakMode, e2.field, "const Class<int?>.constructor1(null).field");
+ expect(new Class<Null>.constructor1(null).field, e3.field,
+ "Class<Null>.constructor1(null).field");
+ expect(new Class<int>.constructor2(null).field, e4.field,
+ "Class<int>.constructor2(null).field");
+ expect(true, new Class<int?>.constructor2(null).field,
+ "new Class<int?>.constructor2(null).field");
+ // const Class<int?> is evaluated as const Class<int*> in weak mode:
+ expect(new Class<int?>.constructor2(null).field, e5.field,
+ "Class<int?>.constructor2(null).field");
+ expect(new Class<Null>.constructor2(null).field, e6.field,
+ "Class<Null>.constructor2(null).field");
+ expect(new Class<int>.constructor3(null).field, e7.field,
+ "Class<int>.constructor3(null).field");
+ expect(new Class<int?>.constructor3(null).field, e8.field,
+ "Class<int?>.constructor3(null).field");
+ expect(new Class<int?>.constructor3(null).field, e8.field,
+ "Class<int?>.constructor3(null).field");
+ expect(new Class<Null>.constructor3(null).field, e9.field,
+ "Class<Null>.constructor3(null).field");
+ expect(new Class<int>.constructor4(null).field, e10.field,
+ "Class<int>.constructor4(null).field");
+ expect(new Class<int?>.constructor4(null).field, e11.field,
+ "Class<int?>.constructor4(null).field");
+ expect(new Class<Null>.constructor4(null).field, e12.field,
+ "Class<Null>.constructor4(null).field");
test();
}
diff --git a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.textual_outline.expect
index 93feb55..baf0ddd 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.textual_outline.expect
@@ -1,6 +1,7 @@
import 'dart:async';
import 'constant_null_is_lib.dart';
+final bool isWeakMode = const <Null>[] is List<Object>;
const c0 = null is int?;
const c1 = null is int;
const c2 = null is Null;
@@ -14,5 +15,26 @@
const c10 = null is FutureOr<Never>;
const c11 = null is FutureOr<Never?>;
const c12 = null is FutureOr<Never>?;
+const e1 = const Class<int>.constructor1(null);
+const e2 = const Class<int?>.constructor1(null);
+const e3 = const Class<Null>.constructor1(null);
+const e4 = const Class<int>.constructor2(null);
+const e5 = const Class<int?>.constructor2(null);
+const e6 = const Class<Null>.constructor2(null);
+const e7 = const Class<int>.constructor3(null);
+const e8 = const Class<int?>.constructor3(null);
+const e9 = const Class<Null>.constructor3(null);
+const e10 = const Class<int>.constructor4(null);
+const e11 = const Class<int?>.constructor4(null);
+const e12 = const Class<Null>.constructor4(null);
+
+class Class<T> {
+ final bool field;
+ const Class.constructor1(value) : field = value is T;
+ const Class.constructor2(value) : field = value is T?;
+ const Class.constructor3(value) : field = value is Class<T>;
+ const Class.constructor4(value) : field = value is Class<T>?;
+}
+
main() {}
expect(expected, actual, String message) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.textual_outline_modelled.expect
index 04683eb..b8cfff4 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.textual_outline_modelled.expect
@@ -1,6 +1,14 @@
import 'dart:async';
import 'constant_null_is_lib.dart';
+class Class<T> {
+ const Class.constructor1(value) : field = value is T;
+ const Class.constructor2(value) : field = value is T?;
+ const Class.constructor3(value) : field = value is Class<T>;
+ const Class.constructor4(value) : field = value is Class<T>?;
+ final bool field;
+}
+
const c0 = null is int?;
const c1 = null is int;
const c10 = null is FutureOr<Never>;
@@ -14,5 +22,18 @@
const c7 = null is FutureOr<int>?;
const c8 = null is FutureOr<Null>;
const c9 = null is FutureOr<Null>?;
+const e1 = const Class<int>.constructor1(null);
+const e10 = const Class<int>.constructor4(null);
+const e11 = const Class<int?>.constructor4(null);
+const e12 = const Class<Null>.constructor4(null);
+const e2 = const Class<int?>.constructor1(null);
+const e3 = const Class<Null>.constructor1(null);
+const e4 = const Class<int>.constructor2(null);
+const e5 = const Class<int?>.constructor2(null);
+const e6 = const Class<Null>.constructor2(null);
+const e7 = const Class<int>.constructor3(null);
+const e8 = const Class<int?>.constructor3(null);
+const e9 = const Class<Null>.constructor3(null);
expect(expected, actual, String message) {}
+final bool isWeakMode = const <Null>[] is List<Object>;
main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.weak.expect
index 6490709..486b1e3 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.weak.expect
@@ -7,33 +7,76 @@
import "dart:async";
import "org-dartlang-testcase:///constant_null_is_lib.dart";
-static const field core::bool c0 = #C1;
-static const field core::bool c1 = #C2;
-static const field core::bool c2 = #C1;
-static const field core::bool c3 = #C1;
-static const field core::bool c4 = #C2;
-static const field core::bool c5 = #C1;
-static const field core::bool c6 = #C2;
-static const field core::bool c7 = #C1;
-static const field core::bool c8 = #C1;
-static const field core::bool c9 = #C1;
-static const field core::bool c10 = #C2;
-static const field core::bool c11 = #C1;
-static const field core::bool c12 = #C1;
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ final field core::bool field;
+ const constructor constructor1(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+ ;
+ const constructor constructor2(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T?, super core::Object::•()
+ ;
+ const constructor constructor3(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>, super core::Object::•()
+ ;
+ const constructor constructor4(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>?, super core::Object::•()
+ ;
+}
+static final field core::bool isWeakMode = (#C1) is{ForNonNullableByDefault} core::List<core::Object>;
+static const field core::bool c0 = #C2;
+static const field core::bool c1 = #C3;
+static const field core::bool c2 = #C2;
+static const field core::bool c3 = #C2;
+static const field core::bool c4 = #C3;
+static const field core::bool c5 = #C2;
+static const field core::bool c6 = #C3;
+static const field core::bool c7 = #C2;
+static const field core::bool c8 = #C2;
+static const field core::bool c9 = #C2;
+static const field core::bool c10 = #C3;
+static const field core::bool c11 = #C2;
+static const field core::bool c12 = #C2;
+static const field self::Class<core::int> e1 = #C4;
+static const field self::Class<core::int?> e2 = #C4;
+static const field self::Class<core::Null?> e3 = #C5;
+static const field self::Class<core::int> e4 = #C6;
+static const field self::Class<core::int?> e5 = #C6;
+static const field self::Class<core::Null?> e6 = #C5;
+static const field self::Class<core::int> e7 = #C4;
+static const field self::Class<core::int?> e8 = #C4;
+static const field self::Class<core::Null?> e9 = #C7;
+static const field self::Class<core::int> e10 = #C6;
+static const field self::Class<core::int?> e11 = #C6;
+static const field self::Class<core::Null?> e12 = #C5;
static method main() → dynamic {
- self::expect(null is{ForNonNullableByDefault} core::int?, #C1, "null is int?");
- self::expect(null is{ForNonNullableByDefault} core::int, #C2, "null is int");
- self::expect(null is{ForNonNullableByDefault} core::Null?, #C1, "null is Null");
- self::expect(null is{ForNonNullableByDefault} Never?, #C1, "null is Never?");
- self::expect(null is{ForNonNullableByDefault} Never, #C2, "null is Never");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C1, "null is FutureOr<int?>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C2, "null is FutureOr<int>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C1, "null is FutureOr<int>?");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C1, "null is FutureOr<Null>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C1, "null is FutureOr<Null>?");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C2, "null is FutureOr<Never>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C1, "null is FutureOr<Never?>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C1, "null is FutureOr<Never>?");
+ self::expect(null is{ForNonNullableByDefault} core::int?, #C2, "null is int?");
+ self::expect(null is{ForNonNullableByDefault} core::int, #C3, "null is int");
+ self::expect(null is{ForNonNullableByDefault} core::Null?, #C2, "null is Null");
+ self::expect(null is{ForNonNullableByDefault} Never?, #C2, "null is Never?");
+ self::expect(null is{ForNonNullableByDefault} Never, #C3, "null is Never");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C2, "null is FutureOr<int?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C3, "null is FutureOr<int>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C2, "null is FutureOr<int>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C2, "null is FutureOr<Null>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C2, "null is FutureOr<Null>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C3, "null is FutureOr<Never>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C2, "null is FutureOr<Never?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C2, "null is FutureOr<Never>?");
+ self::expect(new self::Class::constructor1<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor1(null).field");
+ self::expect(true, new self::Class::constructor1<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor1(null).field");
+ self::expect(!self::isWeakMode, (#C4).{self::Class::field}, "const Class<int?>.constructor1(null).field");
+ self::expect(new self::Class::constructor1<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor1(null).field");
+ self::expect(new self::Class::constructor2<core::int>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor2(null).field");
+ self::expect(true, new self::Class::constructor2<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::int?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor2(null).field");
+ self::expect(new self::Class::constructor3<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::Null?>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<Null>.constructor3(null).field");
+ self::expect(new self::Class::constructor4<core::int>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::int?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int?>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor4(null).field");
con::test();
}
static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
@@ -49,14 +92,35 @@
import "dart:async";
import "org-dartlang-testcase:///constant_null_is.dart";
-static const field core::bool* d0 = #C2;
-static const field core::bool* d1 = #C1;
+static const field core::bool* d0 = #C3;
+static const field core::bool* d1 = #C2;
+static const field self::Class<core::int*>* d4 = #C4;
+static const field self::Class<core::Null?>* d5 = #C5;
+static const field self::Class<core::int*>* d6 = #C6;
+static const field self::Class<core::Null?>* d7 = #C5;
+static const field self::Class<core::int*>* d8 = #C4;
+static const field self::Class<core::Null?>* d9 = #C7;
+static const field self::Class<core::int*>* d10 = #C6;
+static const field self::Class<core::Null?>* d11 = #C5;
static method test() → dynamic {
- self::expect(null is core::int*, #C2, "null is int (opt-out)");
- self::expect(null is core::Null?, #C1, "null is Null");
+ self::expect(null is core::int*, #C3, "null is int (opt-out)");
+ self::expect(null is core::Null?, #C2, "null is Null");
+ self::expect(new self::Class::constructor1<core::int*>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor1(null).field (opt-out)");
+ self::expect(new self::Class::constructor1<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor1(null).field (opt-out)");
+ self::expect(new self::Class::constructor2<core::int*>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor2(null).field (opt-out)");
+ self::expect(new self::Class::constructor2<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor2(null).field (opt-out)");
+ self::expect(new self::Class::constructor3<core::int*>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor3(null).field (opt-out)");
+ self::expect(new self::Class::constructor3<core::Null?>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<Null>.constructor3(null).field (opt-out)");
+ self::expect(new self::Class::constructor4<core::int*>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor4(null).field (opt-out)");
+ self::expect(new self::Class::constructor4<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor4(null).field (opt-out)");
}
constants {
- #C1 = true
- #C2 = false
+ #C1 = <core::Null?>[]
+ #C2 = true
+ #C3 = false
+ #C4 = self::Class<core::int*> {field:#C3}
+ #C5 = self::Class<core::Null?> {field:#C2}
+ #C6 = self::Class<core::int*> {field:#C2}
+ #C7 = self::Class<core::Null?> {field:#C3}
}
diff --git a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.weak.transformed.expect
index 6490709..486b1e3 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/constant_null_is.dart.weak.transformed.expect
@@ -7,33 +7,76 @@
import "dart:async";
import "org-dartlang-testcase:///constant_null_is_lib.dart";
-static const field core::bool c0 = #C1;
-static const field core::bool c1 = #C2;
-static const field core::bool c2 = #C1;
-static const field core::bool c3 = #C1;
-static const field core::bool c4 = #C2;
-static const field core::bool c5 = #C1;
-static const field core::bool c6 = #C2;
-static const field core::bool c7 = #C1;
-static const field core::bool c8 = #C1;
-static const field core::bool c9 = #C1;
-static const field core::bool c10 = #C2;
-static const field core::bool c11 = #C1;
-static const field core::bool c12 = #C1;
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ final field core::bool field;
+ const constructor constructor1(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T%, super core::Object::•()
+ ;
+ const constructor constructor2(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class::T?, super core::Object::•()
+ ;
+ const constructor constructor3(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>, super core::Object::•()
+ ;
+ const constructor constructor4(dynamic value) → self::Class<self::Class::T%>
+ : self::Class::field = value is{ForNonNullableByDefault} self::Class<self::Class::T%>?, super core::Object::•()
+ ;
+}
+static final field core::bool isWeakMode = (#C1) is{ForNonNullableByDefault} core::List<core::Object>;
+static const field core::bool c0 = #C2;
+static const field core::bool c1 = #C3;
+static const field core::bool c2 = #C2;
+static const field core::bool c3 = #C2;
+static const field core::bool c4 = #C3;
+static const field core::bool c5 = #C2;
+static const field core::bool c6 = #C3;
+static const field core::bool c7 = #C2;
+static const field core::bool c8 = #C2;
+static const field core::bool c9 = #C2;
+static const field core::bool c10 = #C3;
+static const field core::bool c11 = #C2;
+static const field core::bool c12 = #C2;
+static const field self::Class<core::int> e1 = #C4;
+static const field self::Class<core::int?> e2 = #C4;
+static const field self::Class<core::Null?> e3 = #C5;
+static const field self::Class<core::int> e4 = #C6;
+static const field self::Class<core::int?> e5 = #C6;
+static const field self::Class<core::Null?> e6 = #C5;
+static const field self::Class<core::int> e7 = #C4;
+static const field self::Class<core::int?> e8 = #C4;
+static const field self::Class<core::Null?> e9 = #C7;
+static const field self::Class<core::int> e10 = #C6;
+static const field self::Class<core::int?> e11 = #C6;
+static const field self::Class<core::Null?> e12 = #C5;
static method main() → dynamic {
- self::expect(null is{ForNonNullableByDefault} core::int?, #C1, "null is int?");
- self::expect(null is{ForNonNullableByDefault} core::int, #C2, "null is int");
- self::expect(null is{ForNonNullableByDefault} core::Null?, #C1, "null is Null");
- self::expect(null is{ForNonNullableByDefault} Never?, #C1, "null is Never?");
- self::expect(null is{ForNonNullableByDefault} Never, #C2, "null is Never");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C1, "null is FutureOr<int?>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C2, "null is FutureOr<int>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C1, "null is FutureOr<int>?");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C1, "null is FutureOr<Null>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C1, "null is FutureOr<Null>?");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C2, "null is FutureOr<Never>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C1, "null is FutureOr<Never?>");
- self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C1, "null is FutureOr<Never>?");
+ self::expect(null is{ForNonNullableByDefault} core::int?, #C2, "null is int?");
+ self::expect(null is{ForNonNullableByDefault} core::int, #C3, "null is int");
+ self::expect(null is{ForNonNullableByDefault} core::Null?, #C2, "null is Null");
+ self::expect(null is{ForNonNullableByDefault} Never?, #C2, "null is Never?");
+ self::expect(null is{ForNonNullableByDefault} Never, #C3, "null is Never");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int?>, #C2, "null is FutureOr<int?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>, #C3, "null is FutureOr<int>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::int>?, #C2, "null is FutureOr<int>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>, #C2, "null is FutureOr<Null>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<core::Null?>?, #C2, "null is FutureOr<Null>?");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>, #C3, "null is FutureOr<Never>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never?>, #C2, "null is FutureOr<Never?>");
+ self::expect(null is{ForNonNullableByDefault} asy::FutureOr<Never>?, #C2, "null is FutureOr<Never>?");
+ self::expect(new self::Class::constructor1<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor1(null).field");
+ self::expect(true, new self::Class::constructor1<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor1(null).field");
+ self::expect(!self::isWeakMode, (#C4).{self::Class::field}, "const Class<int?>.constructor1(null).field");
+ self::expect(new self::Class::constructor1<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor1(null).field");
+ self::expect(new self::Class::constructor2<core::int>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor2(null).field");
+ self::expect(true, new self::Class::constructor2<core::int?>(null).{self::Class::field}, "new Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::int?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int?>.constructor2(null).field");
+ self::expect(new self::Class::constructor2<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor2(null).field");
+ self::expect(new self::Class::constructor3<core::int>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::int?>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int?>.constructor3(null).field");
+ self::expect(new self::Class::constructor3<core::Null?>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<Null>.constructor3(null).field");
+ self::expect(new self::Class::constructor4<core::int>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::int?>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int?>.constructor4(null).field");
+ self::expect(new self::Class::constructor4<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor4(null).field");
con::test();
}
static method expect(dynamic expected, dynamic actual, core::String message) → dynamic {
@@ -49,14 +92,35 @@
import "dart:async";
import "org-dartlang-testcase:///constant_null_is.dart";
-static const field core::bool* d0 = #C2;
-static const field core::bool* d1 = #C1;
+static const field core::bool* d0 = #C3;
+static const field core::bool* d1 = #C2;
+static const field self::Class<core::int*>* d4 = #C4;
+static const field self::Class<core::Null?>* d5 = #C5;
+static const field self::Class<core::int*>* d6 = #C6;
+static const field self::Class<core::Null?>* d7 = #C5;
+static const field self::Class<core::int*>* d8 = #C4;
+static const field self::Class<core::Null?>* d9 = #C7;
+static const field self::Class<core::int*>* d10 = #C6;
+static const field self::Class<core::Null?>* d11 = #C5;
static method test() → dynamic {
- self::expect(null is core::int*, #C2, "null is int (opt-out)");
- self::expect(null is core::Null?, #C1, "null is Null");
+ self::expect(null is core::int*, #C3, "null is int (opt-out)");
+ self::expect(null is core::Null?, #C2, "null is Null");
+ self::expect(new self::Class::constructor1<core::int*>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor1(null).field (opt-out)");
+ self::expect(new self::Class::constructor1<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor1(null).field (opt-out)");
+ self::expect(new self::Class::constructor2<core::int*>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor2(null).field (opt-out)");
+ self::expect(new self::Class::constructor2<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor2(null).field (opt-out)");
+ self::expect(new self::Class::constructor3<core::int*>(null).{self::Class::field}, (#C4).{self::Class::field}, "Class<int>.constructor3(null).field (opt-out)");
+ self::expect(new self::Class::constructor3<core::Null?>(null).{self::Class::field}, (#C7).{self::Class::field}, "Class<Null>.constructor3(null).field (opt-out)");
+ self::expect(new self::Class::constructor4<core::int*>(null).{self::Class::field}, (#C6).{self::Class::field}, "Class<int>.constructor4(null).field (opt-out)");
+ self::expect(new self::Class::constructor4<core::Null?>(null).{self::Class::field}, (#C5).{self::Class::field}, "Class<Null>.constructor4(null).field (opt-out)");
}
constants {
- #C1 = true
- #C2 = false
+ #C1 = <core::Null?>[]
+ #C2 = true
+ #C3 = false
+ #C4 = self::Class<core::int*> {field:#C3}
+ #C5 = self::Class<core::Null?> {field:#C2}
+ #C6 = self::Class<core::int*> {field:#C2}
+ #C7 = self::Class<core::Null?> {field:#C3}
}
diff --git a/pkg/front_end/testcases/nnbd_mixed/constant_null_is_lib.dart b/pkg/front_end/testcases/nnbd_mixed/constant_null_is_lib.dart
index 16b98a5..4186c6a 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constant_null_is_lib.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/constant_null_is_lib.dart
@@ -11,10 +11,34 @@
const d1 = null is Null;
//const d2 = null is FutureOr<Null>;
//const d3 = null is Never;
+const d4 = const Class<int>.constructor1(null);
+const d5 = const Class<Null>.constructor1(null);
+const d6 = const Class<int>.constructor2(null);
+const d7 = const Class<Null>.constructor2(null);
+const d8 = const Class<int>.constructor3(null);
+const d9 = const Class<Null>.constructor3(null);
+const d10 = const Class<int>.constructor4(null);
+const d11 = const Class<Null>.constructor4(null);
test() {
expect(null is int, d0, "null is int (opt-out)");
expect(null is Null, d1, "null is Null");
//expect(null is FutureOr<Null>, d2, "null is FutureOr<Null> (opt-out)");
//expect(null is Never, d3, "null is Never (opt-out)");
+ expect(new Class<int>.constructor1(null).field, d4.field,
+ "Class<int>.constructor1(null).field (opt-out)");
+ expect(new Class<Null>.constructor1(null).field, d5.field,
+ "Class<Null>.constructor1(null).field (opt-out)");
+ expect(new Class<int>.constructor2(null).field, d6.field,
+ "Class<int>.constructor2(null).field (opt-out)");
+ expect(new Class<Null>.constructor2(null).field, d7.field,
+ "Class<Null>.constructor2(null).field (opt-out)");
+ expect(new Class<int>.constructor3(null).field, d8.field,
+ "Class<int>.constructor3(null).field (opt-out)");
+ expect(new Class<Null>.constructor3(null).field, d9.field,
+ "Class<Null>.constructor3(null).field (opt-out)");
+ expect(new Class<int>.constructor4(null).field, d10.field,
+ "Class<int>.constructor4(null).field (opt-out)");
+ expect(new Class<Null>.constructor4(null).field, d11.field,
+ "Class<Null>.constructor4(null).field (opt-out)");
}
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41597.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/issue41597.dart.weak.transformed.expect
index c1f54a1..7c7517a 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue41597.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41597.dart.weak.transformed.expect
@@ -62,9 +62,9 @@
core::print(invalid-expression "pkg/front_end/testcases/nnbd_mixed/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
print(x!);
^"!);
- core::print(!(invalid-expression "pkg/front_end/testcases/nnbd_mixed/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+ core::print(!invalid-expression "pkg/front_end/testcases/nnbd_mixed/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
print(!x);
- ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+ ^");
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41657.dart b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart
new file mode 100644
index 0000000..801775a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41657.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.
+
+final isLegacySubtyping1a = const <Null>[] is List<int>;
+const isLegacySubtyping1b = const <Null>[] is List<int>;
+final isLegacySubtyping2a = const <int?>[] is List<int>;
+const isLegacySubtyping2b = const <int?>[] is List<int>;
+final assertLegacySubtyping1a = const <Null>[] as List<int>;
+const assertLegacySubtyping1b = const <Null>[] as List<int>;
+final assertLegacySubtyping2a = const <int?>[] as List<int>;
+const assertLegacySubtyping2b = const <int?>[] as List<int>;
+
+void main() {
+ expect(isLegacySubtyping1a, isLegacySubtyping1b);
+ expect(isLegacySubtyping2a, isLegacySubtyping2b);
+ expect(assertLegacySubtyping1a, assertLegacySubtyping1b);
+ expect(assertLegacySubtyping2a, assertLegacySubtyping2b);
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw "Expected $expected, actual $actual";
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.textual_outline.expect
new file mode 100644
index 0000000..b850bd5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+final isLegacySubtyping1a = const <Null>[] is List<int>;
+const isLegacySubtyping1b = const <Null>[] is List<int>;
+final isLegacySubtyping2a = const <int?>[] is List<int>;
+const isLegacySubtyping2b = const <int?>[] is List<int>;
+final assertLegacySubtyping1a = const <Null>[] as List<int>;
+const assertLegacySubtyping1b = const <Null>[] as List<int>;
+final assertLegacySubtyping2a = const <int?>[] as List<int>;
+const assertLegacySubtyping2b = const <int?>[] as List<int>;
+void main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..459a476
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+const assertLegacySubtyping1b = const <Null>[] as List<int>;
+const assertLegacySubtyping2b = const <int?>[] as List<int>;
+const isLegacySubtyping1b = const <Null>[] is List<int>;
+const isLegacySubtyping2b = const <int?>[] is List<int>;
+expect(expected, actual) {}
+final assertLegacySubtyping1a = const <Null>[] as List<int>;
+final assertLegacySubtyping2a = const <int?>[] as List<int>;
+final isLegacySubtyping1a = const <Null>[] is List<int>;
+final isLegacySubtyping2a = const <int?>[] is List<int>;
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.weak.expect
new file mode 100644
index 0000000..06afa9c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.weak.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static final field core::bool isLegacySubtyping1a = (#C1) is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping1b = #C2;
+static final field core::bool isLegacySubtyping2a = (#C3) is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping2b = #C2;
+static final field core::List<core::int> assertLegacySubtyping1a = (#C1) as{ForNonNullableByDefault} core::List<core::int>;
+static const field core::List<core::int> assertLegacySubtyping1b = #C1;
+static final field core::List<core::int> assertLegacySubtyping2a = (#C3) as{ForNonNullableByDefault} core::List<core::int>;
+static const field core::List<core::int> assertLegacySubtyping2b = #C3;
+static method main() → void {
+ self::expect(self::isLegacySubtyping1a, #C2);
+ self::expect(self::isLegacySubtyping2a, #C2);
+ self::expect(self::assertLegacySubtyping1a, #C1);
+ self::expect(self::assertLegacySubtyping2a, #C3);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = <core::Null?>[]
+ #C2 = true
+ #C3 = <core::int*>[]
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.weak.transformed.expect
new file mode 100644
index 0000000..d562933
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41657.dart.weak.transformed.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static final field core::bool isLegacySubtyping1a = (#C1) is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping1b = #C2;
+static final field core::bool isLegacySubtyping2a = (#C3) is{ForNonNullableByDefault} core::List<core::int>;
+static const field core::bool isLegacySubtyping2b = #C2;
+static final field core::List<core::int> assertLegacySubtyping1a = #C1;
+static const field core::List<core::int> assertLegacySubtyping1b = #C1;
+static final field core::List<core::int> assertLegacySubtyping2a = #C3;
+static const field core::List<core::int> assertLegacySubtyping2b = #C3;
+static method main() → void {
+ self::expect(self::isLegacySubtyping1a, #C2);
+ self::expect(self::isLegacySubtyping2a, #C2);
+ self::expect(self::assertLegacySubtyping1a, #C1);
+ self::expect(self::assertLegacySubtyping2a, #C3);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+
+constants {
+ #C1 = <core::Null?>[]
+ #C2 = true
+ #C3 = <core::int*>[]
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
index bcd8340..72b37b5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
@@ -17,6 +17,7 @@
import self as self;
import "issue41501_lib.dart" as opt;
import "dart:async" as asy;
+import "dart:core" as core;
import "dart:async";
import "org-dartlang-testcase:///issue41501_lib.dart";
@@ -28,13 +29,13 @@
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAlias> foLegacyNonNullable = null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+ ^" in let core::Null? #t2 = null in #t2.==(null) ?{asy::FutureOr<opt::A>} #t2 as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A> : #t2{asy::FutureOr<opt::A>};
asy::FutureOr<opt::A?> foLegacyNullable = null;
- asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAliasNonNullable> foNonNullable = null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+ ^" in let core::Null? #t4 = null in #t4.==(null) ?{asy::FutureOr<opt::A>} #t4 as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A> : #t4{asy::FutureOr<opt::A>};
asy::FutureOr<opt::A?> foNullable = null;
asy::FutureOr<opt::A?> foNonNullableNullable = null;
asy::FutureOr<opt::A?> foNullableNullable = null;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
index bcd8340..8b84923 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
@@ -28,13 +28,13 @@
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAlias> foLegacyNonNullable = null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+ ^" in null;
asy::FutureOr<opt::A?> foLegacyNullable = null;
asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAliasNonNullable> foNonNullable = null; // error
- ^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
+ ^" in null;
asy::FutureOr<opt::A?> foNullable = null;
asy::FutureOr<opt::A?> foNonNullableNullable = null;
asy::FutureOr<opt::A?> foNullableNullable = null;
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
index fbca8cb..0144be4 100644
--- a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
@@ -80,7 +80,7 @@
- 'C' is from 'pkg/front_end/testcases/rasta/issue_000044.dart'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'h'.
C notEvenAConstructor(a) = h;
- ^" as{TypeError,ForDynamic} self::C*;
+ ^";
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/parser_error.dart.strong.transformed.expect
index 13f78fd..104ab44 100644
--- a/pkg/front_end/testcases/rasta/parser_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.strong.transformed.expect
@@ -23,7 +23,7 @@
static method test(dynamic a, {dynamic b = #C1, dynamic c = #C1}) → core::int* {
if((invalid-expression "pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: This couldn't be parsed.
if (?b) return b; /// 01: compile-time error
- ^" as{TypeError,ForDynamic} core::bool* ?{dynamic} b : invalid-expression "pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: This couldn't be parsed.
+ ^" ?{dynamic} b : invalid-expression "pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: This couldn't be parsed.
if (?b) return b; /// 01: compile-time error
^") as{TypeError,ForDynamic} core::bool*)
return b as{TypeError,ForDynamic} core::int*;
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
index 7ababc1..2e3e370 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
@@ -17,11 +17,11 @@
import "dart:core" as core;
static method bad() → dynamic {
- for (core::int* i = (let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+ for (core::int* i = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
for (int i = i;; false) {}
^" in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Getter not found: 'i'.
for (int i = i;; false) {}
- ^") as{TypeError,ForDynamic} core::int*; ; false) {
+ ^"; ; false) {
}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31184.dart.strong.transformed.expect
index ed5c611..57aaf8d 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.strong.transformed.expect
@@ -23,7 +23,7 @@
static method bad() → dynamic {
for (core::int* i = 0, core::int* i = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
for (int i = 0, i > 10; i++) {}
- ^" as{TypeError,ForDynamic} core::int*; invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: This couldn't be parsed.
+ ^"; invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: This couldn't be parsed.
for (int i = 0, i > 10; i++) {}
^".>(10) as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1)) {
}
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
index b100603..a236821 100644
--- a/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
@@ -25,7 +25,7 @@
static method test2() → core::int* {
return invalid-expression "pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
return (i) ++ (i);
- ^" as{TypeError,ForDynamic} core::int*;
+ ^";
self::i;
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_35260.dart.strong.transformed.expect
index a6949eeb..7942bfb 100644
--- a/pkg/front_end/testcases/regress/issue_35260.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.strong.transformed.expect
@@ -49,5 +49,5 @@
static method main() → dynamic {
self::X* x = invalid-expression "pkg/front_end/testcases/regress/issue_35260.dart:15:13: Error: Can't use 'Supertype' because it is declared more than once.
X x = new Supertype();
- ^" as{TypeError,ForDynamic} self::X*;
+ ^";
}
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 3545e88..f8257ff 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -477,7 +477,9 @@
"test/id_testing/data/",
"test/language_versioning/data/",
"test/patching/data",
- "test/static_types/data/"
+ "test/predicates/data",
+ "test/static_types/data/",
+ "test/text_representation/data/"
]
}
}
diff --git a/pkg/front_end/testing_with_lints.json b/pkg/front_end/testing_with_lints.json
index 78fdd07..6cdef88 100644
--- a/pkg/front_end/testing_with_lints.json
+++ b/pkg/front_end/testing_with_lints.json
@@ -16,7 +16,8 @@
"test/id_testing/data/",
"test/language_versioning/data/",
"test/patching/data/",
- "test/static_types/data/"
+ "test/static_types/data/",
+ "test/text_representation/data/"
]
}
}
diff --git a/pkg/frontend_server/lib/src/expression_compiler.dart b/pkg/frontend_server/lib/src/expression_compiler.dart
index 0abad7f..a64a904 100644
--- a/pkg/frontend_server/lib/src/expression_compiler.dart
+++ b/pkg/frontend_server/lib/src/expression_compiler.dart
@@ -437,11 +437,8 @@
// 2. compile kernel AST to JS ast
- _kernel2jsCompiler.setIncrementalCompilationScope(scope.library, scope.cls);
- _kernel2jsCompiler.runtimeModule = js_ast.Identifier('dart');
-
- var jsFun = _kernel2jsCompiler.emitFunction(
- procedure.function, '$debugProcedureName');
+ var jsFun = _kernel2jsCompiler.emitFunctionIncremental(
+ scope.library, scope.cls, procedure.function, '$debugProcedureName');
// 3. apply temporary workarounds for what ideally
// needs to be done in the compiler
diff --git a/pkg/frontend_server/test/src/expression_compiler_test.dart b/pkg/frontend_server/test/src/expression_compiler_test.dart
index 464b53b..52b309c 100644
--- a/pkg/frontend_server/test/src/expression_compiler_test.dart
+++ b/pkg/frontend_server/test/src/expression_compiler_test.dart
@@ -17,6 +17,10 @@
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
+// TODO(annagrin): Replace javascript matching in tests below with evaluating
+// the javascript and checking the result.
+// See https://github.com/dart-lang/sdk/issues/41959
+
class DevelopmentIncrementalCompiler extends IncrementalCompiler {
Uri entryPoint;
@@ -1097,5 +1101,106 @@
});
});
+ group('Expression compiler tests in method with no type use', () {
+ const String source = '''
+ abstract class Key {
+ const factory Key(String value) = ValueKey;
+ const Key.empty();
+ }
+
+ abstract class LocalKey extends Key {
+ const LocalKey() : super.empty();
+ }
+
+ class ValueKey implements LocalKey {
+ const ValueKey(this.value);
+ final String value;
+ }
+
+ class MyClass {
+ const MyClass(this._t);
+ final int _t;
+ }
+
+ int bar(int p){
+ return p;
+ }
+ void main() {
+ var k = Key('t');
+ MyClass c = MyClass(0);
+ int p = 1;
+
+ /* evaluation placeholder */
+ print('\$c, \$k');
+ }
+ ''';
+
+ TestDriver driver;
+ setUp(() {
+ driver = TestDriver(options, source);
+ });
+
+ tearDown(() {
+ driver.delete();
+ });
+
+ test('call function using type', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: 'bar(p)',
+ expectedResult: '''
+ (function(p) {
+ var intL = () => (intL = dart.constFn(dart.legacy(core.int)))();
+ return foo.bar(intL().as(p));
+ }(
+ 1
+ ))
+ ''');
+ });
+
+ test('evaluate const expression', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: 'const MyClass(1)',
+ expectedResult: '''
+ (function(p) {
+ return dart.const(new foo.MyClass.new(1));
+ }(
+ 1
+ ))
+ ''');
+ });
+
+ test('evaluate factory constructor call', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: "Key('t')",
+ expectedResult: '''
+ (function(p) {
+ return new foo.ValueKey.new("t");
+ }(
+ 1
+ ))
+ ''');
+ },
+ skip:
+ 'Incorrect kernel for factory constructor call'); // https://github.com/dart-lang/sdk/issues/41976
+
+ test('evaluate const factory constructor call', () async {
+ await driver.check(
+ scope: <String, String>{'p': '1'},
+ expression: "const Key('t')",
+ expectedResult: '''
+ (function(p) {
+ return dart.const(new foo.ValueKey.new("t"));
+ }(
+ 1
+ ))
+ ''');
+ },
+ skip:
+ 'Incorrect kernel for factory constructor call'); // https://github.com/dart-lang/sdk/issues/41976
+ });
+
return 0;
}
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 5032cc1..ac11efd0 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -6697,6 +6697,22 @@
}
bool equals(Object other, Assumptions assumptions);
+
+ @override
+ String toStringInternal() {
+ return toTypeText(verbose: _verboseTypeToString);
+ }
+
+ /// Returns a textual representation of the this type.
+ ///
+ /// If [verbose] is `true`, qualified names will include the library name/uri.
+ String toTypeText({bool verbose: false}) {
+ StringBuffer sb = new StringBuffer();
+ toTypeTextInternal(sb, verbose: verbose);
+ return sb.toString();
+ }
+
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false});
}
/// The type arising from invalid type annotations.
@@ -6742,8 +6758,8 @@
}
@override
- String toStringInternal() {
- return "invalid-type";
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write("<invalid>");
}
}
@@ -6784,8 +6800,8 @@
}
@override
- String toStringInternal() {
- return "dynamic";
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write("dynamic");
}
}
@@ -6826,8 +6842,8 @@
}
@override
- String toStringInternal() {
- return "void";
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write("void");
}
}
@@ -6875,8 +6891,9 @@
}
@override
- String toStringInternal() {
- return "${nullabilityToString(nullability)}";
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write("Never");
+ sb.write(nullabilityToString(nullability));
}
}
@@ -6917,8 +6934,8 @@
}
@override
- String toStringInternal() {
- return "<BottomType>";
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write("<bottom>");
}
}
@@ -7015,7 +7032,25 @@
}
@override
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write(
+ qualifiedClassNameToString(classNode, includeLibraryName: verbose));
+ if (typeArguments.isNotEmpty) {
+ sb.write("<");
+ String comma = "";
+ for (DartType typeArgument in typeArguments) {
+ sb.write(comma);
+ typeArgument.toTypeTextInternal(sb, verbose: verbose);
+ comma = ", ";
+ }
+ sb.write(">");
+ }
+ sb.write(nullabilityToString(nullability));
+ }
+
+ @override
String toStringInternal() {
+ // TODO(johnniwinther): Unify this with [toTypeTextInternal].
StringBuffer sb = new StringBuffer();
if (_verboseTypeToString) {
sb.write(className.toStringInternal());
@@ -7217,26 +7252,44 @@
}
@override
- String toStringInternal() {
- StringBuffer sb = new StringBuffer();
- sb.write(returnType.toStringInternal());
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ returnType.toTypeTextInternal(sb, verbose: verbose);
sb.write(" Function");
if (typeParameters.isNotEmpty) {
sb.write("<");
String comma = "";
for (TypeParameter typeParameter in typeParameters) {
sb.write(comma);
- sb.write(typeParameter.toStringInternal());
+ sb.write(typeParameter.name);
+ DartType bound = typeParameter.bound;
+
+ bool isTopObject(DartType type) {
+ if (type is InterfaceType &&
+ type.className.node != null &&
+ type.classNode.name == 'Object') {
+ Uri uri = type.classNode.enclosingLibrary?.importUri;
+ return uri?.scheme == 'dart' &&
+ uri?.path == 'core' &&
+ (type.nullability == Nullability.legacy ||
+ type.nullability == Nullability.nullable);
+ }
+ return false;
+ }
+
+ if (!isTopObject(bound) || isTopObject(typeParameter.defaultType)) {
+ // Include explicit bounds only.
+ sb.write(' extends ');
+ bound.toTypeTextInternal(sb, verbose: verbose);
+ }
comma = ", ";
}
sb.write(">");
}
-
sb.write("(");
for (int i = 0; i < positionalParameters.length; i++) {
if (i > 0) sb.write(", ");
if (i == requiredParameterCount) sb.write("[");
- sb.write(positionalParameters[i].toStringInternal());
+ positionalParameters[i].toTypeTextInternal(sb, verbose: verbose);
}
if (requiredParameterCount < positionalParameters.length) sb.write("]");
@@ -7247,14 +7300,12 @@
sb.write("{");
for (int i = 0; i < namedParameters.length; i++) {
if (i > 0) sb.write(", ");
- sb.write(namedParameters[i].toStringInternal());
+ namedParameters[i].toTypeTextInternal(sb, includeLibraryName: verbose);
}
sb.write("}");
}
sb.write(")");
sb.write(nullabilityToString(nullability));
-
- return sb.toString();
}
}
@@ -7356,20 +7407,20 @@
}
@override
- String toStringInternal() {
- StringBuffer sb = new StringBuffer();
- sb.write(typedefNode.toStringInternal());
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write(
+ qualifiedTypedefNameToString(typedefNode, includeLibraryName: verbose));
if (typeArguments.isNotEmpty) {
sb.write("<");
String comma = "";
for (DartType typeArgument in typeArguments) {
sb.write(comma);
- sb.write(typeArgument.toStringInternal());
+ typeArgument.toTypeTextInternal(sb, verbose: verbose);
comma = ", ";
}
sb.write(">");
}
- return sb.toString();
+ sb.write(nullabilityToString(nullability));
}
}
@@ -7415,11 +7466,15 @@
return "NamedType(${toStringInternal()})";
}
+ void toTypeTextInternal(StringBuffer sb, {bool includeLibraryName: false}) {
+ if (isRequired) sb.write("required ");
+ sb.write("$name: ${type.toStringInternal()}");
+ }
+
@override
String toStringInternal() {
StringBuffer sb = new StringBuffer();
- if (isRequired) sb.write("required ");
- sb.write("$name: ${type.toStringInternal()}");
+ toTypeTextInternal(sb, includeLibraryName: _verboseTypeToString);
return sb.toString();
}
}
@@ -7717,10 +7772,9 @@
}
@override
- String toStringInternal() {
- StringBuffer sb = new StringBuffer();
+ void toTypeTextInternal(StringBuffer sb, {bool verbose: false}) {
sb.write(qualifiedTypeParameterNameToString(parameter,
- includeLibraryName: _verboseTypeToString));
+ includeLibraryName: verbose));
sb.write(nullabilityToString(declaredNullability));
if (promotedBound != null) {
sb.write(" & ");
@@ -7737,8 +7791,6 @@
sb.write(nullabilityToString(nullability));
sb.write("' */");
}
-
- return sb.toString();
}
}
@@ -8048,6 +8100,17 @@
int get hashCode;
bool operator ==(Object other);
+ /// Returns a textual representation of the this constant.
+ ///
+ /// If [verbose] is `true`, qualified names will include the library name/uri.
+ String toConstantText({bool verbose: false}) {
+ StringBuffer sb = new StringBuffer();
+ toConstantTextInternal(sb, verbose: verbose);
+ return sb.toString();
+ }
+
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false});
+
/// Gets the type of this constant.
DartType getType(StaticTypeContext context);
@@ -8068,6 +8131,11 @@
bool operator ==(Object other) =>
other is PrimitiveConstant<T> && other.value == value;
+
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write(value);
+ }
}
class NullConstant extends PrimitiveConstant<Null> {
@@ -8162,6 +8230,16 @@
DartType getType(StaticTypeContext context) =>
context.typeEnvironment.coreTypes.symbolRawType(context.nonNullable);
+
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('#');
+ if (verbose && libraryReference != null) {
+ sb.write(libraryNameToString(libraryReference.asLibrary));
+ sb.write('::');
+ }
+ sb.write(name);
+ }
}
class MapConstant extends Constant {
@@ -8183,6 +8261,22 @@
R accept<R>(ConstantVisitor<R> v) => v.visitMapConstant(this);
R acceptReference<R>(Visitor<R> v) => v.visitMapConstantReference(this);
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('<');
+ keyType.toTypeTextInternal(sb, verbose: verbose);
+ sb.write(', ');
+ valueType.toTypeTextInternal(sb, verbose: verbose);
+ sb.write('>{');
+ for (int i = 0; i < entries.length; i++) {
+ if (i > 0) {
+ sb.write(', ');
+ }
+ entries[i].toConstantTextInternal(sb, includeLibraryName: verbose);
+ }
+ sb.write('}');
+ }
+
String toString() => toStringInternal();
String toStringInternal() {
return '${this.runtimeType}<$keyType, $valueType>($entries)';
@@ -8217,6 +8311,13 @@
bool operator ==(Object other) =>
other is ConstantMapEntry && other.key == key && other.value == value;
+
+ void toConstantTextInternal(StringBuffer sb,
+ {bool includeLibraryName: false}) {
+ key.toConstantTextInternal(sb, verbose: includeLibraryName);
+ sb.write(': ');
+ value.toConstantTextInternal(sb, verbose: includeLibraryName);
+ }
}
class ListConstant extends Constant {
@@ -8235,6 +8336,20 @@
R accept<R>(ConstantVisitor<R> v) => v.visitListConstant(this);
R acceptReference<R>(Visitor<R> v) => v.visitListConstantReference(this);
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('<');
+ typeArgument.toTypeTextInternal(sb, verbose: verbose);
+ sb.write('>[');
+ for (int i = 0; i < entries.length; i++) {
+ if (i > 0) {
+ sb.write(', ');
+ }
+ entries[i].toConstantTextInternal(sb, verbose: verbose);
+ }
+ sb.write(']');
+ }
+
String toString() => toStringInternal();
String toStringInternal() {
return '${runtimeType}<${typeArgument.toStringInternal()}>($entries)';
@@ -8272,6 +8387,20 @@
R accept<R>(ConstantVisitor<R> v) => v.visitSetConstant(this);
R acceptReference<R>(Visitor<R> v) => v.visitSetConstantReference(this);
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('<');
+ typeArgument.toTypeTextInternal(sb, verbose: verbose);
+ sb.write('>{');
+ for (int i = 0; i < entries.length; i++) {
+ if (i > 0) {
+ sb.write(', ');
+ }
+ entries[i].toConstantTextInternal(sb, verbose: verbose);
+ }
+ sb.write('}');
+ }
+
String toString() => toStringInternal();
String toStringInternal() {
return '${runtimeType}<${typeArgument.toStringInternal()}>($entries)';
@@ -8316,6 +8445,32 @@
R accept<R>(ConstantVisitor<R> v) => v.visitInstanceConstant(this);
R acceptReference<R>(Visitor<R> v) => v.visitInstanceConstantReference(this);
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write(
+ qualifiedClassNameToString(classNode, includeLibraryName: verbose));
+ if (typeArguments.isNotEmpty) {
+ sb.write('<');
+ for (int i = 0; i < typeArguments.length; i++) {
+ if (i > 0) {
+ sb.write(', ');
+ }
+ typeArguments[i].toTypeTextInternal(sb, verbose: verbose);
+ }
+ sb.write('>');
+ }
+ sb.write('{');
+ String comma = '';
+ fieldValues.forEach((Reference fieldRef, Constant constant) {
+ sb.write(comma);
+ sb.write(qualifiedMemberNameToString(fieldRef.asField));
+ sb.write(': ');
+ constant.toConstantTextInternal(sb, verbose: verbose);
+ comma = ', ';
+ });
+ sb.write('}');
+ }
+
String toString() => toStringInternal();
String toStringInternal() {
final sb = new StringBuffer();
@@ -8369,6 +8524,19 @@
R acceptReference<R>(Visitor<R> v) =>
v.visitPartialInstantiationConstantReference(this);
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('<');
+ for (int i = 0; i < types.length; i++) {
+ if (i > 0) {
+ sb.write(',');
+ }
+ types[i].toTypeTextInternal(sb, verbose: verbose);
+ }
+ sb.write('>');
+ tearOffConstant.toConstantTextInternal(sb, verbose: verbose);
+ }
+
String toString() => toStringInternal();
String toStringInternal() {
return '${runtimeType}(${tearOffConstant.procedure}<'
@@ -8413,6 +8581,12 @@
R accept<R>(ConstantVisitor<R> v) => v.visitTearOffConstant(this);
R acceptReference<R>(Visitor<R> v) => v.visitTearOffConstantReference(this);
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write(
+ qualifiedMemberNameToString(procedure, includeLibraryName: verbose));
+ }
+
String toString() => toStringInternal();
String toStringInternal() {
return '${runtimeType}(${procedure})';
@@ -8443,6 +8617,11 @@
R acceptReference<R>(Visitor<R> v) =>
v.visitTypeLiteralConstantReference(this);
+ @override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ type.toTypeTextInternal(sb, verbose: verbose);
+ }
+
String toString() => toStringInternal();
String toStringInternal() => '${runtimeType}(${type})';
@@ -8478,6 +8657,13 @@
Expression asExpression() => expression;
@override
+ void toConstantTextInternal(StringBuffer sb, {bool verbose: false}) {
+ sb.write('unevaluated{');
+ sb.write(expression);
+ sb.write('}');
+ }
+
+ @override
String toString() {
return "UnevaluatedConstant(${toStringInternal()})";
}
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index df48c44..b778934 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -37,6 +37,8 @@
final String message;
CompilationModeError(this.message);
+
+ String toString() => "CompilationModeError[$message]";
}
class CanonicalNameError {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 069076b..553698e 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -579,16 +579,18 @@
}
}
- /// Collect non-empty metadata repositories associated with the component.
+ /// Collect metadata repositories associated with the component.
void _collectMetadata(Component component) {
- component.metadata.forEach((tag, repository) {
- if (repository.mapping.isEmpty) {
- return;
- }
-
- _metadataSubsections ??= <_MetadataSubsection>[];
- _metadataSubsections.add(new _MetadataSubsection(repository));
- });
+ if (component.metadata.isNotEmpty) {
+ // Component might be loaded lazily - meaning that we can't
+ // just skip empty repositories here, they might be populated by
+ // the serialization process. Instead we will filter empty repositories
+ // later before writing the section out.
+ _metadataSubsections = component.metadata.values
+ .map((MetadataRepository repository) =>
+ new _MetadataSubsection(repository))
+ .toList();
+ }
}
/// Writes metadata associated with the given [Node].
@@ -668,8 +670,10 @@
}
_binaryOffsetForMetadataPayloads = getBufferOffset();
+ _metadataSubsections
+ ?.removeWhere((_MetadataSubsection s) => s.metadataMapping.isEmpty);
- if (_metadataSubsections == null) {
+ if (_metadataSubsections == null || _metadataSubsections.isEmpty) {
_binaryOffsetForMetadataMappings = getBufferOffset();
writeUInt32(0); // Empty section.
return;
diff --git a/pkg/kernel/lib/src/text_util.dart b/pkg/kernel/lib/src/text_util.dart
index 28e7717..fd3f6d7 100644
--- a/pkg/kernel/lib/src/text_util.dart
+++ b/pkg/kernel/lib/src/text_util.dart
@@ -79,7 +79,7 @@
if (node.enclosingClass != null) {
return qualifiedClassNameToString(node.enclosingClass,
includeLibraryName: includeLibraryName) +
- '::' +
+ '.' +
memberNameToString(node);
} else if (includeLibraryName) {
return libraryNameToString(node.enclosingLibrary) +
@@ -101,17 +101,17 @@
if (parent is Class) {
return qualifiedClassNameToString(parent,
includeLibraryName: includeLibraryName) +
- '::' +
+ '.' +
typeParameterNameToString(node);
} else if (parent is Extension) {
return qualifiedExtensionNameToString(parent,
includeLibraryName: includeLibraryName) +
- '::' +
+ '.' +
typeParameterNameToString(node);
} else if (parent is Member) {
return qualifiedMemberNameToString(parent,
includeLibraryName: includeLibraryName) +
- '::' +
+ '.' +
typeParameterNameToString(node);
}
return typeParameterNameToString(node);
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 8c6a691..5ef2712 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -17,7 +17,7 @@
final bool forceNoExplicitGetterCallsForTesting;
final bool enableNullSafety;
- TargetFlags(
+ const TargetFlags(
{this.trackWidgetCreation = false,
this.forceLateLoweringForTesting = false,
this.forceNoExplicitGetterCallsForTesting = false,
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index cc40d2ae..dfd9a79 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -322,12 +322,6 @@
}
}
- static bool isDartTypeSupported(DartType node) =>
- !isDartTypeNotSupported(node);
-
- static bool isDartTypeNotSupported(DartType node) =>
- node is TypedefType || node is NeverType;
-
static bool isExpressionSupported(Expression node) =>
!isExpressionNotSupported(node);
@@ -368,7 +362,6 @@
static bool isSupported(Node node) => !isNotSupported(node);
static bool isNotSupported(Node node) =>
- node is DartType && isDartTypeNotSupported(node) ||
node is Expression && isExpressionNotSupported(node) ||
node is Statement && isStatementNotSupported(node) ||
node is FunctionNode && node.body == null ||
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 3dcc63f..2f071d7 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -877,6 +877,8 @@
String visitFunctionType(FunctionType _) => "->";
String visitTypeParameterType(TypeParameterType _) => "par";
String visitInterfaceType(InterfaceType _) => "interface";
+ String visitNeverType(NeverType _) => "never";
+ String visitTypedefType(TypedefType _) => "typedef";
}
const TextSerializer<InvalidType> invalidTypeSerializer =
@@ -907,6 +909,13 @@
BottomType wrapBottomType(void ignored) => const BottomType();
+const TextSerializer<NeverType> neverTypeSerializer =
+ const Wrapped(unwrapNeverType, wrapNeverType, const Nothing());
+
+void unwrapNeverType(NeverType type) {}
+
+NeverType wrapNeverType(void ignored) => const NeverType(Nullability.legacy);
+
// TODO(dmitryas): Also handle nameParameters, and typedefType.
TextSerializer<FunctionType> functionTypeSerializer = new Wrapped(
unwrapFunctionType,
@@ -983,6 +992,21 @@
tuple.first.reference, Nullability.legacy, tuple.second);
}
+TextSerializer<TypedefType> typedefTypeSerializer = new Wrapped(
+ unwrapTypedefType,
+ wrapTypedefType,
+ Tuple2Serializer(const CanonicalNameSerializer(),
+ new ListSerializer(dartTypeSerializer)));
+
+Tuple2<CanonicalName, List<DartType>> unwrapTypedefType(TypedefType node) {
+ return new Tuple2(node.typedefReference.canonicalName, node.typeArguments);
+}
+
+TypedefType wrapTypedefType(Tuple2<CanonicalName, List<DartType>> tuple) {
+ return new TypedefType.byReference(
+ tuple.first.reference, Nullability.legacy, tuple.second);
+}
+
Case<DartType> dartTypeSerializer =
new Case.uninitialized(const DartTypeTagger());
@@ -1503,6 +1527,8 @@
"->": functionTypeSerializer,
"par": typeParameterTypeSerializer,
"interface": interfaceTypeSerializer,
+ "never": neverTypeSerializer,
+ "typedef": typedefTypeSerializer,
});
statementSerializer.registerTags({
"expr": expressionStatementSerializer,
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index cca8d49..a9e3e13 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -441,6 +441,17 @@
}
/// Transform the given [libraries].
+ ///
+ /// The libraries from [module] is searched for the Widget class,
+ /// the _Location class and the _HasCreationLocation class.
+ /// If the component does not contain them, the ones from a previous run is
+ /// used (if any), otherwise no transformation is performed.
+ ///
+ /// Upon transformation the [changedStructureNotifier] (if provided) is used
+ /// to notify the listener that that class hierarchy of certain classes has
+ /// changed. This is neccesary for instance when doing an incremental
+ /// compilation where the class hierarchy is kept between compiles and thus
+ /// has to be kept up to date.
void transform(Component module, List<Library> libraries,
ChangedStructureNotifier changedStructureNotifier) {
if (libraries.isEmpty) {
diff --git a/pkg/kernel/lib/transformations/type_casts_optimizer.dart b/pkg/kernel/lib/transformations/type_casts_optimizer.dart
new file mode 100644
index 0000000..4df790f
--- /dev/null
+++ b/pkg/kernel/lib/transformations/type_casts_optimizer.dart
@@ -0,0 +1,101 @@
+// 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';
+import 'package:kernel/type_environment.dart'
+ show StaticTypeContext, SubtypeCheckMode, TypeEnvironment;
+
+// Removes redundant type casts and reduces casts to null checks.
+//
+// Handles the following patterns:
+// If S <: T (this includes S <: T? in weak mode)
+//
+// S x; x as T => x
+//
+// If S <: T? in strong mode
+//
+// S x; x as T => (x == null) ? x as T : x
+//
+TreeNode transformAsExpression(
+ AsExpression node, StaticTypeContext staticTypeContext, bool nullSafety) {
+ final DartType operandType = node.operand.getStaticType(staticTypeContext);
+ final env = staticTypeContext.typeEnvironment;
+
+ if (isRedundantTypeCast(node, operandType, env, nullSafety)) {
+ return node.operand;
+ }
+
+ if (canBeReducedToNullCheckAndCast(node, operandType, env, nullSafety)) {
+ // Transform 'x as T' to 'Let tmp = x in (tmp == null) ? tmp as T : tmp'.
+ final tmp =
+ VariableDeclaration(null, initializer: node.operand, type: operandType);
+ final dstType = node.type;
+ return Let(
+ tmp,
+ ConditionalExpression(
+ MethodInvocation(
+ VariableGet(tmp), Name('=='), Arguments([NullLiteral()])),
+ AsExpression(VariableGet(tmp), dstType)
+ ..flags = node.flags
+ ..fileOffset = node.fileOffset,
+ VariableGet(tmp, dstType),
+ dstType));
+ }
+
+ return node;
+}
+
+// Returns true if type cast [node] which has operand of the given
+// [operandStaticType] is redundant and can be removed (replaced with its
+// operand).
+bool isRedundantTypeCast(AsExpression node, DartType operandStaticType,
+ TypeEnvironment env, bool nullSafety) {
+ if (!_canBeTransformed(node)) {
+ return false;
+ }
+
+ return env.isSubtypeOf(
+ operandStaticType,
+ node.type,
+ nullSafety
+ ? SubtypeCheckMode.withNullabilities
+ : SubtypeCheckMode.ignoringNullabilities);
+}
+
+// Returns true if type cast [node] which has operand of the given
+// [operandStaticType] can be reduced to the null-check-and-cast pattern
+// 'Let tmp = [node.operand] in (tmp == null) ? tmp as T : tmp'.
+bool canBeReducedToNullCheckAndCast(AsExpression node,
+ DartType operandStaticType, TypeEnvironment env, bool nullSafety) {
+ if (!_canBeTransformed(node)) {
+ return false;
+ }
+
+ final DartType dst = node.type;
+
+ if (nullSafety && dst.nullability != Nullability.nullable) {
+ final nullableDst = dst.withDeclaredNullability(Nullability.nullable);
+ return env.isSubtypeOf(
+ operandStaticType, nullableDst, SubtypeCheckMode.withNullabilities);
+ }
+
+ return false;
+}
+
+bool _canBeTransformed(AsExpression node) {
+ if (node.isCovarianceCheck) {
+ // Keep casts inserted by the front-end to ensure soundness of
+ // covariant types.
+ return false;
+ }
+
+ final DartType dst = node.type;
+ if (dst is DynamicType || dst is InvalidType) {
+ // Keep casts to dynamic as they have zero overhead but change
+ // the semantics of calls. Also keep invalid types.
+ return false;
+ }
+
+ return true;
+}
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index 3f6d770..731e054 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -388,7 +388,7 @@
''');
_assertOverridePairs(c, []);
- _assertOverridePairs(e, ['test::A::foo overrides test::B::foo']);
+ _assertOverridePairs(e, ['test::A.foo overrides test::B.foo']);
}
/// An abstract member declared in the class is overridden by a member in
@@ -424,8 +424,8 @@
class E extends self::C {}
''');
- _assertOverridePairs(b, ['test::B::foo overrides test::A::foo']);
- _assertOverridePairs(c, ['test::C::foo overrides test::A::foo']);
+ _assertOverridePairs(b, ['test::B.foo overrides test::A.foo']);
+ _assertOverridePairs(c, ['test::C.foo overrides test::A.foo']);
_assertOverridePairs(d, []);
_assertOverridePairs(e, []);
}
@@ -454,7 +454,7 @@
// The documentation says:
// It is possible for two methods to override one another in both directions.
- _assertOverridePairs(b, ['test::B::foo overrides test::A::foo']);
+ _assertOverridePairs(b, ['test::B.foo overrides test::A.foo']);
}
/// 1. A member declared in the class overrides a member inheritable through
@@ -486,8 +486,8 @@
}
''');
- _assertOverridePairs(b, ['test::B::foo overrides test::A::foo']);
- _assertOverridePairs(c, ['test::C::bar overrides test::A::bar']);
+ _assertOverridePairs(b, ['test::B.foo overrides test::A.foo']);
+ _assertOverridePairs(c, ['test::C.bar overrides test::A.bar']);
}
/// 1. A member declared in the class overrides a member inheritable through
@@ -519,8 +519,8 @@
}
''');
- _assertOverridePairs(b, ['test::B::foo= overrides test::A::foo=']);
- _assertOverridePairs(c, ['test::C::bar= overrides test::A::bar=']);
+ _assertOverridePairs(b, ['test::B.foo= overrides test::A.foo=']);
+ _assertOverridePairs(c, ['test::C.bar= overrides test::A.bar=']);
}
void test_getClassAsInstanceOf_generic_extends() {
diff --git a/pkg/kernel/test/metadata_test.dart b/pkg/kernel/test/metadata_test.dart
index a6d285a..dd557fb 100644
--- a/pkg/kernel/test/metadata_test.dart
+++ b/pkg/kernel/test/metadata_test.dart
@@ -87,57 +87,55 @@
void close() {}
}
-/// Visitor that assigns [Metadata] object created with [Metadata.forNode] to
-/// each supported node in the component.
-class Annotator extends RecursiveVisitor<Null> {
- final TestMetadataRepository repository;
+typedef NodePredicate = bool Function(TreeNode node);
- Annotator(Component component)
- : repository = component.metadata[TestMetadataRepository.kTag];
+/// Visitor calling [handle] function on every node which can have metadata
+/// associated with it and also satisfies the given [predicate].
+class Visitor extends RecursiveVisitor<Null> {
+ final NodePredicate predicate;
+ final void Function(TreeNode) handle;
+
+ Visitor(this.predicate, this.handle);
defaultTreeNode(TreeNode node) {
super.defaultTreeNode(node);
- if (MetadataRepository.isSupported(node)) {
- repository.mapping[node] = new Metadata.forNode(node);
+ if (MetadataRepository.isSupported(node) && predicate(node)) {
+ handle(node);
}
}
-
- static void annotate(Component p) {
- globalDebuggingNames = new NameSystem();
- p.accept(new Annotator(p));
- }
}
-/// Visitor that checks that each supported node in the component has correct
-/// metadata.
-class Validator extends RecursiveVisitor<Null> {
- final TestMetadataRepository repository;
+/// Visit the given component assigning [Metadata] object created with
+/// [Metadata.forNode] to each supported node in the component which matches
+/// [shouldAnnotate] predicate.
+void annotate(Component p, NodePredicate shouldAnnotate) {
+ globalDebuggingNames = new NameSystem();
+ final repository = p.metadata[TestMetadataRepository.kTag];
+ p.accept(new Visitor(shouldAnnotate, (node) {
+ repository.mapping[node] = new Metadata.forNode(node);
+ }));
+}
- Validator(Component component)
- : repository = component.metadata[TestMetadataRepository.kTag];
+/// Visit the given component and checks that each supported node in the
+/// component matching [shouldAnnotate] predicate has correct metadata.
+void validate(Component p, NodePredicate shouldAnnotate) {
+ globalDebuggingNames = new NameSystem();
+ final repository = p.metadata[TestMetadataRepository.kTag];
+ p.accept(new Visitor(shouldAnnotate, (node) {
+ final m = repository.mapping[node];
+ final expected = new Metadata.forNode(node);
- defaultTreeNode(TreeNode node) {
- super.defaultTreeNode(node);
- if (MetadataRepository.isSupported(node)) {
- final m = repository.mapping[node];
- final expected = new Metadata.forNode(node);
-
- expect(m.string, equals(expected.string));
- expect(m.member, equals(expected.member));
- expect(m.type, equals(expected.type));
- }
- }
-
- static void validate(Component p) {
- globalDebuggingNames = new NameSystem();
- p.accept(new Validator(p));
- }
+ expect(m, isNotNull);
+ expect(m.string, equals(expected.string));
+ expect(m.member, equals(expected.member));
+ expect(m.type, equals(expected.type));
+ }));
}
Component fromBinary(List<int> bytes) {
var component = new Component();
component.addMetadataRepository(new TestMetadataRepository());
- new BinaryBuilderWithMetadata(bytes).readSingleFileComponent(component);
+ new BinaryBuilderWithMetadata(bytes).readComponent(component);
return component;
}
@@ -147,19 +145,53 @@
return sink.builder.takeBytes();
}
-main() {
- test('annotate-serialize-deserialize-validate', () async {
- final Uri platform = computePlatformBinariesLocation(forceBuildDir: true)
- .resolve("vm_platform_strong.dill");
- final List<int> platformBinary =
- await new File(platform.toFilePath()).readAsBytes();
+main() async {
+ bool anyNode(TreeNode node) => true;
+ bool onlyMethods(TreeNode node) =>
+ node is Procedure &&
+ node.kind == ProcedureKind.Method &&
+ node.enclosingClass != null;
+ final Uri platform = computePlatformBinariesLocation(forceBuildDir: true)
+ .resolve("vm_platform_strong.dill");
+ final List<int> platformBinary =
+ await new File(platform.toFilePath()).readAsBytes();
+
+ Future<void> testRoundTrip(List<int> Function(List<int>) binaryTransformer,
+ NodePredicate shouldAnnotate) async {
final component = fromBinary(platformBinary);
- Annotator.annotate(component);
- Validator.validate(component);
+ annotate(component, shouldAnnotate);
+ validate(component, shouldAnnotate);
+ expect(component.metadata[TestMetadataRepository.kTag].mapping.length,
+ greaterThan(0));
- final annotatedComponentBinary = toBinary(component);
+ final annotatedComponentBinary = binaryTransformer(toBinary(component));
final annotatedComponentFromBinary = fromBinary(annotatedComponentBinary);
- Validator.validate(annotatedComponentFromBinary);
+ validate(annotatedComponentFromBinary, shouldAnnotate);
+ expect(
+ annotatedComponentFromBinary
+ .metadata[TestMetadataRepository.kTag].mapping.length,
+ greaterThan(0));
+ }
+
+ test('annotate-serialize-deserialize-validate', () async {
+ await testRoundTrip((binary) => binary, anyNode);
+ });
+
+ test('annotate-serialize-deserialize-validate-only-methods', () async {
+ await testRoundTrip((binary) => binary, onlyMethods);
+ });
+
+ test('annotate-serialize-deserialize-twice-then-validate', () async {
+ // This test validates that serializing a component that was just
+ // deserialized (without visiting anything) works.
+ await testRoundTrip((binary) => toBinary(fromBinary(binary)), anyNode);
+ });
+
+ test('annotate-serialize-deserialize-twice-then-validate-only-methods',
+ () async {
+ // This test validates that serializing a component that was just
+ // deserialized (without visiting anything) works.
+ await testRoundTrip((binary) => toBinary(fromBinary(binary)), onlyMethods);
});
}
diff --git a/pkg/native_stack_traces/CHANGELOG.md b/pkg/native_stack_traces/CHANGELOG.md
index f11bcb7..9e00323 100644
--- a/pkg/native_stack_traces/CHANGELOG.md
+++ b/pkg/native_stack_traces/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog
+## 0.3.6
+
+- Adjusts RegExp for stack trace header line to be more flexible in what it
+ permits to allow additional information to be added in the Dart VM.
+
## 0.3.5
- Use virtual addresses in non-symbolic stack frames as a fallback if we cannot
diff --git a/pkg/native_stack_traces/lib/src/convert.dart b/pkg/native_stack_traces/lib/src/convert.dart
index 6ebde53..8f81c17 100644
--- a/pkg/native_stack_traces/lib/src/convert.dart
+++ b/pkg/native_stack_traces/lib/src/convert.dart
@@ -16,8 +16,12 @@
// Currently, this happens to include the only pieces of information from the
// stack trace header we need: the absolute addresses during program
// execution of the start of the isolate and VM instructions.
-final _headerEndRE =
- RegExp(r'isolate_instructions: ([\da-f]+) vm_instructions: ([\da-f]+)$');
+//
+// This RegExp has been adjusted to parse the header line found in
+// non-symbolic stack traces and the modified version in signal handler stack
+// traces.
+final _headerEndRE = RegExp(r'isolate_instructions(?:=|: )([\da-f]+),? '
+ r'vm_instructions(?:=|: )([\da-f]+)');
// Parses instructions section information into a new [StackTraceHeader].
//
diff --git a/pkg/native_stack_traces/pubspec.yaml b/pkg/native_stack_traces/pubspec.yaml
index ed4e44a..3b0ad2d 100644
--- a/pkg/native_stack_traces/pubspec.yaml
+++ b/pkg/native_stack_traces/pubspec.yaml
@@ -1,6 +1,6 @@
name: native_stack_traces
description: Utilities for working with non-symbolic stack traces.
-version: 0.3.5
+version: 0.3.6
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/native_stack_traces
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 903f254..7c7c68e 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -72,6 +72,8 @@
var nodeName = _computeNodeDeclarationName(node);
if (nodeName != null) {
parts.add(nodeName);
+ } else if (parts.isEmpty && node is VariableDeclarationList) {
+ parts.add(node.variables.first.declaredElement.name);
}
node = node.parent;
}
@@ -80,15 +82,7 @@
}
static String _computeNodeDeclarationName(AstNode node) {
- if (node is FieldDeclaration) {
- if (node.fields.variables.length == 1) {
- return node.fields.variables.single.declaredElement?.name;
- } else {
- // TODO(srawlins): Handle multiple fields declared at once; likely in
- // caller, not here.
- return null;
- }
- } else if (node is ExtensionDeclaration) {
+ if (node is ExtensionDeclaration) {
return node.declaredElement?.name ?? '<unnamed extension>';
} else if (node is Declaration) {
var name = node.declaredElement?.name;
@@ -289,6 +283,18 @@
/// Add a `/*!*/` hint to a type.
addNonNullableHint,
+
+ /// Change a `/*!*/` hint to a `/*?*/` hint.
+ changeToNullableHint,
+
+ /// Change a `/*?*/` hint to a `/*!*/` hint.
+ changeToNonNullableHint,
+
+ /// Remove a `/*?*/` hint.
+ removeNullableHint,
+
+ /// Remove a `/*!*/` hint.
+ removeNonNullableHint,
}
/// Abstract interface for assigning ids numbers to nodes, and performing
@@ -510,6 +516,14 @@
return 'Add /*?*/ hint';
case HintActionKind.addNonNullableHint:
return 'Add /*!*/ hint';
+ case HintActionKind.removeNullableHint:
+ return 'Remove /*?*/ hint';
+ case HintActionKind.removeNonNullableHint:
+ return 'Remove /*!*/ hint';
+ case HintActionKind.changeToNullableHint:
+ return 'Change to /*?*/ hint';
+ case HintActionKind.changeToNonNullableHint:
+ return 'Change to /*!*/ hint';
}
assert(false);
diff --git a/pkg/nnbd_migration/lib/isolate_server.dart b/pkg/nnbd_migration/lib/isolate_server.dart
deleted file mode 100644
index c4ecfa2..0000000
--- a/pkg/nnbd_migration/lib/isolate_server.dart
+++ /dev/null
@@ -1,164 +0,0 @@
-// 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 library implements [ServerBase], except unlike analysis_server_client's
-/// `Server`, [Server] runs the analysis server in an isolate.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:isolate';
-
-import 'package:analysis_server/starter.dart';
-import 'package:analysis_server_client/listener/server_listener.dart';
-import 'package:analysis_server_client/src/server_base.dart';
-import 'package:analysis_server_client/protocol.dart';
-import 'package:stream_channel/isolate_channel.dart';
-
-/// Wrap server arguments and communication port into a single parameter
-/// for [Isolate.spawn].
-class _IsolateParameters {
- final List<String> arguments;
- final SendPort sendPort;
-
- _IsolateParameters(this.arguments, this.sendPort);
-}
-
-/// Manage an analysis_server launched in an isolate.
-class Server extends ServerBase {
- /// Server isolate object, or `null` if server hasn't been started yet
- /// or if the server has already been stopped.
- Isolate _isolate;
-
- /// The [ReceivePort] data subscription via an [IsolateChannel], or `null`
- /// if either [listenToOutput] has not been called or [stop] has been called.
- StreamSubscription<String> _receiveSubscription;
-
- /// Construct a Server.
- ///
- /// [isolate] and [isolateChannel] are testing-only parameters, allowing
- /// you to bypass start().
- Server(
- {ServerListener listener,
- Isolate isolate,
- IsolateChannel isolateChannel,
- bool stdioPassthrough = false})
- : _isolate = isolate,
- _isolateChannel = isolateChannel,
- super(listener: listener, stdioPassthrough: stdioPassthrough);
-
- /// Completes when the [_isolate] has exited.
- Completer isolateExited = Completer();
-
- /// The [IsolateChannel] by which this class communicates with the [_isolate].
- IsolateChannel _isolateChannel;
-
- /// Force kill the server. The returned future completes when the isolate
- /// is dead.
- Future<void> kill({String reason = 'none'}) {
- listener?.killingServerProcess(reason);
- final isolate = _isolate;
- final isolateExitedOriginal = isolateExited;
- _isolate = null;
- isolateExited = null;
- isolate.kill(priority: Isolate.immediate);
- return isolateExitedOriginal.future;
- }
-
- /// Start listening to output from the server,
- /// and deliver notifications to [notificationProcessor].
- void listenToOutput({NotificationProcessor notificationProcessor}) {
- _receiveSubscription = _isolateChannel.stream
- .transform(utf8.decoder)
- .transform(LineSplitter())
- .listen((line) => outputProcessor(line, notificationProcessor));
- }
-
- /// Send a command to the server. An 'id' will be automatically assigned.
- /// The returned [Future] will be completed when the server acknowledges
- /// the command with a response.
- /// If the server acknowledges the command with a normal (non-error) response,
- /// the future will be completed with the 'result' field from the response.
- /// If the server acknowledges the command with an error response,
- /// the future will be completed with an error.
- Future<Map<String, dynamic>> send(
- String method, Map<String, dynamic> params) =>
- sendCommandWith(method, params, _isolateChannel.sink.add);
-
- /// Start the server in a new [Isolate].
- Future start({
- String clientId,
- String clientVersion,
- int diagnosticPort,
- String instrumentationLogFile,
- String sdkPath,
- bool suppressAnalytics = true,
- bool useAnalysisHighlight2 = false,
- }) async {
- if (_isolate != null) {
- throw Exception('Isolate already started');
- }
-
- // Even though this is an isolate, most of the analysis server code
- // can't tell the difference. So we construct "command line" arguments
- // just the same as analysis_server_client.
- List<String> arguments = [];
- arguments.addAll(getServerArguments(
- clientId: clientId,
- clientVersion: clientVersion,
- suppressAnalytics: suppressAnalytics,
- diagnosticPort: diagnosticPort,
- instrumentationLogFile: instrumentationLogFile,
- sdkPath: sdkPath,
- useAnalysisHighlight2: useAnalysisHighlight2));
-
- listener?.startingServer('((isolate))', arguments);
- ReceivePort receivePort = ReceivePort();
- ReceivePort onExitReceivePort = ReceivePort();
- ReceivePort onErrorReceivePort = ReceivePort();
- onExitReceivePort.listen((_) {
- isolateExited.complete(0);
- });
- onErrorReceivePort.listen((_) {
- listener?.unexpectedStop(null);
- });
- _isolateChannel = IsolateChannel<List<int>>.connectReceive(receivePort);
- _isolate = await Isolate.spawn(
- _runIsolate, _IsolateParameters(arguments, receivePort.sendPort),
- onExit: onExitReceivePort.sendPort);
- }
-
- /// This is the function passed to [Isolate.spawn] to actually begin
- /// the server.
- static void _runIsolate(_IsolateParameters parameters) {
- ServerStarter starter = ServerStarter();
- // TODO(jcollins-g): consider a refactor that does not require passing
- // text arguments to start the server.
- starter.start(parameters.arguments, parameters.sendPort);
- }
-
- /// Attempt to gracefully shutdown the server.
- /// If that fails, then kill the isolate.
- Future<void> stop({Duration timeLimit}) async {
- timeLimit ??= const Duration(seconds: 5);
- if (_isolate == null) {
- // isolate already exited
- return;
- }
- final future = send(SERVER_REQUEST_SHUTDOWN, null);
- final isolate = _isolate;
- _isolate = null;
- await future
- // fall through to wait for exit
- .timeout(timeLimit, onTimeout: () {
- return null;
- }).whenComplete(() async {
- await _receiveSubscription?.cancel();
- _receiveSubscription = null;
- });
- return isolateExited.future.timeout(timeLimit, onTimeout: () {
- listener?.killingServerProcess('server failed to exit');
- isolate.kill(priority: Isolate.immediate);
- });
- }
-}
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index f7bb4f6..88df6f6 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -5,11 +5,7 @@
import 'dart:async';
import 'dart:io' hide File;
-import 'package:analysis_server/src/api_for_nnbd_migration.dart';
-import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
-import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart'
@@ -27,6 +23,8 @@
import 'package:cli_util/cli_logging.dart';
import 'package:meta/meta.dart';
import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
+import 'package:nnbd_migration/src/front_end/driver_provider_impl.dart';
import 'package:nnbd_migration/src/front_end/non_nullable_fix.dart';
import 'package:nnbd_migration/src/utilities/source_edit_diff_formatter.dart';
import 'package:path/path.dart' show Context;
@@ -139,7 +137,7 @@
final Map<String, LineInfo> lineInfo = {};
- _DartFixListener _dartFixListener;
+ DartFixListener _dartFixListener;
_FixCodeProcessor _fixCodeProcessor;
@@ -265,7 +263,7 @@
contextCollection.contexts.single as DriverBasedAnalysisContext;
_fixCodeProcessor = _FixCodeProcessor(context, this);
_dartFixListener =
- _DartFixListener(_DriverProvider(resourceProvider, context));
+ DartFixListener(DriverProviderImpl(resourceProvider, context));
nonNullableFix = NonNullableFix(_dartFixListener, resourceProvider,
included: [options.directory],
preferredPort: options.previewPort,
@@ -412,11 +410,11 @@
}
}
- void _displayChangeSummary(_DartFixListener migrationResults) {
- Map<String, List<_DartFixSuggestion>> fileSuggestions = {};
- for (_DartFixSuggestion suggestion in migrationResults.suggestions) {
+ void _displayChangeSummary(DartFixListener migrationResults) {
+ Map<String, List<DartFixSuggestion>> fileSuggestions = {};
+ for (DartFixSuggestion suggestion in migrationResults.suggestions) {
String file = suggestion.location.file;
- fileSuggestions.putIfAbsent(file, () => <_DartFixSuggestion>[]);
+ fileSuggestions.putIfAbsent(file, () => <DartFixSuggestion>[]);
fileSuggestions[file].add(suggestion);
}
@@ -579,81 +577,11 @@
_BadArgException(this.message);
}
-class _DartFixListener implements DartFixListenerInterface {
- @override
- final DriverProvider server;
-
- @override
- final SourceChange sourceChange = SourceChange('null safety migration');
-
- final List<_DartFixSuggestion> suggestions = [];
-
- _DartFixListener(this.server);
-
- @override
- void addDetail(String detail) {
- throw UnimplementedError('TODO(paulberry)');
- }
-
- @override
- void addEditWithoutSuggestion(Source source, SourceEdit edit) {
- sourceChange.addEdit(source.fullName, -1, edit);
- }
-
- @override
- void addRecommendation(String description, [Location location]) {
- throw UnimplementedError('TODO(paulberry)');
- }
-
- @override
- void addSourceFileEdit(
- String description, Location location, SourceFileEdit fileEdit) {
- suggestions.add(_DartFixSuggestion(description, location: location));
- for (var sourceEdit in fileEdit.edits) {
- sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
- }
- }
-
- @override
- void addSuggestion(String description, Location location) {
- suggestions.add(_DartFixSuggestion(description, location: location));
- }
-
- /// Reset this listener so that it can accrue a new set of changes.
- void reset() {
- suggestions.clear();
- sourceChange
- ..edits.clear()
- ..linkedEditGroups.clear()
- ..selection = null
- ..id = null;
- }
-}
-
-class _DartFixSuggestion {
- final String description;
-
- final Location location;
-
- _DartFixSuggestion(this.description, {@required this.location});
-}
-
-class _DriverProvider implements DriverProvider {
- @override
- final ResourceProvider resourceProvider;
-
- final AnalysisContext analysisContext;
-
- _DriverProvider(this.resourceProvider, this.analysisContext);
-
- @override
- AnalysisSession getAnalysisSession(String path) =>
- analysisContext.currentSession;
-}
-
-class _FixCodeProcessor extends Object with FixCodeProcessor {
+class _FixCodeProcessor extends Object {
final DriverBasedAnalysisContext context;
+ NonNullableFix _task;
+
Set<String> pathsToProcess;
_ProgressBar _progressBar;
@@ -711,12 +639,16 @@
}
}
+ void registerCodeTask(NonNullableFix task) {
+ _task = task;
+ }
+
Future<void> runFirstPhase() async {
// All tasks should be registered; [numPhases] should be finalized.
- _progressBar = _ProgressBar(pathsToProcess.length * numPhases);
+ _progressBar = _ProgressBar(pathsToProcess.length * _task.numPhases);
// Process package
- await processPackage(context.contextRoot.root);
+ await _task.processPackage(context.contextRoot.root);
// Process each source file.
await processResources((ResolvedUnitResult result) async {
@@ -730,19 +662,19 @@
}
if (_migrationCli.options.ignoreErrors ||
_migrationCli.fileErrors.isEmpty) {
- await processCodeTasks(0, result);
+ await _task.processUnit(0, result);
}
});
}
Future<List<String>> runLaterPhases() async {
- for (var phase = 1; phase < numPhases; phase++) {
+ for (var phase = 1; phase < _task.numPhases; phase++) {
await processResources((ResolvedUnitResult result) async {
_progressBar.tick();
- await processCodeTasks(phase, result);
+ await _task.processUnit(phase, result);
});
}
- await finishCodeTasks();
+ await _task.finish();
_progressBar.complete();
return nonNullableFixTask.previewUrls;
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 3670f37..ee0201b 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -757,6 +757,8 @@
var origin = FieldFormalParameterOrigin(source, node);
if (node.type == null) {
_linkDecoratedTypes(parameterType, fieldType, origin, isUnion: false);
+ _checkAssignment(origin, FixReasonTarget.root,
+ source: fieldType, destination: parameterType, hard: false);
} else {
_dispatch(node.type);
_checkAssignment(origin, FixReasonTarget.root,
@@ -2967,9 +2969,7 @@
/// [destination]. [origin] should be used as the origin for any edges
/// created. [hard] indicates whether a hard edge should be created.
/// [sourceIsFunctionLiteral] indicates whether the source of the assignment
- /// is a function literal expression. [sourceIsSetupCall] indicates whether
- /// the source of the assignment is a function literal passed to the test
- /// package's `setUp` function.
+ /// is a function literal expression.
void _checkAssignment(EdgeOrigin origin, FixReasonTarget edgeTarget,
{@required DecoratedType source,
@required DecoratedType destination,
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index 1a0cefd..47d8aa5 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -640,10 +640,50 @@
}
/// Implementation of [NodeChange] specialized for operating on
-/// [FieldFormalParameter] nodes which are function-typed formal parameters.
+/// [FieldFormalParameter] nodes.
class NodeChangeForFieldFormalParameter
extends NodeChangeForType<FieldFormalParameter> {
+ /// If not `null`, an explicit type annotation that should be added to the
+ /// parameter.
+ DartType addExplicitType;
+
NodeChangeForFieldFormalParameter() : super._();
+
+ @override
+ Iterable<String> get _toStringParts =>
+ [if (addExplicitType != null) 'addExplicitType'];
+
+ @override
+ EditPlan _apply(FieldFormalParameter node, FixAggregator aggregator) {
+ if (addExplicitType != null) {
+ var typeText = aggregator.typeToCode(addExplicitType);
+ // Even a field formal parameter can use `var`, `final`.
+ if (node.keyword?.keyword == Keyword.VAR) {
+ // TODO(srawlins): Test instrumentation info.
+ var info =
+ AtomicEditInfo(NullabilityFixDescription.replaceVar(typeText), {});
+ return aggregator.planner.passThrough(node, innerPlans: [
+ aggregator.planner
+ .replaceToken(node, node.keyword, typeText, info: info),
+ ...aggregator.innerPlansForNode(node),
+ ]);
+ } else {
+ // TODO(srawlins): Test instrumentation info.
+ var info =
+ AtomicEditInfo(NullabilityFixDescription.addType(typeText), {});
+ var offset = node.thisKeyword.offset;
+ return aggregator.planner.passThrough(node, innerPlans: [
+ aggregator.planner.insertText(node, offset, [
+ AtomicEdit.insert(typeText, info: info),
+ AtomicEdit.insert(' ')
+ ]),
+ ...aggregator.innerPlansForNode(node),
+ ]);
+ }
+ } else {
+ return super._apply(node, aggregator);
+ }
+ }
}
/// Implementation of [NodeChange] specialized for operating on
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 8ac7da1..96c8338 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -929,9 +929,22 @@
@override
void visitFieldFormalParameter(FieldFormalParameter node) {
- // Field formal parameter types are generally handled in [visitTypeName],
- // _function-typed_ field formal parameters need to be handled here.
- if (node.parameters != null) {
+ if (node.type == null) {
+ // Potentially add an explicit type to a field formal parameter.
+ var decl = node.declaredElement as FieldFormalParameterElement;
+ var decoratedType = _fixBuilder._variables.decoratedElementType(decl);
+ var decoratedFieldType =
+ _fixBuilder._variables.decoratedElementType(decl.field);
+ var typeToAdd = _fixBuilder._variables.toFinalType(decoratedType);
+ var fieldFinalType =
+ _fixBuilder._variables.toFinalType(decoratedFieldType);
+ if (typeToAdd is InterfaceType &&
+ !_fixBuilder._typeSystem.isSubtypeOf(fieldFinalType, typeToAdd)) {
+ (_fixBuilder._getChange(node) as NodeChangeForFieldFormalParameter)
+ .addExplicitType = typeToAdd;
+ }
+ } else if (node.parameters != null) {
+ // Handle function-typed field formal parameters.
var decoratedType =
_fixBuilder._variables.decoratedElementType(node.declaredElement);
if (decoratedType.node.isNullable) {
diff --git a/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart b/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart
new file mode 100644
index 0000000..0ff6f8c
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart
@@ -0,0 +1,73 @@
+// 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/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ hide AnalysisError;
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/src/front_end/driver_provider_impl.dart';
+
+class DartFixListener {
+ final DriverProviderImpl server;
+
+ final SourceChange sourceChange = SourceChange('null safety migration');
+
+ final List<DartFixSuggestion> suggestions = [];
+
+ DartFixListener(this.server);
+
+ /// Add the given [detail] to the list of details to be returned to the
+ /// client.
+ void addDetail(String detail) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+
+ /// Record an edit to be sent to the client.
+ ///
+ /// The associated suggestion should be separately added by calling
+ /// [addSuggestion].
+ void addEditWithoutSuggestion(Source source, SourceEdit edit) {
+ sourceChange.addEdit(source.fullName, -1, edit);
+ }
+
+ /// Record a recommendation to be sent to the client.
+ void addRecommendation(String description, [Location location]) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+
+ /// Record a source change to be sent to the client.
+ void addSourceFileEdit(
+ String description, Location location, SourceFileEdit fileEdit) {
+ suggestions.add(DartFixSuggestion(description, location: location));
+ for (var sourceEdit in fileEdit.edits) {
+ sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
+ }
+ }
+
+ /// Record a suggestion to be sent to the client.
+ ///
+ /// The associated edits should be separately added by calling
+ /// [addEditWithoutRecommendation].
+ void addSuggestion(String description, Location location) {
+ suggestions.add(DartFixSuggestion(description, location: location));
+ }
+
+ /// Reset this listener so that it can accrue a new set of changes.
+ void reset() {
+ suggestions.clear();
+ sourceChange
+ ..edits.clear()
+ ..linkedEditGroups.clear()
+ ..selection = null
+ ..id = null;
+ }
+}
+
+class DartFixSuggestion {
+ final String description;
+
+ final Location location;
+
+ DartFixSuggestion(this.description, {@required this.location});
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/driver_provider_impl.dart b/pkg/nnbd_migration/lib/src/front_end/driver_provider_impl.dart
new file mode 100644
index 0000000..340d5c7
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/front_end/driver_provider_impl.dart
@@ -0,0 +1,20 @@
+// 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/analysis_context.dart';
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
+
+class DriverProviderImpl {
+ final ResourceProvider resourceProvider;
+
+ final AnalysisContext analysisContext;
+
+ DriverProviderImpl(this.resourceProvider, this.analysisContext);
+
+ /// Return the appropriate analysis session for the file with the given
+ /// [path].
+ AnalysisSession getAnalysisSession(String path) =>
+ analysisContext.currentSession;
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
index cc9580f..bf77587 100644
--- a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -4,7 +4,6 @@
import 'dart:collection';
-import 'package:analysis_server/src/api_for_nnbd_migration.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -18,6 +17,8 @@
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
+import 'package:nnbd_migration/src/front_end/driver_provider_impl.dart';
import 'package:nnbd_migration/src/front_end/instrumentation_information.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
@@ -37,7 +38,7 @@
final InstrumentationInformation info;
/// The listener used to gather the changes to be applied.
- final DartFixListenerInterface listener;
+ final DartFixListener listener;
/// The [NullabilityMigration] instance for this migration.
final NullabilityMigration migration;
@@ -51,7 +52,7 @@
this.migration, this.nodeMapper);
/// The provider used to get information about libraries.
- DriverProvider get driverProvider => listener.server;
+ DriverProviderImpl get driverProvider => listener.server;
/// Return the migration information for all of the libraries that were
/// migrated.
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
index afae8bd..8f62adb 100644
--- a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
@@ -93,15 +93,11 @@
var links = <UnitLink>[];
for (var unit in units) {
var count = unit.fixRegions.length;
- links.add(UnitLink(
- _pathTo(target: unit), pathContext.split(computeName(unit)), count));
+ links.add(
+ UnitLink(unit.path, pathContext.split(computeName(unit)), count));
}
return links;
}
-
- /// The path to [target], as an HTTP URI path, using forward slash separators.
- String _pathTo({@required UnitInfo target}) =>
- '/' + pathContext.split(target.path).skip(1).join('/');
}
/// A location from or to which a user might want to navigate.
@@ -298,38 +294,42 @@
_diskContentHash, md5.convert((checkContent ?? '').codeUnits).bytes);
}
- void handleInsertion(int offset, String replacement) {
+ void handleSourceEdit(SourceEdit sourceEdit) {
final contentCopy = content;
final regionsCopy = List<RegionInfo>.from(regions);
- final length = replacement.length;
- final migratedOffset = offsetMapper.map(offset);
+ final insertLength = sourceEdit.replacement.length;
+ final deleteLength = sourceEdit.length;
+ final migratedOffset = offsetMapper.map(sourceEdit.offset);
+ final diskOffset = diskChangesOffsetMapper.map(sourceEdit.offset);
+ if (migratedOffset == null || diskOffset == null) {
+ throw StateError('cannot apply replacement, offset has been deleted.');
+ }
try {
- content =
- content.replaceRange(migratedOffset, migratedOffset, replacement);
+ content = content.replaceRange(migratedOffset,
+ migratedOffset + deleteLength, sourceEdit.replacement);
regions.clear();
- regions.addAll(regionsCopy.map((region) {
- if (region.offset < migratedOffset) {
- return region;
- }
- // TODO: perhaps this should be handled by offset mapper instead, since
- // offset mapper handles navigation, edits, and traces, and this is the
- // odd ball out.
- return RegionInfo(
- region.regionType,
- region.offset + length,
- region.length,
- region.lineNumber,
- region.explanation,
- region.kind,
- region.isCounted,
- edits: region.edits,
- traces: region.traces);
- }));
+ regions.addAll(regionsCopy
+ .where((region) => region.offset + region.length <= migratedOffset));
+ regions.addAll(regionsCopy
+ .where((region) => region.offset >= migratedOffset + deleteLength)
+ .map((region) => RegionInfo(
+ region.regionType,
+ // TODO: perhaps this should be handled by offset mapper instead,
+ // since offset mapper handles navigation, edits, and traces, and
+ // this is the odd ball out.
+ region.offset + insertLength - deleteLength,
+ region.length,
+ region.lineNumber,
+ region.explanation,
+ region.kind,
+ region.isCounted,
+ edits: region.edits,
+ traces: region.traces)));
diskChangesOffsetMapper = OffsetMapper.sequence(
diskChangesOffsetMapper,
- OffsetMapper.forInsertion(
- diskChangesOffsetMapper.map(offset), length));
+ OffsetMapper.forReplacement(
+ diskOffset, deleteLength, sourceEdit.replacement));
} catch (e) {
regions.clear();
regions.addAll(regionsCopy);
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_state.dart b/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
index f61a5fd..adb249f 100644
--- a/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_state.dart
@@ -2,9 +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:analysis_server/src/api_for_nnbd_migration.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
import 'package:nnbd_migration/src/front_end/info_builder.dart';
import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
@@ -24,7 +24,7 @@
final NodeMapper nodeMapper = SimpleNodeMapper();
/// The listener used to collect fixes.
- final DartFixListenerInterface listener;
+ final DartFixListener listener;
/// The listener that collected information during the migration.
final InstrumentationListener instrumentationListener;
diff --git a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
index 09d975c..8dc7ffe 100644
--- a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
@@ -47,6 +47,7 @@
var linksGroupedByDirectory = _groupBy(
links.where((link) => link.depth > depth),
(UnitLink link) => link.pathParts[depth]);
+
return [
for (var entry in linksGroupedByDirectory.entries)
NavigationTreeNode.directory(
@@ -57,7 +58,7 @@
NavigationTreeNode.file(
name: link.fileName,
path: pathContext.joinAll(link.pathParts),
- href: link.url,
+ href: pathMapper.map(link.fullPath),
editCount: link.editCount,
),
];
diff --git a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
index e479335..2fa4073 100644
--- a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
@@ -2,11 +2,6 @@
// 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/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/api_for_nnbd_migration.dart';
-import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
-import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
-import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -15,6 +10,7 @@
import 'package:charcode/charcode.dart';
import 'package:meta/meta.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
import 'package:nnbd_migration/src/front_end/migration_state.dart';
import 'package:nnbd_migration/src/front_end/migration_summary.dart';
@@ -26,7 +22,7 @@
/// [NonNullableFix] visits each named type in a resolved compilation unit
/// and determines whether the associated variable or parameter can be null
/// then adds or removes a '?' trailing the named type as appropriate.
-class NonNullableFix extends FixCodeTask {
+class NonNullableFix {
/// TODO(paulberry): stop using permissive mode once the migration logic is
/// mature enough.
static const bool _usePermissiveMode = true;
@@ -42,7 +38,7 @@
final int preferredPort;
- final DartFixListenerInterface listener;
+ final DartFixListener listener;
/// The root of the included paths.
///
@@ -95,10 +91,8 @@
reset();
}
- @override
int get numPhases => 3;
- @override
Future<void> finish() async {
migration.finish();
final state = MigrationState(
@@ -126,7 +120,6 @@
/// Update the pubspec.yaml file to specify a minimum Dart SDK version which
/// enables the Null Safety feature.
- @override
Future<void> processPackage(Folder pkgFolder) async {
if (!_packageIsNNBD) {
return;
@@ -223,7 +216,6 @@
}
}
- @override
Future<void> processUnit(int phase, ResolvedUnitResult result) async {
if (!_packageIsNNBD) {
return;
@@ -293,13 +285,6 @@
_allServers.clear();
}
- static void task(DartFixRegistrar registrar, DartFixListener listener,
- EditDartfixParams params) {
- registrar.registerCodeTask(NonNullableFix(
- listener, listener.resourceProvider,
- included: params.included, preferredPort: params.port));
- }
-
/// Get the "root" of all [included] paths. See [includedRoot] for its
/// definition.
static String _getIncludedRoot(
@@ -331,7 +316,7 @@
}
class NullabilityMigrationAdapter implements NullabilityMigrationListener {
- final DartFixListenerInterface listener;
+ final DartFixListener listener;
NullabilityMigrationAdapter(this.listener);
diff --git a/pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart b/pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart
index f53fd79..0ff2d76 100644
--- a/pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/offset_mapper.dart
@@ -16,9 +16,19 @@
/// Return a mapper representing the file modified by an insertion at [offset]
/// the given with [length].
factory OffsetMapper.forInsertion(int offset, int length) =>
- _SimpleInsertionMapper(offset, length);
+ _SimpleSourceEditMapper(offset, 0, length);
+
+ /// Return a mapper representing the file modified by an insertion at [offset]
+ /// with [replacemnet] text overwriting the given [length].
+ factory OffsetMapper.forReplacement(
+ int offset, int length, String replacement) =>
+ _SimpleSourceEditMapper(offset, length, replacement.length);
/// Return a mapper representing [rebased] rebased by [rebaser].
+ ///
+ /// Warning: this does not currently handle cases where the [rebased] mapper
+ /// contains an insert or deletion in the middle of a range deleted by
+ /// [rebaser]. This is not a case that currently needs to be supported.
factory OffsetMapper.rebase(OffsetMapper rebaser, OffsetMapper rebased) {
return _RebasedOffsetMapper(rebaser, rebased);
}
@@ -30,7 +40,7 @@
}
/// Return the post-edit offset that corresponds to the given pre-edit
- /// [offset].
+ /// [offset], or `null` when that offset has been deleted.
int map(int offset);
}
@@ -97,6 +107,9 @@
int map(int offset) {
for (final mapper in innerMappers) {
offset = mapper.map(offset);
+ if (offset == null) {
+ break;
+ }
}
return offset;
}
@@ -110,17 +123,37 @@
@override
int map(int offset) {
- final delta = rebased.map(offset) - offset;
- return rebaser.map(offset) + delta;
+ final rebasedOffset = rebased.map(offset);
+ final rebasingOffset = rebaser.map(offset);
+ if (rebasedOffset == null || rebasingOffset == null) {
+ return null;
+ }
+ final delta = rebasedOffset - offset;
+ return rebasingOffset + delta;
}
}
-class _SimpleInsertionMapper implements OffsetMapper {
+class _SimpleSourceEditMapper implements OffsetMapper {
+ /// The offset where the replacement begins.
final int offset;
- final int length;
- _SimpleInsertionMapper(this.offset, this.length);
+ /// The length of text to be replaced.
+ final int replacedLength;
+
+ /// The length of text to be inserted as a replacement.
+ final int replacementLength;
+
+ _SimpleSourceEditMapper(
+ this.offset, this.replacedLength, this.replacementLength);
@override
- int map(int offset) => offset < this.offset ? offset : offset + length;
+ int map(int offset) {
+ if (offset < this.offset) {
+ return offset;
+ }
+ if (offset < this.offset + replacedLength) {
+ return null;
+ }
+ return offset + replacementLength - replacedLength;
+ }
}
diff --git a/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart
index 120d232..2d97c61 100644
--- a/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/region_renderer.dart
@@ -37,7 +37,7 @@
TargetLink linkForTarget(NavigationTarget target) {
var relativePath = _relativePathToTarget(target, unitDir);
- var targetUri = _uriForRelativePath(relativePath, target);
+ var targetUri = _uriForPath(target.filePath, target);
return TargetLink(
path: relativePath,
href: targetUri,
@@ -57,7 +57,8 @@
}).toString());
var response = EditDetails(
- path: unitInfo.path,
+ displayPath: unitInfo.path,
+ uriPath: pathMapper.map(unitInfo.path),
line: region.lineNumber,
explanation: region.explanation,
edits: supportsIncrementalWorkflow
@@ -92,12 +93,12 @@
}
/// Return the URL that will navigate to the given [target] in the file at the
- /// given [relativePath].
- String _uriForRelativePath(String relativePath, NavigationTarget target) {
+ /// given [path].
+ String _uriForPath(String path, NavigationTarget target) {
var queryParams = {
'offset': target.offset,
if (target.line != null) 'line': target.line,
}.entries.map((entry) => '${entry.key}=${entry.value}').join('&');
- return '$relativePath?$queryParams';
+ return '${pathMapper.map(path)}?$queryParams';
}
}
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
index 0c21ff4..d1bf62a 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
@@ -422,7 +422,7 @@
border-top: 2px solid black;
border-radius: 7px;
box-shadow: 0px 0px 20px 2px #b4bfcb22;
- z-index: 1;
+ z-index: 400;
background: #2b3036;
padding: 20px;
}
@@ -541,7 +541,9 @@
margin: 3px;
}
-button, a.button {
+/* Careful here. `a.button` is repetitive but required to get correct
+ * specificity */
+button, .button, a.button {
background-color: #33ccff;
border: 2px solid #37aedc;
border-radius: 3px;
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
index ffab306..ef4f63a 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -327,7 +327,7 @@
''';
String _migration_css;
-// migration_css md5 is '48272ee82aad7512b42c6445e21eec48'
+// migration_css md5 is 'e7d5579e5a4661f81ce5734eff427a6d'
String _migration_css_base64 = '''
LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
@@ -438,52 +438,53 @@
cGxheTogbm9uZTsKICBwb3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAxNTBweDsKICBsZWZ0OiAxNTBweDsK
ICByaWdodDogMTUwcHg7CiAgYm90dG9tOiAxNTBweDsKICBib3JkZXI6IDFweCBzb2xpZCBibGFjazsK
ICBib3JkZXItdG9wOiAycHggc29saWQgYmxhY2s7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJveC1z
-aGFkb3c6IDBweCAwcHggMjBweCAycHggI2I0YmZjYjIyOwogIHotaW5kZXg6IDE7CiAgYmFja2dyb3Vu
-ZDogIzJiMzAzNjsKICBwYWRkaW5nOiAyMHB4Owp9CgoucG9wdXAtcGFuZSAuY2xvc2UgewogIHBvc2l0
-aW9uOiBhYnNvbHV0ZTsKICByaWdodDogMTBweDsKICB0b3A6IDEwcHg7CiAgY3Vyc29yOiBwb2ludGVy
-OwogIHRleHQtc2hhZG93OiAxcHggMXB4IDJweCAjODg4OwogIGJveC1zaGFkb3c6IDFweCAxcHggMnB4
-ICMxMTE7Cn0KCi5wb3B1cC1wYW5lIGgyIHsKICBwYWRkaW5nOiAyMXB4OwogIGhlaWdodDogMTAlOwog
-IG1hcmdpbjogMHB4OwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7Cn0KCi5wb3B1cC1wYW5lIHAgewog
-IGhlaWdodDogMTAlOwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7CiAgcGFkZGluZzogMHB4IDIwcHg7
-Cn0KCi5wb3B1cC1wYW5lIHByZSB7CiAgYmFja2dyb3VuZDogIzI4MmIyZTsKICBwYWRkaW5nOiAyMHB4
-OwogIGJvdHRvbTogMHB4OwogIG92ZXJmbG93OiBhdXRvIHNjcm9sbDsKICBoZWlnaHQ6IDY1JTsKICBt
-YXJnaW46IDBweDsKICBib3gtc2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9wdXAtcGFuZSAuYnV0dG9u
-LmJvdHRvbSB7CiAgbWFyZ2luOiAyMHB4IDBweDsKICBkaXNwbGF5OiBibG9jazsKICB0ZXh0LWFsaWdu
-OiBjZW50ZXI7Cn0KCi5yZXJ1bm5pbmctcGFuZSB7CiAgZGlzcGxheTogbm9uZTsKfQoKYm9keS5yZXJ1
-bm5pbmcgLnJlcnVubmluZy1wYW5lIHsKICBkaXNwbGF5OiBibG9jazsKICBwb3NpdGlvbjogZml4ZWQ7
-CiAgdG9wOiAwcHg7CiAgYm90dG9tOiAwcHg7CiAgbGVmdDogMHB4OwogIHJpZ2h0OiAwcHg7CiAgYmFj
-a2dyb3VuZC1jb2xvcjogIzAwMDAwMEFBOyAvKiB0cmFuc2x1Y2VudCBibGFjayAqLwogIHotaW5kZXg6
-IDQwMDsKfQoKLnJlcnVubmluZy1wYW5lIGgxIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdG9wOiA1
-MCU7CiAgbGVmdDogNTAlOwogIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpOwp9CgouZWRp
-dC1wYW5lbCAudHlwZS1kZXNjcmlwdGlvbiB7CiAgLyogRnJvbSBITEpTJ3MgLmhsanMta2V5d29yZCwg
-LmhsanMtc2VsZWN0b3ItdGFnLCAuaGxqcy1kZWxldGlvbiAqLwogIGNvbG9yOiAjY2M3ODMyOwogIGZv
-bnQtZmFtaWx5OiBtb25vc3BhY2U7Cn0KCnVsLnRyYWNlIHsKICBmb250LXNpemU6IDEzcHg7CiAgbGlz
-dC1zdHlsZS10eXBlOiBub25lOwogIHBhZGRpbmctbGVmdDogMHB4Owp9Cgp1bC50cmFjZSBsaSB7CiAg
-Y29sb3I6IHdoaXRlOwp9Cgp1bC50cmFjZSBsaSAuZnVuY3Rpb24gewogIC8qIEZyb20gSExKUydzIC5o
-bGpzLXNlY3Rpb24sIC5obGpzLXRpdGxlLCAuaGxqcy10eXBlICovCiAgY29sb3I6ICNmZmM2NmQ7CiAg
-Zm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKICBmb250LXdlaWdodDogNjAwOwp9Cgp1bC50cmFjZSBsaSBw
-LmRyYXdlciB7CiAgbWFyZ2luOiAzcHggMHB4OwogIHBhZGRpbmc6IDBweCAwcHggMHB4IDE0cHg7Cn0K
-CnVsLnRyYWNlIGxpIHAuZHJhd2VyIGJ1dHRvbiB7CiAgbWFyZ2luLXJpZ2h0OiAzcHg7Cn0KCi5lbGV2
-YXRpb24tejQgewogIGJveC1zaGFkb3c6IDBweCAycHggNHB4IC0xcHggcmdiYSgwLCAwLCAwLCAwLjIp
-LAogICAgICAwcHggNHB4IDVweCAwcHggcmdiYSgwLCAwLCAwLCAwLjE0KSwKICAgICAgMHB4IDFweCAx
-MHB4IDBweCByZ2JhKDAsIDAsIDAsIC4xMik7Cn0KCmEgewogIGNvbG9yOiAjY2NjOwogIGZpbGw6ICNj
-Y2M7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwp9CgphOmhvdmVyIHsKICBjb2xvcjogI2ZmZjsKICBm
-aWxsOiAjZmZmOwp9CgouYWRkLWhpbnQtbGluayB7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIG1h
-cmdpbjogM3B4Owp9CgpidXR0b24sIGEuYnV0dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzNjY2Zm
-OwogIGJvcmRlcjogMnB4IHNvbGlkICMzN2FlZGM7CiAgYm9yZGVyLXJhZGl1czogM3B4OwogIHBhZGRp
-bmc6IDZweCAxMHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGNvbG9yOiAjMjgyODI4Owp9CgpidXR0
-b246aG92ZXIsIC5idXR0b246aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6ICM4MGRmZmY7CiAgYm9y
-ZGVyOiAycHggc29saWQgIzUyYjhlMDsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCmJ1dHRvbltkaXNhYmxl
-ZF0gewogIGJhY2tncm91bmQtY29sb3I6ICM3YWE4Yjg7CiAgY29sb3I6ICM1MDcxNzc7CiAgYm9yZGVy
-OiAycHggc29saWQgIzUwNzE3NzsKICBjdXJzb3I6IG5vdC1hbGxvd2VkOwp9CgoucGxhY2Vob2xkZXIg
-ewogIGNvbG9yOiAjNzc3OwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBtYXJnaW4tdG9wOiAzZW0gIWlt
-cG9ydGFudDsKfQoKLyoqCiAqIEhMSlMgT3ZlcnJpZGVzCiAqLwouaGxqcyB7CiAgLyoqCiAgICogVGhp
-cyBhbGxvd3MgdGhlIHBlci1saW5lIGhpZ2hsaWdodHMgdG8gc2hvdy4KICAgKi8KICBiYWNrZ3JvdW5k
-OiBub25lOwp9Cg==
+aGFkb3c6IDBweCAwcHggMjBweCAycHggI2I0YmZjYjIyOwogIHotaW5kZXg6IDQwMDsKICBiYWNrZ3Jv
+dW5kOiAjMmIzMDM2OwogIHBhZGRpbmc6IDIwcHg7Cn0KCi5wb3B1cC1wYW5lIC5jbG9zZSB7CiAgcG9z
+aXRpb246IGFic29sdXRlOwogIHJpZ2h0OiAxMHB4OwogIHRvcDogMTBweDsKICBjdXJzb3I6IHBvaW50
+ZXI7CiAgdGV4dC1zaGFkb3c6IDFweCAxcHggMnB4ICM4ODg7CiAgYm94LXNoYWRvdzogMXB4IDFweCAy
+cHggIzExMTsKfQoKLnBvcHVwLXBhbmUgaDIgewogIHBhZGRpbmc6IDIxcHg7CiAgaGVpZ2h0OiAxMCU7
+CiAgbWFyZ2luOiAwcHg7CiAgYm94LXNpemluZzogYm9yZGVyLWJveDsKfQoKLnBvcHVwLXBhbmUgcCB7
+CiAgaGVpZ2h0OiAxMCU7CiAgYm94LXNpemluZzogYm9yZGVyLWJveDsKICBwYWRkaW5nOiAwcHggMjBw
+eDsKfQoKLnBvcHVwLXBhbmUgcHJlIHsKICBiYWNrZ3JvdW5kOiAjMjgyYjJlOwogIHBhZGRpbmc6IDIw
+cHg7CiAgYm90dG9tOiAwcHg7CiAgb3ZlcmZsb3c6IGF1dG8gc2Nyb2xsOwogIGhlaWdodDogNjUlOwog
+IG1hcmdpbjogMHB4OwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7Cn0KCi5wb3B1cC1wYW5lIC5idXR0
+b24uYm90dG9tIHsKICBtYXJnaW46IDIwcHggMHB4OwogIGRpc3BsYXk6IGJsb2NrOwogIHRleHQtYWxp
+Z246IGNlbnRlcjsKfQoKLnJlcnVubmluZy1wYW5lIHsKICBkaXNwbGF5OiBub25lOwp9Cgpib2R5LnJl
+cnVubmluZyAucmVydW5uaW5nLXBhbmUgewogIGRpc3BsYXk6IGJsb2NrOwogIHBvc2l0aW9uOiBmaXhl
+ZDsKICB0b3A6IDBweDsKICBib3R0b206IDBweDsKICBsZWZ0OiAwcHg7CiAgcmlnaHQ6IDBweDsKICBi
+YWNrZ3JvdW5kLWNvbG9yOiAjMDAwMDAwQUE7IC8qIHRyYW5zbHVjZW50IGJsYWNrICovCiAgei1pbmRl
+eDogNDAwOwp9CgoucmVydW5uaW5nLXBhbmUgaDEgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB0b3A6
+IDUwJTsKICBsZWZ0OiA1MCU7CiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7Cn0KCi5l
+ZGl0LXBhbmVsIC50eXBlLWRlc2NyaXB0aW9uIHsKICAvKiBGcm9tIEhMSlMncyAuaGxqcy1rZXl3b3Jk
+LCAuaGxqcy1zZWxlY3Rvci10YWcsIC5obGpzLWRlbGV0aW9uICovCiAgY29sb3I6ICNjYzc4MzI7CiAg
+Zm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKfQoKdWwudHJhY2UgewogIGZvbnQtc2l6ZTogMTNweDsKICBs
+aXN0LXN0eWxlLXR5cGU6IG5vbmU7CiAgcGFkZGluZy1sZWZ0OiAwcHg7Cn0KCnVsLnRyYWNlIGxpIHsK
+ICBjb2xvcjogd2hpdGU7Cn0KCnVsLnRyYWNlIGxpIC5mdW5jdGlvbiB7CiAgLyogRnJvbSBITEpTJ3Mg
+LmhsanMtc2VjdGlvbiwgLmhsanMtdGl0bGUsIC5obGpzLXR5cGUgKi8KICBjb2xvcjogI2ZmYzY2ZDsK
+ICBmb250LWZhbWlseTogbW9ub3NwYWNlOwogIGZvbnQtd2VpZ2h0OiA2MDA7Cn0KCnVsLnRyYWNlIGxp
+IHAuZHJhd2VyIHsKICBtYXJnaW46IDNweCAwcHg7CiAgcGFkZGluZzogMHB4IDBweCAwcHggMTRweDsK
+fQoKdWwudHJhY2UgbGkgcC5kcmF3ZXIgYnV0dG9uIHsKICBtYXJnaW4tcmlnaHQ6IDNweDsKfQoKLmVs
+ZXZhdGlvbi16NCB7CiAgYm94LXNoYWRvdzogMHB4IDJweCA0cHggLTFweCByZ2JhKDAsIDAsIDAsIDAu
+MiksCiAgICAgIDBweCA0cHggNXB4IDBweCByZ2JhKDAsIDAsIDAsIDAuMTQpLAogICAgICAwcHggMXB4
+IDEwcHggMHB4IHJnYmEoMCwgMCwgMCwgLjEyKTsKfQoKYSB7CiAgY29sb3I6ICNjY2M7CiAgZmlsbDog
+I2NjYzsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCmE6aG92ZXIgewogIGNvbG9yOiAjZmZmOwog
+IGZpbGw6ICNmZmY7Cn0KCi5hZGQtaGludC1saW5rIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAg
+bWFyZ2luOiAzcHg7Cn0KCi8qIENhcmVmdWwgaGVyZS4gYGEuYnV0dG9uYCBpcyByZXBldGl0aXZlIGJ1
+dCByZXF1aXJlZCB0byBnZXQgY29ycmVjdAogKiBzcGVjaWZpY2l0eSAqLwpidXR0b24sIC5idXR0b24s
+IGEuYnV0dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzNjY2ZmOwogIGJvcmRlcjogMnB4IHNvbGlk
+ICMzN2FlZGM7CiAgYm9yZGVyLXJhZGl1czogM3B4OwogIHBhZGRpbmc6IDZweCAxMHB4OwogIGZvbnQt
+d2VpZ2h0OiBib2xkOwogIGNvbG9yOiAjMjgyODI4Owp9CgpidXR0b246aG92ZXIsIC5idXR0b246aG92
+ZXIgewogIGJhY2tncm91bmQtY29sb3I6ICM4MGRmZmY7CiAgYm9yZGVyOiAycHggc29saWQgIzUyYjhl
+MDsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCmJ1dHRvbltkaXNhYmxlZF0gewogIGJhY2tncm91bmQtY29s
+b3I6ICM3YWE4Yjg7CiAgY29sb3I6ICM1MDcxNzc7CiAgYm9yZGVyOiAycHggc29saWQgIzUwNzE3NzsK
+ICBjdXJzb3I6IG5vdC1hbGxvd2VkOwp9CgoucGxhY2Vob2xkZXIgewogIGNvbG9yOiAjNzc3OwogIHRl
+eHQtYWxpZ246IGNlbnRlcjsKICBtYXJnaW4tdG9wOiAzZW0gIWltcG9ydGFudDsKfQoKLyoqCiAqIEhM
+SlMgT3ZlcnJpZGVzCiAqLwouaGxqcyB7CiAgLyoqCiAgICogVGhpcyBhbGxvd3MgdGhlIHBlci1saW5l
+IGhpZ2hsaWdodHMgdG8gc2hvdy4KICAgKi8KICBiYWNrZ3JvdW5kOiBub25lOwp9Cg==
''';
String _migration_js;
-// migration_dart md5 is 'a17b4fb1f36406ccc822638c6f0bd988'
+// migration_dart md5 is '45896e96651e161c6def4d377a5a9d10'
String _migration_js_base64 = '''
KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
@@ -882,8 +883,8 @@
Y3Rpb24oYSl7cmV0dXJuIGF9LApEUTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEludDhBcnJheShhKX0s
Cm9kOmZ1bmN0aW9uKGEsYixjKXtpZihhPj4+MCE9PWF8fGE+PWMpdGhyb3cgSC5iKEguSFkoYixhKSl9
LApyTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIShhPj4+MCE9PWEpKXQ9Yj4+PjAhPT1ifHxhPmJ8
-fGI+YwplbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIoSC5hdShhLGIsYykpCnJldHVybiBifSwKcEY6ZnVu
-Y3Rpb24gcEYoKXt9LApMWjpmdW5jdGlvbiBMWigpe30sCkRnOmZ1bmN0aW9uIERnKCl7fSwKUGc6ZnVu
+fGI+YwplbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIoSC5hdShhLGIsYykpCnJldHVybiBifSwKZUg6ZnVu
+Y3Rpb24gZUgoKXt9LApMWjpmdW5jdGlvbiBMWigpe30sCkRnOmZ1bmN0aW9uIERnKCl7fSwKUGc6ZnVu
Y3Rpb24gUGcoKXt9LAp4ajpmdW5jdGlvbiB4aigpe30sCmRFOmZ1bmN0aW9uIGRFKCl7fSwKWkE6ZnVu
Y3Rpb24gWkEoKXt9LAp3ZjpmdW5jdGlvbiB3Zigpe30sClBxOmZ1bmN0aW9uIFBxKCl7fSwKZUU6ZnVu
Y3Rpb24gZUUoKXt9LApWNjpmdW5jdGlvbiBWNigpe30sClJHOmZ1bmN0aW9uIFJHKCl7fSwKVlA6ZnVu
@@ -920,7 +921,7 @@
aW5zdGFuY2VvZiBILlRwKXt0PUguSlMoYSkKaWYodCE9bnVsbClyZXR1cm4gdH1yZXR1cm4gSC5xKGEp
fSwKcTpmdW5jdGlvbihhKXt2YXIgdAppZihhIGluc3RhbmNlb2YgUC5NaCl7dD1hLiR0aQpyZXR1cm4g
dCE9bnVsbD90OkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC50NihhKQpyZXR1cm4g
-SC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciB0PWFbdi5hcnJheVJ0aV0scz11Lm0KaWYo
+SC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciB0PWFbdi5hcnJheVJ0aV0scz11LmIKaWYo
dD09bnVsbClyZXR1cm4gcwppZih0LmNvbnN0cnVjdG9yIT09cy5jb25zdHJ1Y3RvcilyZXR1cm4gcwpy
ZXR1cm4gdH0sCkxoOmZ1bmN0aW9uKGEpe3ZhciB0PWEuJHRpCnJldHVybiB0IT1udWxsP3Q6SC5WVShh
KX0sClZVOmZ1bmN0aW9uKGEpe3ZhciB0PWEuY29uc3RydWN0b3Iscz10LiRjY2FjaGUKaWYocyE9bnVs
@@ -930,7 +931,7 @@
LHM9YSxyPXYudHlwZXMscT1yW3NdCmlmKHR5cGVvZiBxPT0ic3RyaW5nIil7dD1ILkUodi50eXBlVW5p
dmVyc2UscSwhMSkKcltzXT10CnJldHVybiB0fXJldHVybiBxfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHQ9
dGhpcyxzPUguWU8scj11LksKaWYodD09PXIpe3M9SC5rZQp0LmE9SC5UaX1lbHNlIGlmKEguQTgodCl8
-fHQ9PT1yKXtzPUguSXcKdC5hPUguaG59ZWxzZSBpZih0PT09dS5xKXM9SC5vawplbHNlIGlmKHQ9PT11
+fHQ9PT1yKXtzPUguSXcKdC5hPUguaG59ZWxzZSBpZih0PT09dS5wKXM9SC5vawplbHNlIGlmKHQ9PT11
LmdSKXM9SC5LSAplbHNlIGlmKHQ9PT11LmRpKXM9SC5LSAplbHNlIGlmKHQ9PT11Lk4pcz1ILk1NCmVs
c2UgaWYodD09PXUueSlzPUguclEKZWxzZSBpZih0Lnk9PT05KXtyPXQuegppZih0LlEuZXZlcnkoSC5j
Yykpe3Qucj0iJGkiK3IKcz1ILnQ0fX10LmI9cwpyZXR1cm4gdC5iKGEpfSwKWU86ZnVuY3Rpb24oYSl7
@@ -1174,7 +1175,7 @@
eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEou
YzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBK
LmtzKGEpfSwKaWE6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29y
-KGEpPT1hKXJldHVybiBKLnVyLnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9m
+KGEpPT1hKXJldHVybiBKLmJVLnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9m
IGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLllFLnBy
b3RvdHlwZQppZih0eXBlb2YgYT09ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNv
bnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3Qi
@@ -1206,2352 +1207,2343 @@
LAppZzpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5nUWcoYSl9LApsNTpmdW5jdGlvbihhLGIpe3Jl
dHVybiBKLlJFKGEpLnNoZihhLGIpfSwKbGQ6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLnJZKGEpLk5q
KGEsYixjKX0sCm06ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYT09Im51bWJlciImJnR5cGVvZiBiPT0i
-bnVtYmVyIilyZXR1cm4gYStiCnJldHVybiBKLlRKKGEpLmgoYSxiKX0sCnA0OmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIEouclkoYSkuVGMoYSxiKX0sCnEwOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5R
-aShhLGIsYyl9LApxRjpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5nVmwoYSl9LAp0SDpmdW5jdGlv
-bihhLGIsYyl7cmV0dXJuIEouUkUoYSkucGsoYSxiLGMpfSwKeDk6ZnVuY3Rpb24oYSxiKXtpZih0eXBl
-b2YgYj09PSJudW1iZXIiKWlmKGEuY29uc3RydWN0b3I9PUFycmF5fHx0eXBlb2YgYT09InN0cmluZyJ8
-fEgud1YoYSxhW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdKSlpZihiPj4+MD09PWImJmI8YS5sZW5ndGgp
-cmV0dXJuIGFbYl0KcmV0dXJuIEouVTYoYSkucShhLGIpfSwKemw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-Si5VNihhKS50ZyhhLGIpfSwKdkI6ZnVuY3Rpb24gdkIoKXt9LAp5RTpmdW5jdGlvbiB5RSgpe30sCllF
-OmZ1bmN0aW9uIFlFKCl7fSwKTUY6ZnVuY3Rpb24gTUYoKXt9LAppQzpmdW5jdGlvbiBpQygpe30sCmtk
-OmZ1bmN0aW9uIGtkKCl7fSwKYzU6ZnVuY3Rpb24gYzUoKXt9LApqZDpmdW5jdGlvbiBqZChhKXt0aGlz
-LiR0aT1hfSwKUG86ZnVuY3Rpb24gUG8oYSl7dGhpcy4kdGk9YX0sCm0xOmZ1bmN0aW9uIG0xKGEsYixj
-KXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8uJHRpPWN9LApxSTpmdW5jdGlv
-biBxSSgpe30sCnVyOmZ1bmN0aW9uIHVyKCl7fSwKVkE6ZnVuY3Rpb24gVkEoKXt9LApEcjpmdW5jdGlv
-biBEcigpe319LFA9ewpPajpmdW5jdGlvbigpe3ZhciB0LHMscj17fQppZihzZWxmLnNjaGVkdWxlSW1t
-ZWRpYXRlIT1udWxsKXJldHVybiBQLkVYKCkKaWYoc2VsZi5NdXRhdGlvbk9ic2VydmVyIT1udWxsJiZz
-ZWxmLmRvY3VtZW50IT1udWxsKXt0PXNlbGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2IikKcz1z
-ZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpyLmE9bnVsbApuZXcgc2VsZi5NdXRhdGlv
-bk9ic2VydmVyKEgudFIobmV3IFAudGgociksMSkpLm9ic2VydmUodCx7Y2hpbGRMaXN0OnRydWV9KQpy
-ZXR1cm4gbmV3IFAuaGEocix0LHMpfWVsc2UgaWYoc2VsZi5zZXRJbW1lZGlhdGUhPW51bGwpcmV0dXJu
-IFAueXQoKQpyZXR1cm4gUC5xVygpfSwKWlY6ZnVuY3Rpb24oYSl7c2VsZi5zY2hlZHVsZUltbWVkaWF0
-ZShILnRSKG5ldyBQLlZzKHUuTS5hKGEpKSwwKSl9LApvQTpmdW5jdGlvbihhKXtzZWxmLnNldEltbWVk
-aWF0ZShILnRSKG5ldyBQLkZ0KHUuTS5hKGEpKSwwKSl9LApCejpmdW5jdGlvbihhKXt1Lk0uYShhKQpQ
-LlFOKDAsYSl9LApRTjpmdW5jdGlvbihhLGIpe3ZhciB0PW5ldyBQLlczKCkKdC5DWShhLGIpCnJldHVy
-biB0fSwKRlg6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmloKG5ldyBQLnZzKCQuWDMsYS5DKCJ2czww
-PiIpKSxhLkMoImloPDA+IikpfSwKREk6ZnVuY3Rpb24oYSxiKXthLiQyKDAsbnVsbCkKYi5iPSEwCnJl
-dHVybiBiLmF9LApqUTpmdW5jdGlvbihhLGIpe1AuSmUoYSxiKX0sCnlDOmZ1bmN0aW9uKGEsYil7Yi5h
-TSgwLGEpfSwKZjM6ZnVuY3Rpb24oYSxiKXtiLncwKEguUnUoYSksSC50cyhhKSl9LApKZTpmdW5jdGlv
-bihhLGIpe3ZhciB0LHMscj1uZXcgUC5XTShiKSxxPW5ldyBQLlNYKGIpCmlmKGEgaW5zdGFuY2VvZiBQ
-LnZzKWEuUWQocixxLHUueikKZWxzZXt0PXUuegppZih1LmMuYihhKSlhLlNxKHIscSx0KQplbHNle3M9
-bmV3IFAudnMoJC5YMyx1Ll8pCnMuYT00CnMuYz1hCnMuUWQocixxLHQpfX19LApsejpmdW5jdGlvbihh
-KXt2YXIgdD1mdW5jdGlvbihiLGMpe3JldHVybiBmdW5jdGlvbihkLGUpe3doaWxlKHRydWUpdHJ5e2Io
-ZCxlKQpicmVha31jYXRjaChzKXtlPXMKZD1jfX19KGEsMSkKcmV0dXJuICQuWDMuTGoobmV3IFAuR3Mo
-dCksdS5QLHUucSx1LnopfSwKR1E6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMSl9LApUaDpm
-dW5jdGlvbigpe3JldHVybiBDLndRfSwKWW06ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMyl9
-LApsMDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5xNChhLGIuQygicTQ8MD4iKSl9LAprMzpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMscgpiLmE9MQp0cnl7YS5TcShuZXcgUC5wVihiKSxuZXcgUC5VNyhiKSx1
-LlApfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5yYihuZXcgUC52cihiLHQscykpfX0sCkE5
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PXUuXztzPWEuYSxzPT09MjspYT10LmEoYS5jKQpp
-ZihzPj00KXtyPWIuYWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5IWihiLHIpfWVsc2V7cj11LnguYShiLmMp
-CmIuYT0yCmIuYz1hCmEualEocil9fSwKSFo6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsayxqLGksaCxnLGYsZT1udWxsLGQ9e30sYz1kLmE9YQpmb3IodD11Lm4scz11Lngscj11LmM7ITA7
-KXtxPXt9CnA9Yy5hPT09OAppZihiPT1udWxsKXtpZihwKXtvPXQuYShjLmMpClAuTDIoZSxlLGMuYixv
-LmEsby5iKX1yZXR1cm59Zm9yKDtuPWIuYSxuIT1udWxsO2I9bil7Yi5hPW51bGwKUC5IWihkLmEsYil9
-Yz1kLmEKbT1jLmMKcS5hPXAKcS5iPW0KbD0hcAppZihsKXtrPWIuYwprPShrJjEpIT09MHx8KGsmMTUp
-PT09OH1lbHNlIGs9ITAKaWYoayl7az1iLmIKaj1rLmIKaWYocCl7aT1jLmI9PT1qCmk9IShpfHxpKX1l
-bHNlIGk9ITEKaWYoaSl7dC5hKG0pClAuTDIoZSxlLGMuYixtLmEsbS5iKQpyZXR1cm59aD0kLlgzCmlm
-KGghPT1qKSQuWDM9agplbHNlIGg9ZQpjPWIuYwppZigoYyYxNSk9PT04KW5ldyBQLlJUKGQscSxiLHAp
-LiQwKCkKZWxzZSBpZihsKXtpZigoYyYxKSE9PTApbmV3IFAucnEocSxiLG0pLiQwKCl9ZWxzZSBpZigo
-YyYyKSE9PTApbmV3IFAuUlcoZCxxLGIpLiQwKCkKaWYoaCE9bnVsbCkkLlgzPWgKYz1xLmIKaWYoci5i
-KGMpKXtpZihjLmE+PTQpe2c9cy5hKGsuYykKay5jPW51bGwKYj1rLk44KGcpCmsuYT1jLmEKay5jPWMu
-YwpkLmE9Ywpjb250aW51ZX1lbHNlIFAuQTkoYyxrKQpyZXR1cm59fWY9Yi5iCmc9cy5hKGYuYykKZi5j
-PW51bGwKYj1mLk44KGcpCmM9cS5hCmw9cS5iCmlmKCFjKXtmLiR0aS5jLmEobCkKZi5hPTQKZi5jPWx9
-ZWxzZXt0LmEobCkKZi5hPTgKZi5jPWx9ZC5hPWYKYz1mfX0sClZIOmZ1bmN0aW9uKGEsYil7dmFyIHQK
-aWYodS5hZy5iKGEpKXJldHVybiBiLkxqKGEsdS56LHUuSyx1LmwpCnQ9dS5iSQppZih0LmIoYSkpcmV0
-dXJuIHQuYShhKQp0aHJvdyBILmIoUC5MMyhhLCJvbkVycm9yIiwiRXJyb3IgaGFuZGxlciBtdXN0IGFj
-Y2VwdCBvbmUgT2JqZWN0IG9yIG9uZSBPYmplY3QgYW5kIGEgU3RhY2tUcmFjZSBhcyBhcmd1bWVudHMs
-IGFuZCByZXR1cm4gYSBhIHZhbGlkIHJlc3VsdCIpKX0sCnB1OmZ1bmN0aW9uKCl7dmFyIHQscwpmb3Io
-O3Q9JC5TNix0IT1udWxsOyl7JC5tZz1udWxsCnM9dC5iCiQuUzY9cwppZihzPT1udWxsKSQuazg9bnVs
-bAp0LmEuJDAoKX19LAplTjpmdW5jdGlvbigpeyQuVUQ9ITAKdHJ5e1AucHUoKX1maW5hbGx5eyQubWc9
-bnVsbAokLlVEPSExCmlmKCQuUzYhPW51bGwpJC51dCgpLiQxKFAuVjkoKSl9fSwKZVc6ZnVuY3Rpb24o
-YSl7dmFyIHQ9bmV3IFAuT00oYSkKaWYoJC5TNj09bnVsbCl7JC5TNj0kLms4PXQKaWYoISQuVUQpJC51
-dCgpLiQxKFAuVjkoKSl9ZWxzZSAkLms4PSQuazguYj10fSwKclI6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-PSQuUzYKaWYocj09bnVsbCl7UC5lVyhhKQokLm1nPSQuazgKcmV0dXJufXQ9bmV3IFAuT00oYSkKcz0k
-Lm1nCmlmKHM9PW51bGwpe3QuYj1yCiQuUzY9JC5tZz10fWVsc2V7dC5iPXMuYgokLm1nPXMuYj10Cmlm
-KHQuYj09bnVsbCkkLms4PXR9fSwKcmI6ZnVuY3Rpb24oYSl7dmFyIHQ9bnVsbCxzPSQuWDMKaWYoQy5O
-VT09PXMpe1AuVGsodCx0LEMuTlUsYSkKcmV0dXJufVAuVGsodCx0LHMsdS5NLmEocy5HWShhKSkpfSwK
-UXc6ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKUgudmgoUC5FZSgic3RyZWFtIikpCnJldHVybiBuZXcg
-UC54SShiLkMoInhJPDA+IikpfSwKVGw6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iPT1udWxsP1AudjAoYSk6
-YgpQLlVJKGEsImVycm9yIix1LkspCnJldHVybiBuZXcgUC5PSChhLHQpfSwKdjA6ZnVuY3Rpb24oYSl7
-dmFyIHQKaWYodS5XLmIoYSkpe3Q9YS5nSUkoKQppZih0IT1udWxsKXJldHVybiB0fXJldHVybiBDLnBk
-fSwKTDI6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD17fQp0LmE9ZAp0LmI9ZQppZihkPT1udWxsKXt0
-LmE9bmV3IFAuQVQoITEsbnVsbCwiZXJyb3IiLCJNdXN0IG5vdCBiZSBudWxsIikKdC5iPVAuWmIoKX1Q
-LnJSKG5ldyBQLnBLKHQpKX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscz0kLlgzCmlmKHM9
-PT1jKXJldHVybiBkLiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1kLiQwKCkKcmV0dXJuIHN9ZmluYWxseXsk
-LlgzPXR9fSwKeXY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJl
-dHVybiBkLiQxKGUpCiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShlKQpyZXR1cm4gc31maW5hbGx5eyQuWDM9
-dH19LApReDpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJl
-dHVybiBkLiQyKGUsZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQyKGUsZikKcmV0dXJuIHN9ZmluYWxseXsk
-LlgzPXR9fSwKVGs6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKdS5NLmEoZCkKdD1DLk5VIT09YwppZih0
-KWQ9ISghdHx8ITEpP2MuR1koZCk6Yy5SVChkLHUuSCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEp
-e3RoaXMuYT1hfSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1j
-fSwKVnM6ZnVuY3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9YX0s
-ClczOmZ1bmN0aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
-CmloOmZ1bmN0aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpmdW5j
-dGlvbiBXTShhKXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rp
-b24gR3MoYSl7dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
-R1Y6ZnVuY3Rpb24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9
-Yn0sCnE0OmZ1bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmI4OmZ1bmN0aW9uIGI4
-KCl7fSwKUGY6ZnVuY3Rpb24gUGYoKXt9LApaZjpmdW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMu
-JHRpPWJ9LApGZTpmdW5jdGlvbiBGZShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEK
-Xy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpf
-LmE9MApfLmI9YQpfLmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0
-aGlzLmI9Yn0sCm9ROmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlv
-biBwVihhKXt0aGlzLmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24g
-dnIoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKckg6ZnVuY3Rpb24gckgoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApa
-TDpmdW5jdGlvbiBaTChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlv
-biBSVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKalo6ZnVuY3Rp
-b24galooYSl7dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
-dGhpcy5jPWN9LApSVzpmdW5jdGlvbiBSVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9
-LApPTTpmdW5jdGlvbiBPTShhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0sCnFoOmZ1bmN0aW9uIHFoKCl7
-fSwKQjU6ZnVuY3Rpb24gQjUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnVPOmZ1bmN0aW9uIHVPKGEs
-Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNTzpmdW5jdGlvbiBNTygpe30sCmtUOmZ1bmN0aW9uIGtUKCl7
-fSwKeEk6ZnVuY3Rpb24geEkoYSl7dGhpcy4kdGk9YX0sCk9IOmZ1bmN0aW9uIE9IKGEsYil7dGhpcy5h
-PWEKdGhpcy5iPWJ9LAptMDpmdW5jdGlvbiBtMCgpe30sCnBLOmZ1bmN0aW9uIHBLKGEpe3RoaXMuYT1h
-fSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlvbiBoaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
-PWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKT1I6ZnVu
-Y3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKRUY6ZnVuY3Rpb24oYSxi
-LGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJGbzwxLDI+IikuYShILkI3KGEsbmV3IEguTjUo
-Yi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkpfSwKRmw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-bmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8MSwyPiIpKX0sCkxzOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6ZnVuY3Rpb24oKXt2YXIgdD1PYmplY3QuY3Jl
-YXRlKG51bGwpCnRbIjxub24taWRlbnRpZmllci1rZXk+Il09dApkZWxldGUgdFsiPG5vbi1pZGVudGlm
-aWVyLWtleT4iXQpyZXR1cm4gdH0sCnJqOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1uZXcgUC5sbShhLGIs
-Yy5DKCJsbTwwPiIpKQp0LmM9YS5lCnJldHVybiB0fSwKRVA6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMK
-aWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIilyZXR1cm4iKC4uLikiCnJldHVybiBiKyIuLi4i
-K2N9dD1ILlZNKFtdLHUucykKQy5ObS5pKCQueGcsYSkKdHJ5e1AuVnIoYSx0KX1maW5hbGx5e2lmKDA+
-PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3AoKX1zPVAudmcoYix1LlIuYSh0
-KSwiLCAiKStjCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKV0U6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0LHMKaWYoUC5oQihhKSlyZXR1cm4gYisiLi4uIitjCnQ9bmV3IFAuUm4oYikKQy5ObS5pKCQu
-eGcsYSkKdHJ5e3M9dApzLmE9UC52ZyhzLmEsYSwiLCAiKX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3Ro
-KXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3AoKX10LmErPWMKcz10LmEKcmV0dXJuIHMuY2hhckNv
-ZGVBdCgwKT09MD9zOnN9LApoQjpmdW5jdGlvbihhKXt2YXIgdCxzCmZvcih0PSQueGcubGVuZ3RoLHM9
-MDtzPHQ7KytzKWlmKGE9PT0kLnhnW3NdKXJldHVybiEwCnJldHVybiExfSwKVnI6ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzLHIscSxwLG8sbixtPWEuZ2t6KGEpLGw9MCxrPTAKd2hpbGUoITApe2lmKCEobDw4MHx8
-azwzKSlicmVhawppZighbS5GKCkpcmV0dXJuCnQ9SC5kKG0uZ2woKSkKQy5ObS5pKGIsdCkKbCs9dC5s
-ZW5ndGgrMjsrK2t9aWYoIW0uRigpKXtpZihrPD01KXJldHVybgppZigwPj1iLmxlbmd0aClyZXR1cm4g
-SC5rKGIsLTEpCnM9Yi5wb3AoKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5rKGIsLTEpCnI9Yi5wb3Ao
-KX1lbHNle3E9bS5nbCgpOysrawppZighbS5GKCkpe2lmKGs8PTQpe0MuTm0uaShiLEguZChxKSkKcmV0
-dXJufXM9SC5kKHEpCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILmsoYiwtMSkKcj1iLnBvcCgpCmwrPXMu
-bGVuZ3RoKzJ9ZWxzZXtwPW0uZ2woKTsrK2sKZm9yKDttLkYoKTtxPXAscD1vKXtvPW0uZ2woKTsrK2sK
-aWYoaz4xMDApe3doaWxlKCEwKXtpZighKGw+NzUmJms+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0
-dXJuIEguayhiLC0xKQpsLT1iLnBvcCgpLmxlbmd0aCsyOy0ta31DLk5tLmkoYiwiLi4uIikKcmV0dXJu
-fX1yPUguZChxKQpzPUguZChwKQpsKz1zLmxlbmd0aCtyLmxlbmd0aCs0fX1pZihrPmIubGVuZ3RoKzIp
-e2wrPTUKbj0iLi4uIn1lbHNlIG49bnVsbAp3aGlsZSghMCl7aWYoIShsPjgwJiZiLmxlbmd0aD4zKSli
-cmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5rKGIsLTEpCmwtPWIucG9wKCkubGVuZ3RoKzIKaWYo
-bj09bnVsbCl7bCs9NQpuPSIuLi4ifX1pZihuIT1udWxsKUMuTm0uaShiLG4pCkMuTm0uaShiLHIpCkMu
-Tm0uaShiLHMpfSwKdE06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9UC5McyhiKQpmb3IodD1hLmxlbmd0
-aCxzPTA7czxhLmxlbmd0aDthLmxlbmd0aD09PXR8fCgwLEgubGspKGEpLCsrcylyLmkoMCxiLmEoYVtz
-XSkpCnJldHVybiByfSwKbk86ZnVuY3Rpb24oYSl7dmFyIHQscz17fQppZihQLmhCKGEpKXJldHVybiJ7
-Li4ufSIKdD1uZXcgUC5SbigiIikKdHJ5e0MuTm0uaSgkLnhnLGEpCnQuYSs9InsiCnMuYT0hMAphLkso
-MCxuZXcgUC5yYShzLHQpKQp0LmErPSJ9In1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBI
-LmsoJC54ZywtMSkKJC54Zy5wb3AoKX1zPXQuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30s
-CmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5mPV8uZT1fLmQ9Xy5jPV8uYj1udWxs
-Cl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBibihhKXt0aGlzLmE9YQp0aGlzLmM9dGhpcy5iPW51
-bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51
-bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7fSwKTFU6ZnVuY3Rpb24gTFUoKXt9LApsRDpmdW5j
-dGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7fSwKcmE6ZnVuY3Rpb24gcmEoYSxiKXt0aGlzLmE9
-YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7fSwKeVE6ZnVuY3Rpb24geVEoYSl7dGhpcy5hPWF9
-LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0aW9uIFBuKCl7fSwKR2o6ZnVuY3Rpb24gR2ooYSxi
-KXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTWE6ZnVuY3Rpb24gTWEoKXt9LApWajpmdW5jdGlvbiBWaigp
-e30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVuY3Rpb24gblkoKXt9LApUQzpmdW5jdGlvbiBUQygp
-e30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKQlM6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQppZih0eXBl
-b2YgYSE9InN0cmluZyIpdGhyb3cgSC5iKEguSShhKSkKdD1udWxsCnRyeXt0PUpTT04ucGFyc2UoYSl9
-Y2F0Y2gocil7cz1ILlJ1KHIpCnE9UC5ycihTdHJpbmcocyksbnVsbCxudWxsKQp0aHJvdyBILmIocSl9
-cT1QLlFlKHQpCnJldHVybiBxfSwKUWU6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVsbClyZXR1cm4g
-bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGEKaWYoT2JqZWN0LmdldFByb3RvdHlwZU9m
-KGEpIT09QXJyYXkucHJvdG90eXBlKXJldHVybiBuZXcgUC51dyhhLE9iamVjdC5jcmVhdGUobnVsbCkp
-CmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpYVt0XT1QLlFlKGFbdF0pCnJldHVybiBhfSwKa3k6ZnVuY3Rp
-b24oYSxiLGMsZCl7aWYoYiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuIFAuUlAoITEsYixjLGQp
-CnJldHVybiBudWxsfSwKUlA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyPSQudEwoKQppZihyPT1u
-dWxsKXJldHVybiBudWxsCnQ9MD09PWMKaWYodCYmITApcmV0dXJuIFAuT1EocixiKQpzPWIubGVuZ3Ro
-CmQ9UC5qQihjLGQscykKaWYodCYmZD09PXMpcmV0dXJuIFAuT1EocixiKQpyZXR1cm4gUC5PUShyLGIu
-c3ViYXJyYXkoYyxkKSl9LApPUTpmdW5jdGlvbihhLGIpe2lmKFAuQWooYikpcmV0dXJuIG51bGwKcmV0
-dXJuIFAuSmgoYSxiKX0sCkpoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0cnl7dD1hLmRlY29kZShiKQpy
-ZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpfXJldHVybiBudWxsfSwKQWo6ZnVuY3Rpb24oYSl7dmFyIHQs
-cz1hLmxlbmd0aC0yCmZvcih0PTA7dDxzOysrdClpZihhW3RdPT09MjM3KWlmKChhW3QrMV0mMjI0KT09
-PTE2MClyZXR1cm4hMApyZXR1cm4hMX0sCldJOmZ1bmN0aW9uKCl7dmFyIHQscwp0cnl7dD1uZXcgVGV4
-dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVybiB0fWNhdGNoKHMpe0guUnUocyl9cmV0
-dXJuIG51bGx9LApjUDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyCmZvcih0PUouVTYoYSkscz1iO3M8
-YzsrK3Mpe3I9dC5xKGEscykKaWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci56TSgpCmlmKChy
-JjEyNykhPT1yKXJldHVybiBzLWJ9cmV0dXJuIGMtYn0sCnhNOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXtp
-ZihDLmpuLnpZKGYsNCkhPT0wKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCBw
-YWRkZWQgbGVuZ3RoIG11c3QgYmUgbXVsdGlwbGUgb2YgZm91ciwgaXMgIitmLGEsYykpCmlmKGQrZSE9
-PWYpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsICc9JyBub3QgYXQgdGhlIGVu
-ZCIsYSxiKSkKaWYoZT4yKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCBtb3Jl
-IHRoYW4gdHdvICc9JyBjaGFyYWN0ZXJzIixhLGIpKX0sCkd5OmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4g
-bmV3IFAuVWQoYSxiKX0sCk5DOmZ1bmN0aW9uKGEpe3JldHVybiBhLkx0KCl9LAp1WDpmdW5jdGlvbihh
-LGIsYyl7dmFyIHQscz1uZXcgUC5SbigiIikscj1uZXcgUC50dShzLFtdLFAuQ3koKSkKci5pVShhKQp0
-PXMuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCnV3OmZ1bmN0aW9uIHV3KGEsYil7dGhp
-cy5hPWEKdGhpcy5iPWIKdGhpcy5jPW51bGx9LAppODpmdW5jdGlvbiBpOChhKXt0aGlzLmE9YX0sCkNW
-OmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpmdW5jdGlvbiBVaygpe30sCndJ
-OmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApVZDpmdW5jdGlvbiBVZChhLGIpe3Ro
-aXMuYT1hCnRoaXMuYj1ifSwKSzg6ZnVuY3Rpb24gSzgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmJ5
-OmZ1bmN0aW9uIGJ5KCl7fSwKb2o6ZnVuY3Rpb24gb2ooYSl7dGhpcy5iPWF9LApNeDpmdW5jdGlvbiBN
-eChhKXt0aGlzLmE9YX0sClNoOmZ1bmN0aW9uIFNoKCl7fSwKdGk6ZnVuY3Rpb24gdGkoYSxiKXt0aGlz
-LmE9YQp0aGlzLmI9Yn0sCnR1OmZ1bmN0aW9uIHR1KGEsYixjKXt0aGlzLmM9YQp0aGlzLmE9Ygp0aGlz
-LmI9Y30sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMoKXt9LApSdzpmdW5jdGlvbiBS
-dyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEpe3RoaXMuYT1hfSwKYno6ZnVu
-Y3Rpb24gYnooYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0hMApfLmY9Xy5lPV8uZD0wfSwK
-UUE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguSHAoYSxjKQppZih0IT1udWxsKXJldHVybiB0CmlmKGIh
-PW51bGwpcmV0dXJuIGIuJDEoYSkKdGhyb3cgSC5iKFAucnIoYSxudWxsLG51bGwpKX0sCm9zOmZ1bmN0
-aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILlRwKXJldHVybiBhLlooMCkKcmV0dXJuIkluc3RhbmNlIG9m
-ICciK0guZChILmxoKGEpKSsiJyJ9LApPODpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1KLlFpKGEsYykK
-aWYoYSE9PTAmJiEwKWZvcih0PTA7dDxzLmxlbmd0aDsrK3QpQy5ObS5ZKHMsdCxiKQpyZXR1cm4gc30s
-CkNIOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPUguVk0oW10sYy5DKCJqZDwwPiIpKQpmb3IodD1KLklU
-KGEpO3QuRigpOylDLk5tLmkocyxjLmEodC5nbCgpKSkKaWYoYilyZXR1cm4gcwpyZXR1cm4gYy5DKCJ6
-TTwwPiIpLmEoSi5FcChzKSl9LApBRjpmdW5jdGlvbihhLGIpe3JldHVybiBiLkMoInpNPDA+IikuYShK
-LnVuKFAuQ0goYSwhMSxiKSkpfSwKSE06ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKEFycmF5LmlzQXJy
-YXkoYSkpe3UudC5hKGEpCnQ9YS5sZW5ndGgKYz1QLmpCKGIsYyx0KQpyZXR1cm4gSC5lVChiPjB8fGM8
-dD9DLk5tLkQ2KGEsYixjKTphKX1pZih1LmJtLmIoYSkpcmV0dXJuIEguZncoYSxiLFAuakIoYixjLGEu
-bGVuZ3RoKSkKcmV0dXJuIFAuYncoYSxiLGMpfSwKT286ZnVuY3Rpb24oYSl7cmV0dXJuIEguTHcoYSl9
-LApidzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD1udWxsCmlmKGI8MCl0aHJvdyBILmIoUC5U
-RShiLDAsSi5IKGEpLHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixK
-LkgoYSkscCxwKSkKcz1KLklUKGEpCmZvcihyPTA7cjxiOysrcilpZighcy5GKCkpdGhyb3cgSC5iKFAu
-VEUoYiwwLHIscCxwKSkKcT1bXQppZih0KWZvcig7cy5GKCk7KXEucHVzaChzLmdsKCkpCmVsc2UgZm9y
-KHI9YjtyPGM7KytyKXtpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHIscCxwKSkKcS5wdXNoKHMu
-Z2woKSl9cmV0dXJuIEguZVQocSl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0
-KGEsITEsITAsITEsITEsITEpKX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1KLklUKGIpCmlmKCF0
-LkYoKSlyZXR1cm4gYQppZihjLmxlbmd0aD09PTApe2RvIGErPUguZCh0LmdsKCkpCndoaWxlKHQuRigp
-KX1lbHNle2ErPUguZCh0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0guZCh0LmdsKCkpfXJldHVybiBh
-fSwKbHI6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rp
-b24oKXt2YXIgdD1ILk0wKCkKaWYodCE9bnVsbClyZXR1cm4gUC5oSyh0KQp0aHJvdyBILmIoUC5MNCgi
-J1VyaS5iYXNlJyBpcyBub3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
-cyxyLHEscCxvLG49IjAxMjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXt0PSQuejQoKS5iCmlmKHR5
-cGVvZiBiIT0ic3RyaW5nIilILnZoKEguSShiKSkKdD10LnRlc3QoYil9ZWxzZSB0PSExCmlmKHQpcmV0
-dXJuIGIKSC5MaChjKS5DKCJVay5TIikuYShiKQpzPWMuZ1pFKCkuV0ooYikKZm9yKHQ9cy5sZW5ndGgs
-cj0wLHE9IiI7cjx0Oysrcil7cD1zW3JdCmlmKHA8MTI4KXtvPXA+Pj40CmlmKG8+PTgpcmV0dXJuIEgu
-ayhhLG8pCm89KGFbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pcSs9SC5MdyhwKQplbHNl
-IHE9ZCYmcD09PTMyP3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYxNV19cmV0dXJuIHEuY2hhckNv
-ZGVBdCgwKT09MD9xOnF9LApaYjpmdW5jdGlvbigpe3ZhciB0LHMKaWYoSC5vVCgkLnA2KCkpKXJldHVy
-biBILnRzKG5ldyBFcnJvcigpKQp0cnl7dGhyb3cgSC5iKCIiKX1jYXRjaChzKXtILlJ1KHMpCnQ9SC50
-cyhzKQpyZXR1cm4gdH19LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRoLmFicyhhKSxzPWE8MD8iLSI6
-IiIKaWYodD49MTAwMClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4gcysiMCIrdAppZih0Pj0xMCly
-ZXR1cm4gcysiMDAiK3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEwMCly
-ZXR1cm4iIithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9uKGEp
-e2lmKGE+PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApoOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBh
-PT0ibnVtYmVyInx8SC5yUShhKXx8bnVsbD09YSlyZXR1cm4gSi5BYyhhKQppZih0eXBlb2YgYT09InN0
-cmluZyIpcmV0dXJuIEpTT04uc3RyaW5naWZ5KGEpCnJldHVybiBQLm9zKGEpfSwKaFY6ZnVuY3Rpb24o
-YSl7cmV0dXJuIG5ldyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkFUKCExLG51
-bGwsbnVsbCxhKX0sCkwzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuQVQoITAsYSxiLGMpfSwK
-RWU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkFUKCExLG51bGwsYSwiTXVzdCBub3QgYmUgbnVsbCIp
-fSwKVUk6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpdGhyb3cgSC5iKFAuRWUoYikpCnJldHVybiBh
-fSwKTzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuYkoobnVsbCxudWxsLCEwLGEsYiwiVmFsdWUg
-bm90IGluIHJhbmdlIil9LApURTpmdW5jdGlvbihhLGIsYyxkLGUpe3JldHVybiBuZXcgUC5iSihiLGMs
-ITAsYSxkLCJJbnZhbGlkIHZhbHVlIil9LAp3QTpmdW5jdGlvbihhLGIsYyxkKXtpZihhPGJ8fGE+Yyl0
-aHJvdyBILmIoUC5URShhLGIsYyxkLG51bGwpKQpyZXR1cm4gYX0sCmpCOmZ1bmN0aW9uKGEsYixjKXtp
-ZigwPmF8fGE+Yyl0aHJvdyBILmIoUC5URShhLDAsYywic3RhcnQiLG51bGwpKQppZihiIT1udWxsKXtp
-ZihhPmJ8fGI+Yyl0aHJvdyBILmIoUC5URShiLGEsYywiZW5kIixudWxsKSkKcmV0dXJuIGJ9cmV0dXJu
-IGN9LAprMTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhIT09Im51bWJlciIpcmV0dXJuIGEuSigpCmlm
-KGE8MCl0aHJvdyBILmIoUC5URShhLDAsbnVsbCxiLG51bGwpKQpyZXR1cm4gYX0sCnQ6ZnVuY3Rpb24o
-YSxiLGMsZCxlKXt2YXIgdD1ILldZKGU9PW51bGw/Si5IKGIpOmUpCnJldHVybiBuZXcgUC5lWSh0LCEw
-LGEsYywiSW5kZXggb3V0IG9mIHJhbmdlIil9LApMNDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudWIo
-YSl9LApuOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5kcyhhKX0sClBWOmZ1bmN0aW9uKGEpe3JldHVy
-biBuZXcgUC5saihhKX0sCmE0OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5VVihhKX0sCnJyOmZ1bmN0
-aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuYUUoYSxiLGMpfSwKZEg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
-IHQscz1ILlZNKFtdLGQuQygiamQ8MD4iKSkKQy5ObS5zQShzLGEpCmZvcih0PTA7dDxhOysrdClDLk5t
-Llkocyx0LGIuJDEodCkpCnJldHVybiBzfSwKaEs6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4s
-bSxsLGssaixpLGgsZyxmLGU9bnVsbCxkPWEubGVuZ3RoCmlmKGQ+PTUpe3Q9KChKLlF6KGEsNCleNTgp
-KjN8Qy54Qi5XKGEsMCleMTAwfEMueEIuVyhhLDEpXjk3fEMueEIuVyhhLDIpXjExNnxDLnhCLlcoYSwz
-KV45Nyk+Pj4wCmlmKHQ9PT0wKXJldHVybiBQLktEKGQ8ZD9DLnhCLk5qKGEsMCxkKTphLDUsZSkuZ2xS
-KCkKZWxzZSBpZih0PT09MzIpcmV0dXJuIFAuS0QoQy54Qi5OaihhLDUsZCksMCxlKS5nbFIoKX1zPW5l
-dyBBcnJheSg4KQpzLmZpeGVkJGxlbmd0aD1BcnJheQpyPUguVk0ocyx1LnQpCkMuTm0uWShyLDAsMCkK
-Qy5ObS5ZKHIsMSwtMSkKQy5ObS5ZKHIsMiwtMSkKQy5ObS5ZKHIsNywtMSkKQy5ObS5ZKHIsMywwKQpD
-Lk5tLlkociw0LDApCkMuTm0uWShyLDUsZCkKQy5ObS5ZKHIsNixkKQppZihQLlVCKGEsMCxkLDAscik+
-PTE0KUMuTm0uWShyLDcsZCkKcT1yWzFdCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIHEudEIo
-KQppZihxPj0wKWlmKFAuVUIoYSwwLHEsMjAscik9PT0yMClyWzddPXEKcz1yWzJdCmlmKHR5cGVvZiBz
-IT09Im51bWJlciIpcmV0dXJuIHMuaCgpCnA9cysxCm89clszXQpuPXJbNF0KbT1yWzVdCmw9cls2XQpp
-Zih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkooKQppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJl
-dHVybiBILnBZKG0pCmlmKGw8bSltPWwKaWYodHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5KKCkK
-aWYobjxwKW49bQplbHNlIGlmKG48PXEpbj1xKzEKaWYodHlwZW9mIG8hPT0ibnVtYmVyIilyZXR1cm4g
-by5KKCkKaWYobzxwKW89bgpzPXJbN10KaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5KKCkK
-az1zPDAKaWYoaylpZihwPnErMyl7aj1lCms9ITF9ZWxzZXtzPW8+MAppZihzJiZvKzE9PT1uKXtqPWUK
-az0hMX1lbHNle2lmKCEobTxkJiZtPT09bisyJiZKLnEwKGEsIi4uIixuKSkpaT1tPm4rMiYmSi5xMChh
-LCIvLi4iLG0tMykKZWxzZSBpPSEwCmlmKGkpe2o9ZQprPSExfWVsc2V7aWYocT09PTQpaWYoSi5xMChh
-LCJmaWxlIiwwKSl7aWYocDw9MCl7aWYoIUMueEIuUWkoYSwiLyIsbikpe2g9ImZpbGU6Ly8vIgp0PTN9
-ZWxzZXtoPSJmaWxlOi8vIgp0PTJ9YT1oK0MueEIuTmooYSxuLGQpCnEtPTAKcz10LTAKbSs9cwpsKz1z
-CmQ9YS5sZW5ndGgKcD03Cm89NwpuPTd9ZWxzZSBpZihuPT09bSl7Zz1tKzE7KytsCmE9Qy54Qi5pNyhh
-LG4sbSwiLyIpOysrZAptPWd9aj0iZmlsZSJ9ZWxzZSBpZihDLnhCLlFpKGEsImh0dHAiLDApKXtpZihz
-JiZvKzM9PT1uJiZDLnhCLlFpKGEsIjgwIixvKzEpKXtmPW4tMwptLT0zCmwtPTMKYT1DLnhCLmk3KGEs
-byxuLCIiKQpkLT0zCm49Zn1qPSJodHRwIn1lbHNlIGo9ZQplbHNlIGlmKHE9PT01JiZKLnEwKGEsImh0
-dHBzIiwwKSl7aWYocyYmbys0PT09biYmSi5xMChhLCI0NDMiLG8rMSkpe2Y9bi00Cm0tPTQKbC09NAph
-PUouZGcoYSxvLG4sIiIpCmQtPTMKbj1mfWo9Imh0dHBzIn1lbHNlIGo9ZQprPSEwfX19ZWxzZSBqPWUK
-aWYoayl7cz1hLmxlbmd0aAppZihkPHMpe2E9Si5sZChhLDAsZCkKcS09MApwLT0wCm8tPTAKbi09MApt
-LT0wCmwtPTB9cmV0dXJuIG5ldyBQLlVmKGEscSxwLG8sbixtLGwsail9cmV0dXJuIFAuanYoYSwwLGQs
-cSxwLG8sbixtLGwsail9LApNdDpmdW5jdGlvbihhKXtILmMoYSkKcmV0dXJuIFAua3UoYSwwLGEubGVu
-Z3RoLEMueE0sITEpfSwKV1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dS5OCnJldHVybiBDLk5tLk4wKEguVk0o
-YS5zcGxpdCgiJiIpLHUucyksUC5GbCh0LHQpLG5ldyBQLm4xKEMueE0pLHUuZil9LApIaDpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbT1udWxsLGw9IklQdjQgYWRkcmVzcyBzaG91bGQgY29u
-dGFpbiBleGFjdGx5IDQgcGFydHMiLGs9ImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSAwLi4y
-NTUiLGo9bmV3IFAuY1MoYSksaT1uZXcgVWludDhBcnJheSg0KQpmb3IodD1pLmxlbmd0aCxzPWIscj1z
-LHE9MDtzPGM7KytzKXtwPUMueEIubShhLHMpCmlmKHAhPT00Nil7aWYoKHBeNDgpPjkpai4kMigiaW52
-YWxpZCBjaGFyYWN0ZXIiLHMpfWVsc2V7aWYocT09PTMpai4kMihsLHMpCm89UC5RQShDLnhCLk5qKGEs
-cixzKSxtLG0pCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQppZihvPjI1NSlqLiQy
-KGsscikKbj1xKzEKaWYocT49dClyZXR1cm4gSC5rKGkscSkKaVtxXT1vCnI9cysxCnE9bn19aWYocSE9
-PTMpai4kMihsLGMpCm89UC5RQShDLnhCLk5qKGEscixjKSxtLG0pCmlmKHR5cGVvZiBvIT09Im51bWJl
-ciIpcmV0dXJuIG8ub3MoKQppZihvPjI1NSlqLiQyKGsscikKaWYocT49dClyZXR1cm4gSC5rKGkscSkK
-aVtxXT1vCnJldHVybiBpfSwKZWc6ZnVuY3Rpb24oYSxiLGEwKXt2YXIgdCxzLHIscSxwLG8sbixtLGws
-ayxqLGksaCxnLGYsZSxkPW5ldyBQLlZDKGEpLGM9bmV3IFAuSlQoZCxhKQppZihhLmxlbmd0aDwyKWQu
-JDEoImFkZHJlc3MgaXMgdG9vIHNob3J0IikKdD1ILlZNKFtdLHUudCkKZm9yKHM9YixyPXMscT0hMSxw
-PSExO3M8YTA7KytzKXtvPUMueEIubShhLHMpCmlmKG89PT01OCl7aWYocz09PWIpeysrcwppZihDLnhC
-Lm0oYSxzKSE9PTU4KWQuJDIoImludmFsaWQgc3RhcnQgY29sb24uIixzKQpyPXN9aWYocz09PXIpe2lm
-KHEpZC4kMigib25seSBvbmUgd2lsZGNhcmQgYDo6YCBpcyBhbGxvd2VkIixzKQpDLk5tLmkodCwtMSkK
-cT0hMH1lbHNlIEMuTm0uaSh0LGMuJDIocixzKSkKcj1zKzF9ZWxzZSBpZihvPT09NDYpcD0hMH1pZih0
-Lmxlbmd0aD09PTApZC4kMSgidG9vIGZldyBwYXJ0cyIpCm49cj09PWEwCm09Qy5ObS5ncloodCkKaWYo
-biYmbSE9PS0xKWQuJDIoImV4cGVjdGVkIGEgcGFydCBhZnRlciBsYXN0IGA6YCIsYTApCmlmKCFuKWlm
-KCFwKUMuTm0uaSh0LGMuJDIocixhMCkpCmVsc2V7bD1QLkhoKGEscixhMCkKQy5ObS5pKHQsKGxbMF08
-PDh8bFsxXSk+Pj4wKQpDLk5tLmkodCwobFsyXTw8OHxsWzNdKT4+PjApfWlmKHEpe2lmKHQubGVuZ3Ro
-PjcpZC4kMSgiYW4gYWRkcmVzcyB3aXRoIGEgd2lsZGNhcmQgbXVzdCBoYXZlIGxlc3MgdGhhbiA3IHBh
-cnRzIil9ZWxzZSBpZih0Lmxlbmd0aCE9PTgpZC4kMSgiYW4gYWRkcmVzcyB3aXRob3V0IGEgd2lsZGNh
-cmQgbXVzdCBjb250YWluIGV4YWN0bHkgOCBwYXJ0cyIpCms9bmV3IFVpbnQ4QXJyYXkoMTYpCmZvciht
-PXQubGVuZ3RoLGo9ay5sZW5ndGgsaT05LW0scz0wLGg9MDtzPG07KytzKXtnPXRbc10KaWYoZz09PS0x
-KWZvcihmPTA7ZjxpOysrZil7aWYoaDwwfHxoPj1qKXJldHVybiBILmsoayxoKQprW2hdPTAKZT1oKzEK
-aWYoZT49ailyZXR1cm4gSC5rKGssZSkKa1tlXT0wCmgrPTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZiho
-PDB8fGg+PWopcmV0dXJuIEguayhrLGgpCmtbaF09ZQplPWgrMQppZihlPj1qKXJldHVybiBILmsoayxl
-KQprW2VdPWcmMjU1CmgrPTJ9fXJldHVybiBrfSwKanY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyxoLGks
-ail7dmFyIHQscyxyLHEscCxvLG4sbT1udWxsCmlmKGo9PW51bGwpaWYoZD5iKWo9UC5QaShhLGIsZCkK
-ZWxzZXtpZihkPT09YilQLlIzKGEsYiwiSW52YWxpZCBlbXB0eSBzY2hlbWUiKQpqPSIifWlmKGU+Yil7
-dD1kKzMKcz10PGU/UC56UihhLHQsZS0xKToiIgpyPVAuT2UoYSxlLGYsITEpCmlmKHR5cGVvZiBmIT09
-Im51bWJlciIpcmV0dXJuIGYuaCgpCnE9ZisxCmlmKHR5cGVvZiBnIT09Im51bWJlciIpcmV0dXJuIEgu
-cFkoZykKcD1xPGc/UC53QihQLlFBKEoubGQoYSxxLGcpLG5ldyBQLmUxKGEsZiksbSksaik6bX1lbHNl
-e3A9bQpyPXAKcz0iIn1vPVAua2EoYSxnLGgsbSxqLHIhPW51bGwpCmlmKHR5cGVvZiBoIT09Im51bWJl
-ciIpcmV0dXJuIGguSigpCm49aDxpP1AubGUoYSxoKzEsaSxtKTptCnJldHVybiBuZXcgUC5EbihqLHMs
-cixwLG8sbixpPGM/UC50RyhhLGkrMSxjKTptKX0sCktMOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3Zh
-ciB0LHMscixxLHAsbwpmPVAuUGkoZiwwLGY9PW51bGw/MDpmLmxlbmd0aCkKZz1QLnpSKGcsMCxnPT1u
-dWxsPzA6Zy5sZW5ndGgpCmE9UC5PZShhLDAsYT09bnVsbD8wOmEubGVuZ3RoLCExKQp0PVAubGUobnVs
-bCwwLDAsZSkKcz1QLnRHKG51bGwsMCwwKQpkPVAud0IoZCxmKQpyPWY9PT0iZmlsZSIKaWYoYT09bnVs
-bClxPWcubGVuZ3RoIT09MHx8ZCE9bnVsbHx8cgplbHNlIHE9ITEKaWYocSlhPSIiCnE9YT09bnVsbApw
-PSFxCmI9UC5rYShiLDAsYj09bnVsbD8wOmIubGVuZ3RoLGMsZixwKQpvPWYubGVuZ3RoPT09MAppZihv
-JiZxJiYhQy54Qi5uKGIsIi8iKSliPVAud0YoYiwhb3x8cCkKZWxzZSBiPVAueGUoYikKcmV0dXJuIG5l
-dyBQLkRuKGYsZyxxJiZDLnhCLm4oYiwiLy8iKT8iIjphLGQsYix0LHMpfSwKd0s6ZnVuY3Rpb24oYSl7
-aWYoYT09PSJodHRwIilyZXR1cm4gODAKaWYoYT09PSJodHRwcyIpcmV0dXJuIDQ0MwpyZXR1cm4gMH0s
-ClIzOmZ1bmN0aW9uKGEsYixjKXt0aHJvdyBILmIoUC5ycihjLGEsYikpfSwKWGQ6ZnVuY3Rpb24oYSxi
-LGMsZCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPW51bGwsaD1iLmxlbmd0aAppZihoIT09MCl7
-cj0wCndoaWxlKCEwKXtpZighKHI8aCkpe3Q9IiIKcz0wCmJyZWFrfWlmKEMueEIuVyhiLHIpPT09NjQp
-e3Q9Qy54Qi5OaihiLDAscikKcz1yKzEKYnJlYWt9KytyfWlmKHM8aCYmQy54Qi5XKGIscyk9PT05MSl7
-Zm9yKHE9cyxwPS0xO3E8aDsrK3Epe289Qy54Qi5XKGIscSkKaWYobz09PTM3JiZwPDApe249Qy54Qi5R
-aShiLCIyNSIscSsxKT9xKzI6cQpwPXEKcT1ufWVsc2UgaWYobz09PTkzKWJyZWFrfWlmKHE9PT1oKXRo
-cm93IEguYihQLnJyKCJJbnZhbGlkIElQdjYgaG9zdCBlbnRyeS4iLGIscykpCm09cDwwP3E6cApQLmVn
-KGIscysxLG0pOysrcQppZihxIT09aCYmQy54Qi5XKGIscSkhPT01OCl0aHJvdyBILmIoUC5ycigiSW52
-YWxpZCBlbmQgb2YgYXV0aG9yaXR5IixiLHEpKX1lbHNlIHE9cwp3aGlsZSghMCl7aWYoIShxPGgpKXts
-PWkKYnJlYWt9aWYoQy54Qi5XKGIscSk9PT01OCl7az1DLnhCLkcoYixxKzEpCmw9ay5sZW5ndGghPT0w
-P1AuUUEoayxpLGkpOmkKYnJlYWt9KytxfWo9Qy54Qi5OaihiLHMscSl9ZWxzZXtsPWkKaj1sCnQ9IiJ9
-cmV0dXJuIFAuS0woaixpLEguVk0oYy5zcGxpdCgiLyIpLHUucyksbCxkLGEsdCl9LAprRTpmdW5jdGlv
-bihhLGIpe0MuTm0uSyhhLG5ldyBQLk5ZKCExKSl9LApITjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxy
-CmZvcih0PUgucUMoYSxjLG51bGwsSC50NihhKS5jKSx0PW5ldyBILmE3KHQsdC5nQSh0KSx0LiR0aS5D
-KCJhNzxhTC5FPiIpKTt0LkYoKTspe3M9dC5kCnI9UC5udSgnWyIqLzo8Pj9cXFxcfF0nKQpzLnRvU3Ry
-aW5nCmlmKEgubTIocyxyLDApKXt0PVAuTDQoIklsbGVnYWwgY2hhcmFjdGVyIGluIHBhdGg6ICIrcykK
-dGhyb3cgSC5iKHQpfX19LApyZzpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKCEoNjU8PWEmJmE8PTkwKSl0
-PTk3PD1hJiZhPD0xMjIKZWxzZSB0PSEwCmlmKHQpcmV0dXJuCnQ9UC5MNCgiSWxsZWdhbCBkcml2ZSBs
-ZXR0ZXIgIitQLk9vKGEpKQp0aHJvdyBILmIodCl9LAp3QjpmdW5jdGlvbihhLGIpe2lmKGEhPW51bGwm
-JmE9PT1QLndLKGIpKXJldHVybiBudWxsCnJldHVybiBhfSwKT2U6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
-IHQscyxyLHEscCxvCmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoYj09PWMpcmV0dXJuIiIKaWYoQy54
-Qi5tKGEsYik9PT05MSl7aWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gYy5ITigpCnQ9Yy0xCmlm
-KEMueEIubShhLHQpIT09OTMpUC5SMyhhLGIsIk1pc3NpbmcgZW5kIGBdYCB0byBtYXRjaCBgW2AgaW4g
-aG9zdCIpCnM9YisxCnI9UC50byhhLHMsdCkKaWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5K
-KCkKaWYocjx0KXtxPXIrMQpwPVAuT0EoYSxDLnhCLlFpKGEsIjI1IixxKT9yKzM6cSx0LCIlMjUiKX1l
-bHNlIHA9IiIKUC5lZyhhLHMscikKcmV0dXJuIEMueEIuTmooYSxiLHIpLnRvTG93ZXJDYXNlKCkrcCsi
-XSJ9aWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQpvPWIKZm9yKDtvPGM7KytvKWlm
-KEMueEIubShhLG8pPT09NTgpe3I9Qy54Qi5YVShhLCIlIixiKQppZighKHI+PWImJnI8Yykpcj1jCmlm
-KHI8Yyl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShhLCIyNSIscSk/ciszOnEsYywiJTI1Iil9ZWxzZSBw
-PSIiClAuZWcoYSxiLHIpCnJldHVybiJbIitDLnhCLk5qKGEsYixyKStwKyJdIn1yZXR1cm4gUC5PTChh
-LGIsYyl9LAp0bzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1DLnhCLlhVKGEsIiUiLGIpCmlmKHM+PWIp
-e2lmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykKdD1zPGN9ZWxzZSB0PSExCnJldHVy
-biB0P3M6Y30sCk9BOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPWQhPT0i
-Ij9uZXcgUC5SbihkKTpudWxsCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykKdD1i
-CnM9dApyPSEwCmZvcig7dDxjOyl7cT1DLnhCLm0oYSx0KQppZihxPT09Mzcpe3A9UC5ydihhLHQsITAp
-Cm89cD09bnVsbAppZihvJiZyKXt0Kz0zCmNvbnRpbnVlfWlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikK
-bj1rLmErPUMueEIuTmooYSxzLHQpCmlmKG8pcD1DLnhCLk5qKGEsdCx0KzMpCmVsc2UgaWYocD09PSIl
-IilQLlIzKGEsdCwiWm9uZUlEIHNob3VsZCBub3QgY29udGFpbiAlIGFueW1vcmUiKQprLmE9bitwCnQr
-PTMKcz10CnI9ITB9ZWxzZXtpZihxPDEyNyl7bz1xPj4+NAppZihvPj04KXJldHVybiBILmsoQy5GMyxv
-KQpvPShDLkYzW29dJjE8PChxJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKXtpZihyJiY2NTw9cSYmOTA+
-PXEpe2lmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKaWYoczx0KXtrLmErPUMueEIuTmooYSxzLHQpCnM9
-dH1yPSExfSsrdH1lbHNle2lmKChxJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7bT1DLnhCLm0oYSx0KzEp
-CmlmKChtJjY0NTEyKT09PTU2MzIwKXtxPTY1NTM2fChxJjEwMjMpPDwxMHxtJjEwMjMKbD0yfWVsc2Ug
-bD0xfWVsc2UgbD0xCmlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5hKz1DLnhCLk5qKGEscyx0KQpr
-LmErPVAuelgocSkKdCs9bApzPXR9fX1pZihrPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihz
-PGMpay5hKz1DLnhCLk5qKGEscyxjKQpvPWsuYQpyZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30s
-Ck9MOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqCmlmKHR5cGVvZiBjIT09
-Im51bWJlciIpcmV0dXJuIEgucFkoYykKdD1iCnM9dApyPW51bGwKcT0hMApmb3IoO3Q8Yzspe3A9Qy54
-Qi5tKGEsdCkKaWYocD09PTM3KXtvPVAucnYoYSx0LCEwKQpuPW89PW51bGwKaWYobiYmcSl7dCs9Mwpj
-b250aW51ZX1pZihyPT1udWxsKXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5OaihhLHMsdCkKbD1yLmErPSFx
-P20udG9Mb3dlckNhc2UoKTptCmlmKG4pe289Qy54Qi5OaihhLHQsdCszKQprPTN9ZWxzZSBpZihvPT09
-IiUiKXtvPSIlMjUiCms9MX1lbHNlIGs9MwpyLmE9bCtvCnQrPWsKcz10CnE9ITB9ZWxzZXtpZihwPDEy
-Nyl7bj1wPj4+NAppZihuPj04KXJldHVybiBILmsoQy5lYSxuKQpuPShDLmVhW25dJjE8PChwJjE1KSkh
-PT0wfWVsc2Ugbj0hMQppZihuKXtpZihxJiY2NTw9cCYmOTA+PXApe2lmKHI9PW51bGwpcj1uZXcgUC5S
-bigiIikKaWYoczx0KXtyLmErPUMueEIuTmooYSxzLHQpCnM9dH1xPSExfSsrdH1lbHNle2lmKHA8PTkz
-KXtuPXA+Pj40CmlmKG4+PTgpcmV0dXJuIEguayhDLmFrLG4pCm49KEMuYWtbbl0mMTw8KHAmMTUpKSE9
-PTB9ZWxzZSBuPSExCmlmKG4pUC5SMyhhLHQsIkludmFsaWQgY2hhcmFjdGVyIikKZWxzZXtpZigocCY2
-NDUxMik9PT01NTI5NiYmdCsxPGMpe2o9Qy54Qi5tKGEsdCsxKQppZigoaiY2NDUxMik9PT01NjMyMCl7
-cD02NTUzNnwocCYxMDIzKTw8MTB8aiYxMDIzCms9Mn1lbHNlIGs9MX1lbHNlIGs9MQppZihyPT1udWxs
-KXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5OaihhLHMsdCkKci5hKz0hcT9tLnRvTG93ZXJDYXNlKCk6bQpy
-LmErPVAuelgocCkKdCs9awpzPXR9fX19aWYocj09bnVsbClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYo
-czxjKXttPUMueEIuTmooYSxzLGMpCnIuYSs9IXE/bS50b0xvd2VyQ2FzZSgpOm19bj1yLmEKcmV0dXJu
-IG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApQaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYo
-Yj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5yWShhKS5XKGEsYikpKVAuUjMoYSxiLCJTY2hlbWUgbm90
-IHN0YXJ0aW5nIHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpmb3IodD1iLHM9ITE7dDxjOysrdCl7
-cj1DLnhCLlcoYSx0KQppZihyPDEyOCl7cT1yPj4+NAppZihxPj04KXJldHVybiBILmsoQy5tSyxxKQpx
-PShDLm1LW3FdJjE8PChyJjE1KSkhPT0wfWVsc2UgcT0hMQppZighcSlQLlIzKGEsdCwiSWxsZWdhbCBz
-Y2hlbWUgY2hhcmFjdGVyIikKaWYoNjU8PXImJnI8PTkwKXM9ITB9YT1DLnhCLk5qKGEsYixjKQpyZXR1
-cm4gUC5ZYShzP2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9PT0iaHR0cCIp
-cmV0dXJuImh0dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0cHMiKXJldHVy
-biJodHRwcyIKaWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9LAp6UjpmdW5j
-dGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxDLnRvLCExKX0s
-CmthOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdCxzPWU9PT0iZmlsZSIscj1zfHxmLHE9YT09bnVs
-bAppZihxJiZkPT1udWxsKXJldHVybiBzPyIvIjoiIgpxPSFxCmlmKHEmJmQhPW51bGwpdGhyb3cgSC5i
-KFAueFkoIkJvdGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQppZihxKXQ9UC5QSShh
-LGIsYyxDLldkLCEwKQplbHNle2QudG9TdHJpbmcKcT1ILnQ2KGQpCnQ9bmV3IEgubEooZCxxLkMoInFV
-KDEpIikuYShuZXcgUC5SWigpKSxxLkMoImxKPDEscVU+IikpLnpWKDAsIi8iKX1pZih0Lmxlbmd0aD09
-PTApe2lmKHMpcmV0dXJuIi8ifWVsc2UgaWYociYmIUMueEIubih0LCIvIikpdD0iLyIrdApyZXR1cm4g
-UC5Kcih0LGUsZil9LApKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Yi5sZW5ndGg9PT0wCmlmKHQmJiFj
-JiYhQy54Qi5uKGEsIi8iKSlyZXR1cm4gUC53RihhLCF0fHxjKQpyZXR1cm4gUC54ZShhKX0sCmxlOmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9e30KaWYoYSE9bnVsbCl7aWYoZCE9bnVsbCl0aHJvdyBILmIo
-UC54WSgiQm90aCBxdWVyeSBhbmQgcXVlcnlQYXJhbWV0ZXJzIHNwZWNpZmllZCIpKQpyZXR1cm4gUC5Q
-SShhLGIsYyxDLlZDLCEwKX1pZihkPT1udWxsKXJldHVybiBudWxsCnQ9bmV3IFAuUm4oIiIpCnMuYT0i
-IgpkLksoMCxuZXcgUC55NShuZXcgUC5NRShzLHQpKSkKcz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgw
-KT09MD9zOnN9LAp0RzpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4g
-UC5QSShhLGIsYyxDLlZDLCEwKX0sCnJ2OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG89Yisy
-CmlmKG8+PWEubGVuZ3RoKXJldHVybiIlIgp0PUMueEIubShhLGIrMSkKcz1DLnhCLm0oYSxvKQpyPUgu
-b28odCkKcT1ILm9vKHMpCmlmKHI8MHx8cTwwKXJldHVybiIlIgpwPXIqMTYrcQppZihwPDEyNyl7bz1D
-LmpuLndHKHAsNCkKaWYobz49OClyZXR1cm4gSC5rKEMuRjMsbykKbz0oQy5GM1tvXSYxPDwocCYxNSkp
-IT09MH1lbHNlIG89ITEKaWYobylyZXR1cm4gSC5MdyhjJiY2NTw9cCYmOTA+PXA/KHB8MzIpPj4+MDpw
-KQppZih0Pj05N3x8cz49OTcpcmV0dXJuIEMueEIuTmooYSxiLGIrMykudG9VcHBlckNhc2UoKQpyZXR1
-cm4gbnVsbH0sCnpYOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuPSIwMTIzNDU2Nzg5QUJDREVG
-IgppZihhPDEyOCl7dD1uZXcgQXJyYXkoMykKdC5maXhlZCRsZW5ndGg9QXJyYXkKcz1ILlZNKHQsdS50
-KQpDLk5tLlkocywwLDM3KQpDLk5tLlkocywxLEMueEIuVyhuLGE+Pj40KSkKQy5ObS5ZKHMsMixDLnhC
-LlcobixhJjE1KSl9ZWxzZXtpZihhPjIwNDcpaWYoYT42NTUzNSl7cj0yNDAKcT00fWVsc2V7cj0yMjQK
-cT0zfWVsc2V7cj0xOTIKcT0yfXQ9bmV3IEFycmF5KDMqcSkKdC5maXhlZCRsZW5ndGg9QXJyYXkKcz1I
-LlZNKHQsdS50KQpmb3IocD0wOy0tcSxxPj0wO3I9MTI4KXtvPUMuam4uYmYoYSw2KnEpJjYzfHIKQy5O
-bS5ZKHMscCwzNykKQy5ObS5ZKHMscCsxLEMueEIuVyhuLG8+Pj40KSkKQy5ObS5ZKHMscCsyLEMueEIu
-VyhuLG8mMTUpKQpwKz0zfX1yZXR1cm4gUC5ITShzLDAsbnVsbCl9LApQSTpmdW5jdGlvbihhLGIsYyxk
-LGUpe3ZhciB0PVAuVWwoYSxiLGMsZCxlKQpyZXR1cm4gdD09bnVsbD9DLnhCLk5qKGEsYixjKTp0fSwK
-VWw6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG89bnVsbCxuPSFlLG09YixsPW0saz1v
-CndoaWxlKCEwKXtpZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLkooKQppZih0eXBlb2YgYyE9
-PSJudW1iZXIiKXJldHVybiBILnBZKGMpCmlmKCEobTxjKSlicmVhawpjJDA6e3Q9Qy54Qi5tKGEsbSkK
-aWYodDwxMjcpe3M9dD4+PjQKaWYocz49OClyZXR1cm4gSC5rKGQscykKcz0oZFtzXSYxPDwodCYxNSkp
-IT09MH1lbHNlIHM9ITEKaWYocykrK20KZWxzZXtpZih0PT09Mzcpe3I9UC5ydihhLG0sITEpCmlmKHI9
-PW51bGwpe20rPTMKYnJlYWsgYyQwfWlmKCIlIj09PXIpe3I9IiUyNSIKcT0xfWVsc2UgcT0zfWVsc2V7
-aWYobilpZih0PD05Myl7cz10Pj4+NAppZihzPj04KXJldHVybiBILmsoQy5hayxzKQpzPShDLmFrW3Nd
-JjE8PCh0JjE1KSkhPT0wfWVsc2Ugcz0hMQplbHNlIHM9ITEKaWYocyl7UC5SMyhhLG0sIkludmFsaWQg
-Y2hhcmFjdGVyIikKcT1vCnI9cX1lbHNle2lmKCh0JjY0NTEyKT09PTU1Mjk2KXtzPW0rMQppZihzPGMp
-e3A9Qy54Qi5tKGEscykKaWYoKHAmNjQ1MTIpPT09NTYzMjApe3Q9NjU1MzZ8KHQmMTAyMyk8PDEwfHAm
-MTAyMwpxPTJ9ZWxzZSBxPTF9ZWxzZSBxPTF9ZWxzZSBxPTEKcj1QLnpYKHQpfX1pZihrPT1udWxsKWs9
-bmV3IFAuUm4oIiIpCmsuYSs9Qy54Qi5OaihhLGwsbSkKay5hKz1ILmQocikKaWYodHlwZW9mIHEhPT0i
-bnVtYmVyIilyZXR1cm4gSC5wWShxKQptKz1xCmw9bX19fWlmKGs9PW51bGwpcmV0dXJuIG8KaWYodHlw
-ZW9mIGwhPT0ibnVtYmVyIilyZXR1cm4gbC5KKCkKaWYobDxjKWsuYSs9Qy54Qi5OaihhLGwsYykKbj1r
-LmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LAp5QjpmdW5jdGlvbihhKXtpZihDLnhCLm4o
-YSwiLiIpKXJldHVybiEwCnJldHVybiBDLnhCLk9ZKGEsIi8uIikhPT0tMX0sCnhlOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscixxLHAsbyxuCmlmKCFQLnlCKGEpKXJldHVybiBhCnQ9SC5WTShbXSx1LnMpCmZvcihz
-PWEuc3BsaXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEscD0wO3A8cjsrK3Ape289c1twXQppZihKLlJNKG8s
-Ii4uIikpe249dC5sZW5ndGgKaWYobiE9PTApe2lmKDA+PW4pcmV0dXJuIEguayh0LC0xKQp0LnBvcCgp
-CmlmKHQubGVuZ3RoPT09MClDLk5tLmkodCwiIil9cT0hMH1lbHNlIGlmKCIuIj09PW8pcT0hMAplbHNl
-e0MuTm0uaSh0LG8pCnE9ITF9fWlmKHEpQy5ObS5pKHQsIiIpCnJldHVybiBDLk5tLnpWKHQsIi8iKX0s
-CndGOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvCmlmKCFQLnlCKGEpKXJldHVybiFiP1AuQzEo
-YSk6YQp0PUguVk0oW10sdS5zKQpmb3Iocz1hLnNwbGl0KCIvIikscj1zLmxlbmd0aCxxPSExLHA9MDtw
-PHI7KytwKXtvPXNbcF0KaWYoIi4uIj09PW8paWYodC5sZW5ndGghPT0wJiZDLk5tLmdyWih0KSE9PSIu
-LiIpe2lmKDA+PXQubGVuZ3RoKXJldHVybiBILmsodCwtMSkKdC5wb3AoKQpxPSEwfWVsc2V7Qy5ObS5p
-KHQsIi4uIikKcT0hMX1lbHNlIGlmKCIuIj09PW8pcT0hMAplbHNle0MuTm0uaSh0LG8pCnE9ITF9fXM9
-dC5sZW5ndGgKaWYocyE9PTApaWYocz09PTEpe2lmKDA+PXMpcmV0dXJuIEguayh0LDApCnM9dFswXS5s
-ZW5ndGg9PT0wfWVsc2Ugcz0hMQplbHNlIHM9ITAKaWYocylyZXR1cm4iLi8iCmlmKHF8fEMuTm0uZ3Ja
-KHQpPT09Ii4uIilDLk5tLmkodCwiIikKaWYoIWIpe2lmKDA+PXQubGVuZ3RoKXJldHVybiBILmsodCww
-KQpDLk5tLlkodCwwLFAuQzEodFswXSkpfXJldHVybiBDLk5tLnpWKHQsIi8iKX0sCkMxOmZ1bmN0aW9u
-KGEpe3ZhciB0LHMscixxPWEubGVuZ3RoCmlmKHE+PTImJlAuRXQoSi5ReihhLDApKSlmb3IodD0xO3Q8
-cTsrK3Qpe3M9Qy54Qi5XKGEsdCkKaWYocz09PTU4KXJldHVybiBDLnhCLk5qKGEsMCx0KSsiJTNBIitD
-LnhCLkcoYSx0KzEpCmlmKHM8PTEyNyl7cj1zPj4+NAppZihyPj04KXJldHVybiBILmsoQy5tSyxyKQpy
-PShDLm1LW3JdJjE8PChzJjE1KSk9PT0wfWVsc2Ugcj0hMAppZihyKWJyZWFrfXJldHVybiBhfSwKbW46
-ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9YS5nRmooKSxwPXEubGVuZ3RoCmlmKHA+MCYmSi5IKHFbMF0p
-PT09MiYmSi5hNihxWzBdLDEpPT09NTgpe2lmKDA+PXApcmV0dXJuIEguayhxLDApClAucmcoSi5hNihx
-WzBdLDApLCExKQpQLkhOKHEsITEsMSkKdD0hMH1lbHNle1AuSE4ocSwhMSwwKQp0PSExfXM9YS5ndFQo
-KSYmIXQ/IlxcIjoiIgppZihhLmdjaigpKXtyPWEuZ0pmKGEpCmlmKHIubGVuZ3RoIT09MClzPXMrIlxc
-IityKyJcXCJ9cz1QLnZnKHMscSwiXFwiKQpwPXQmJnA9PT0xP3MrIlxcIjpzCnJldHVybiBwLmNoYXJD
-b2RlQXQoMCk9PTA/cDpwfSwKSWg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKZm9yKHQ9MCxzPTA7czwy
-Oysrcyl7cj1DLnhCLlcoYSxiK3MpCmlmKDQ4PD1yJiZyPD01Nyl0PXQqMTYrci00OAplbHNle3J8PTMy
-CmlmKDk3PD1yJiZyPD0xMDIpdD10KjE2K3ItODcKZWxzZSB0aHJvdyBILmIoUC54WSgiSW52YWxpZCBV
-UkwgZW5jb2RpbmciKSl9fXJldHVybiB0fSwKa3U6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIs
-cSxwPUouclkoYSksbz1iCndoaWxlKCEwKXtpZighKG88Yykpe3Q9ITAKYnJlYWt9cz1wLlcoYSxvKQpp
-ZihzPD0xMjcpaWYocyE9PTM3KXI9ZSYmcz09PTQzCmVsc2Ugcj0hMAplbHNlIHI9ITAKaWYocil7dD0h
-MQpicmVha30rK299aWYodCl7aWYoQy54TSE9PWQpcj0hMQplbHNlIHI9ITAKaWYocilyZXR1cm4gcC5O
-aihhLGIsYykKZWxzZSBxPW5ldyBILnFqKHAuTmooYSxiLGMpKX1lbHNle3E9SC5WTShbXSx1LnQpCmZv
-cihvPWI7bzxjOysrbyl7cz1wLlcoYSxvKQppZihzPjEyNyl0aHJvdyBILmIoUC54WSgiSWxsZWdhbCBw
-ZXJjZW50IGVuY29kaW5nIGluIFVSSSIpKQppZihzPT09Mzcpe2lmKG8rMz5hLmxlbmd0aCl0aHJvdyBI
-LmIoUC54WSgiVHJ1bmNhdGVkIFVSSSIpKQpDLk5tLmkocSxQLkloKGEsbysxKSkKbys9Mn1lbHNlIGlm
-KGUmJnM9PT00MylDLk5tLmkocSwzMikKZWxzZSBDLk5tLmkocSxzKX19dS5MLmEocSkKcmV0dXJuIG5l
-dyBQLkdZKCExKS5XSihxKX0sCkV0OmZ1bmN0aW9uKGEpe3ZhciB0PWF8MzIKcmV0dXJuIDk3PD10JiZ0
-PD0xMjJ9LApLRDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsPSJJbnZhbGlkIE1J
-TUUgdHlwZSIsaz1ILlZNKFtiLTFdLHUudCkKZm9yKHQ9YS5sZW5ndGgscz1iLHI9LTEscT1udWxsO3M8
-dDsrK3Mpe3E9Qy54Qi5XKGEscykKaWYocT09PTQ0fHxxPT09NTkpYnJlYWsKaWYocT09PTQ3KXtpZihy
-PDApe3I9cwpjb250aW51ZX10aHJvdyBILmIoUC5ycihsLGEscykpfX1pZihyPDAmJnM+Yil0aHJvdyBI
-LmIoUC5ycihsLGEscykpCmZvcig7cSE9PTQ0Oyl7Qy5ObS5pKGsscyk7KytzCmZvcihwPS0xO3M8dDsr
-K3Mpe3E9Qy54Qi5XKGEscykKaWYocT09PTYxKXtpZihwPDApcD1zfWVsc2UgaWYocT09PTU5fHxxPT09
-NDQpYnJlYWt9aWYocD49MClDLk5tLmkoayxwKQplbHNle289Qy5ObS5nclooaykKaWYocSE9PTQ0fHxz
-IT09bys3fHwhQy54Qi5RaShhLCJiYXNlNjQiLG8rMSkpdGhyb3cgSC5iKFAucnIoIkV4cGVjdGluZyAn
-PSciLGEscykpCmJyZWFrfX1DLk5tLmkoayxzKQpuPXMrMQppZigoay5sZW5ndGgmMSk9PT0xKWE9Qy5o
-OS55cihhLG4sdCkKZWxzZXttPVAuVWwoYSxuLHQsQy5WQywhMCkKaWYobSE9bnVsbClhPUMueEIuaTco
-YSxuLHQsbSl9cmV0dXJuIG5ldyBQLlBFKGEsayxjKX0sCktOOmZ1bmN0aW9uKCl7dmFyIHQ9IjAxMjM0
-NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6LS5f
-fiEkJicoKSorLDs9IixzPSIuIixyPSI6IixxPSIvIixwPSI/IixvPSIjIixuPXUuZ2MsbT1QLmRIKDIy
-LG5ldyBQLnEzKCksITAsbiksbD1uZXcgUC55SShtKSxrPW5ldyBQLmM2KCksaj1uZXcgUC5xZCgpLGk9
-bi5hKGwuJDIoMCwyMjUpKQprLiQzKGksdCwxKQprLiQzKGkscywxNCkKay4kMyhpLHIsMzQpCmsuJDMo
-aSxxLDMpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE0LDIyNSkpCmsuJDMo
-aSx0LDEpCmsuJDMoaSxzLDE1KQprLiQzKGksciwzNCkKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIp
-CmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxNSwyMjUpKQprLiQzKGksdCwxKQprLiQzKGksIiUiLDIy
-NSkKay4kMyhpLHIsMzQpCmsuJDMoaSxxLDkpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4u
-YShsLiQyKDEsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLHIsMzQpCmsuJDMoaSxxLDEwKQprLiQzKGks
-cCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigyLDIzNSkpCmsuJDMoaSx0LDEzOSkKay4kMyhp
-LHEsMTMxKQprLiQzKGkscywxNDYpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQy
-KDMsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDY4KQprLiQzKGkscywxOCkKay4kMyhpLHAsMTcy
-KQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNCwyMjkpKQprLiQzKGksdCw1KQpqLiQzKGksIkFaIiwy
-MjkpCmsuJDMoaSxyLDEwMikKay4kMyhpLCJAIiw2OCkKay4kMyhpLCJbIiwyMzIpCmsuJDMoaSxxLDEz
-OCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNSwyMjkpKQprLiQzKGksdCw1
-KQpqLiQzKGksIkFaIiwyMjkpCmsuJDMoaSxyLDEwMikKay4kMyhpLCJAIiw2OCkKay4kMyhpLHEsMTM4
-KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig2LDIzMSkpCmouJDMoaSwiMTki
-LDcpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEzOCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUp
-Cmk9bi5hKGwuJDIoNywyMzEpKQpqLiQzKGksIjA5Iiw3KQprLiQzKGksIkAiLDY4KQprLiQzKGkscSwx
-MzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQprLiQzKG4uYShsLiQyKDgsOCkpLCJdIiw1KQpp
-PW4uYShsLiQyKDksMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxzLDE2KQprLiQzKGkscSwyMzQpCmsu
-JDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE2LDIzNSkpCmsuJDMoaSx0LDExKQpr
-LiQzKGkscywxNykKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEo
-bC4kMigxNywyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEsOSkKay4kMyhpLHAsMTcyKQprLiQzKGks
-bywyMDUpCmk9bi5hKGwuJDIoMTAsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxzLDE4KQprLiQzKGks
-cSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE4LDIzNSkpCmsuJDMo
-aSx0LDExKQprLiQzKGkscywxOSkKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIw
-NSkKaT1uLmEobC4kMigxOSwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEsMjM0KQprLiQzKGkscCwx
-NzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxMSwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEs
-MTApCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDEyLDIzNikpCmsuJDMoaSx0
-LDEyKQprLiQzKGkscCwxMikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDEzLDIzNykpCmsuJDMoaSx0
-LDEzKQprLiQzKGkscCwxMykKai4kMyhuLmEobC4kMigyMCwyNDUpKSwiYXoiLDIxKQpsPW4uYShsLiQy
-KDIxLDI0NSkpCmouJDMobCwiYXoiLDIxKQpqLiQzKGwsIjA5IiwyMSkKay4kMyhsLCIrLS4iLDIxKQpy
-ZXR1cm4gbX0sClVCOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvPSQudlooKQpmb3Io
-dD1KLnJZKGEpLHM9YjtzPGM7KytzKXtpZihkPDB8fGQ+PW8ubGVuZ3RoKXJldHVybiBILmsobyxkKQpy
-PW9bZF0KcT10LlcoYSxzKV45NgppZihxPjk1KXE9MzEKaWYocT49ci5sZW5ndGgpcmV0dXJuIEguayhy
-LHEpCnA9cltxXQpkPXAmMzEKQy5ObS5ZKGUscD4+PjUscyl9cmV0dXJuIGR9LApXRjpmdW5jdGlvbiBX
-RihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYTI6ZnVuY3Rpb24gYTIoKXt9LAppUDpmdW5jdGlvbiBp
-UChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQ1A6ZnVuY3Rpb24gQ1AoKXt9LApYUzpmdW5jdGlvbiBY
-Uygpe30sCkM2OmZ1bmN0aW9uIEM2KGEpe3RoaXMuYT1hfSwKTEs6ZnVuY3Rpb24gTEsoKXt9LApBVDpm
-dW5jdGlvbiBBVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYko6
-ZnVuY3Rpb24gYkooYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5lPWEKXy5mPWIKXy5hPWMKXy5iPWQK
-Xy5jPWUKXy5kPWZ9LAplWTpmdW5jdGlvbiBlWShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5mPWEKXy5h
-PWIKXy5iPWMKXy5jPWQKXy5kPWV9LAptcDpmdW5jdGlvbiBtcChhLGIsYyxkKXt2YXIgXz10aGlzCl8u
-YT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKdWI6ZnVuY3Rpb24gdWIoYSl7dGhpcy5hPWF9LApkczpmdW5j
-dGlvbiBkcyhhKXt0aGlzLmE9YX0sCmxqOmZ1bmN0aW9uIGxqKGEpe3RoaXMuYT1hfSwKVVY6ZnVuY3Rp
-b24gVVYoYSl7dGhpcy5hPWF9LAprNTpmdW5jdGlvbiBrNSgpe30sCktZOmZ1bmN0aW9uIEtZKCl7fSwK
-dDc6ZnVuY3Rpb24gdDcoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlzLmE9YX0sCmFF
-OmZ1bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkVIOmZ1bmN0aW9u
-IEVIKCl7fSwKSWY6ZnVuY3Rpb24gSWYoKXt9LApjWDpmdW5jdGlvbiBjWCgpe30sCkFuOmZ1bmN0aW9u
-IEFuKCl7fSwKek06ZnVuY3Rpb24gek0oKXt9LApaMDpmdW5jdGlvbiBaMCgpe30sCk4zOmZ1bmN0aW9u
-IE4zKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKYzg6ZnVuY3Rpb24gYzgoKXt9
-LApsZjpmdW5jdGlvbiBsZigpe30sCk1oOmZ1bmN0aW9uIE1oKCl7fSwKT2Q6ZnVuY3Rpb24gT2QoKXt9
-LAppYjpmdW5jdGlvbiBpYigpe30sCnh1OmZ1bmN0aW9uIHh1KCl7fSwKR3o6ZnVuY3Rpb24gR3ooKXt9
-LApaZDpmdW5jdGlvbiBaZCgpe30sCnFVOmZ1bmN0aW9uIHFVKCl7fSwKUm46ZnVuY3Rpb24gUm4oYSl7
-dGhpcy5hPWF9LApHRDpmdW5jdGlvbiBHRCgpe30sCm4xOmZ1bmN0aW9uIG4xKGEpe3RoaXMuYT1hfSwK
-Y1M6ZnVuY3Rpb24gY1MoYSl7dGhpcy5hPWF9LApWQzpmdW5jdGlvbiBWQyhhKXt0aGlzLmE9YX0sCkpU
-OmZ1bmN0aW9uIEpUKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApEbjpmdW5jdGlvbiBEbihhLGIsYyxk
-LGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mCl8ucj1n
-Cl8uUT1fLno9Xy55PV8ueD1udWxsfSwKZTE6ZnVuY3Rpb24gZTEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
-Yn0sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1hfSwKUlo6ZnVuY3Rpb24gUlooKXt9LApNRTpmdW5j
-dGlvbiBNRShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKeTU6ZnVuY3Rpb24geTUoYSl7dGhpcy5hPWF9
-LApQRTpmdW5jdGlvbiBQRShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApxMzpmdW5j
-dGlvbiBxMygpe30sCnlJOmZ1bmN0aW9uIHlJKGEpe3RoaXMuYT1hfSwKYzY6ZnVuY3Rpb24gYzYoKXt9
-LApxZDpmdW5jdGlvbiBxZCgpe30sClVmOmZ1bmN0aW9uIFVmKGEsYixjLGQsZSxmLGcsaCl7dmFyIF89
-dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLng9aApfLnk9bnVs
-bH0sCnFlOmZ1bmN0aW9uIHFlKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5j
-PWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy5RPV8uej1fLnk9Xy54PW51bGx9LAppSjpmdW5jdGlv
-biBpSigpe30sCmpnOmZ1bmN0aW9uIGpnKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApUYTpmdW5jdGlv
-biBUYShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQmY6ZnVuY3Rpb24gQmYoYSxiKXt0aGlzLmE9YQp0
-aGlzLmI9Yn0sCkFzOmZ1bmN0aW9uIEFzKCl7fSwKR0U6ZnVuY3Rpb24gR0UoYSl7dGhpcy5hPWF9LApO
-NzpmdW5jdGlvbiBONyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdVE6ZnVuY3Rpb24gdVEoKXt9LApo
-RjpmdW5jdGlvbiBoRigpe30sClI0OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgpILkU5KGIpCnUu
-ai5hKGQpCmlmKEgub1QoYikpe3Q9W2NdCkMuTm0uRlYodCxkKQpkPXR9cz11LnoKcj1QLkNIKEouTTEo
-ZCxQLncwKCkscyksITAscykKdS5aLmEoYSkKcmV0dXJuIFAud1koSC5FayhhLHIsbnVsbCkpfSwKRG06
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnRyeXtpZihPYmplY3QuaXNFeHRlbnNpYmxlKGEpJiYhT2JqZWN0
-LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYikpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShh
-LGIse3ZhbHVlOmN9KQpyZXR1cm4hMH19Y2F0Y2godCl7SC5SdSh0KX1yZXR1cm4hMX0sCk9tOmZ1bmN0
-aW9uKGEsYil7aWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYikpcmV0dXJu
-IGFbYl0KcmV0dXJuIG51bGx9LAp3WTpmdW5jdGlvbihhKXtpZihhPT1udWxsfHx0eXBlb2YgYT09InN0
-cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8SC5yUShhKSlyZXR1cm4gYQppZihhIGluc3RhbmNlb2Yg
-UC5FNClyZXR1cm4gYS5hCmlmKEguUjkoYSkpcmV0dXJuIGEKaWYodS53LmIoYSkpcmV0dXJuIGEKaWYo
-YSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIEgubzIoYSkKaWYodS5aLmIoYSkpcmV0dXJuIFAuaEUoYSwi
-JGRhcnRfanNGdW5jdGlvbiIsbmV3IFAuUEMoKSkKcmV0dXJuIFAuaEUoYSwiXyRkYXJ0X2pzT2JqZWN0
-IixuZXcgUC5tdCgkLmtJKCkpKX0sCmhFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1QLk9tKGEsYikKaWYo
-dD09bnVsbCl7dD1jLiQxKGEpClAuRG0oYSxiLHQpfXJldHVybiB0fSwKTDc6ZnVuY3Rpb24oYSl7dmFy
-IHQscwppZihhPT1udWxsfHx0eXBlb2YgYT09InN0cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8dHlw
-ZW9mIGE9PSJib29sZWFuIilyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJkguUjko
-YSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZ1LncuYihhKSlyZXR1cm4gYQpl
-bHNlIGlmKGEgaW5zdGFuY2VvZiBEYXRlKXt0PUguV1koYS5nZXRUaW1lKCkpCmlmKE1hdGguYWJzKHQp
-PD04NjRlMTMpcz0hMQplbHNlIHM9ITAKaWYocylILnZoKFAueFkoIkRhdGVUaW1lIGlzIG91dHNpZGUg
-dmFsaWQgcmFuZ2U6ICIrdCkpClAuVUkoITEsImlzVXRjIix1LnkpCnJldHVybiBuZXcgUC5pUCh0LCEx
-KX1lbHNlIGlmKGEuY29uc3RydWN0b3I9PT0kLmtJKCkpcmV0dXJuIGEubwplbHNlIHJldHVybiBQLk5E
-KGEpfSwKTkQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIFAuaVEoYSwk
-LndRKCksbmV3IFAuTnooKSkKaWYoYSBpbnN0YW5jZW9mIEFycmF5KXJldHVybiBQLmlRKGEsJC5Dcigp
-LG5ldyBQLlFTKCkpCnJldHVybiBQLmlRKGEsJC5DcigpLG5ldyBQLm5wKCkpfSwKaVE6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciB0PVAuT20oYSxiKQppZih0PT1udWxsfHwhKGEgaW5zdGFuY2VvZiBPYmplY3QpKXt0
-PWMuJDEoYSkKUC5EbShhLGIsdCl9cmV0dXJuIHR9LApQQzpmdW5jdGlvbiBQQygpe30sCm10OmZ1bmN0
-aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6ZnVuY3Rpb24gTnooKXt9LApRUzpmdW5jdGlvbiBRUygpe30s
-Cm5wOmZ1bmN0aW9uIG5wKCl7fSwKRTQ6ZnVuY3Rpb24gRTQoYSl7dGhpcy5hPWF9LApyNzpmdW5jdGlv
-biByNyhhKXt0aGlzLmE9YX0sClR6OmZ1bmN0aW9uIFR6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0s
-CmNvOmZ1bmN0aW9uIGNvKCl7fSwKbmQ6ZnVuY3Rpb24gbmQoKXt9LApLZTpmdW5jdGlvbiBLZShhKXt0
-aGlzLmE9YX0sCmQ1OmZ1bmN0aW9uIGQ1KCl7fSwKbjY6ZnVuY3Rpb24gbjYoKXt9fSxXPXsKeDM6ZnVu
-Y3Rpb24oKXtyZXR1cm4gd2luZG93fSwKWnI6ZnVuY3Rpb24oKXtyZXR1cm4gZG9jdW1lbnR9LApKNjpm
-dW5jdGlvbihhKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIikKaWYoYSE9bnVsbCl0Lmhy
-ZWY9YQpyZXR1cm4gdH0sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1kb2N1bWVudC5ib2R5LHM9KHQm
-JkMuUlkpLnI2KHQsYSxiLGMpCnMudG9TdHJpbmcKdD11LmFjCnQ9bmV3IEguVTUobmV3IFcuZTcocyks
-dC5DKCJhMihsRC5FKSIpLmEobmV3IFcuQ3YoKSksdC5DKCJVNTxsRC5FPiIpKQpyZXR1cm4gdS5oLmEo
-dC5ncjgodCkpfSwKclM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPSJlbGVtZW50IHRhZyB1bmF2YWlsYWJs
-ZSIKdHJ5e3Q9Si5SRShhKQppZih0eXBlb2YgdC5nbnMoYSk9PSJzdHJpbmciKXI9dC5nbnMoYSl9Y2F0
-Y2gocyl7SC5SdShzKX1yZXR1cm4gcn0sCnFEOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9bmV3IFAu
-dnMoJC5YMyx1LlkpLHA9bmV3IFAuWmYocSx1LkUpLG89bmV3IFhNTEh0dHBSZXF1ZXN0KCkKQy5EdC5l
-byhvLCJHRVQiLGEsITApCmIuSygwLG5ldyBXLmJVKG8pKQp0PXUuYW4Kcz10LmEobmV3IFcuaEgobyxw
-KSkKdS5NLmEobnVsbCkKcj11LnAKVy5KRShvLCJsb2FkIixzLCExLHIpClcuSkUobywiZXJyb3IiLHQu
-YShwLmdZSigpKSwhMSxyKQpvLnNlbmQoKQpyZXR1cm4gcX0sCkMwOmZ1bmN0aW9uKGEsYil7YT01MzY4
-NzA5MTEmYStiCmE9NTM2ODcwOTExJmErKCg1MjQyODcmYSk8PDEwKQpyZXR1cm4gYV5hPj4+Nn0sCnJF
-OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0PVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxz
-PTUzNjg3MDkxMSZ0KygoNjcxMDg4NjMmdCk8PDMpCnNePXM+Pj4xMQpyZXR1cm4gNTM2ODcwOTExJnMr
-KCgxNjM4MyZzKTw8MTUpfSwKVE46ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5jbGFzc0xpc3QKZm9y
-KHQ9Yi5sZW5ndGgscz0wO3M8Yi5sZW5ndGg7Yi5sZW5ndGg9PT10fHwoMCxILmxrKShiKSwrK3Mpci5h
-ZGQoYltzXSl9LApKRTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PVcuYUYobmV3IFcudk4oYyksdS5C
-KQppZih0IT1udWxsJiYhMClKLmRaKGEsYix0LCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHQsITEsZS5D
-KCJ4QzwwPiIpKX0sClR3OmZ1bmN0aW9uKGEpe3ZhciB0PVcuSjYobnVsbCkscz13aW5kb3cubG9jYXRp
-b24KdD1uZXcgVy5KUShuZXcgVy5tayh0LHMpKQp0LkNZKGEpCnJldHVybiB0fSwKeVc6ZnVuY3Rpb24o
-YSxiLGMsZCl7dS5oLmEoYSkKSC5jKGIpCkguYyhjKQp1LmNyLmEoZCkKcmV0dXJuITB9LApRVzpmdW5j
-dGlvbihhLGIsYyxkKXt2YXIgdCxzLHIKdS5oLmEoYSkKSC5jKGIpCkguYyhjKQp0PXUuY3IuYShkKS5h
-CnM9dC5hCnMuaHJlZj1jCnI9cy5ob3N0bmFtZQp0PXQuYgppZighKHI9PXQuaG9zdG5hbWUmJnMucG9y
-dD09dC5wb3J0JiZzLnByb3RvY29sPT10LnByb3RvY29sKSlpZihyPT09IiIpaWYocy5wb3J0PT09IiIp
-e3Q9cy5wcm90b2NvbAp0PXQ9PT0iOiJ8fHQ9PT0iIn1lbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0h
-MApyZXR1cm4gdH0sCkJsOmZ1bmN0aW9uKCl7dmFyIHQ9dS5OLHM9UC50TShDLlF4LHQpLHI9dS5kRy5h
-KG5ldyBXLklBKCkpLHE9SC5WTShbIlRFTVBMQVRFIl0sdS5zKQp0PW5ldyBXLmN0KHMsUC5Mcyh0KSxQ
-LkxzKHQpLFAuTHModCksbnVsbCkKdC5DWShudWxsLG5ldyBILmxKKEMuUXgscix1LmR2KSxxLG51bGwp
-CnJldHVybiB0fSwKUHY6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gVy5Q
-MShhKX0sCnFjOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoInBvc3RN
-ZXNzYWdlIiBpbiBhKXt0PVcuUDEoYSkKaWYodS51LmIodCkpcmV0dXJuIHQKcmV0dXJuIG51bGx9ZWxz
-ZSByZXR1cm4gdS51LmEoYSl9LApQMTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93KXJldHVybiB1LmNp
-LmEoYSkKZWxzZSByZXR1cm4gbmV3IFcuZFcoYSl9LApISDpmdW5jdGlvbihhKXtpZihhPT09d2luZG93
-LmxvY2F0aW9uKXJldHVybiBhCmVsc2UgcmV0dXJuIG5ldyBXLkZiKCl9LAphRjpmdW5jdGlvbihhLGIp
-e3ZhciB0PSQuWDMKaWYodD09PUMuTlUpcmV0dXJuIGEKcmV0dXJuIHQuUHkoYSxiKX0sCnFFOmZ1bmN0
-aW9uIHFFKCl7fSwKR2g6ZnVuY3Rpb24gR2goKXt9LApmWTpmdW5jdGlvbiBmWSgpe30sCm5COmZ1bmN0
-aW9uIG5CKCl7fSwKQXo6ZnVuY3Rpb24gQXooKXt9LApRUDpmdW5jdGlvbiBRUCgpe30sCm54OmZ1bmN0
-aW9uIG54KCl7fSwKb0o6ZnVuY3Rpb24gb0ooKXt9LAppZDpmdW5jdGlvbiBpZCgpe30sClFGOmZ1bmN0
-aW9uIFFGKCl7fSwKTmg6ZnVuY3Rpb24gTmgoKXt9LApJQjpmdW5jdGlvbiBJQigpe30sCm43OmZ1bmN0
-aW9uIG43KCl7fSwKd3o6ZnVuY3Rpb24gd3ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY3Y6ZnVu
-Y3Rpb24gY3YoKXt9LApDdjpmdW5jdGlvbiBDdigpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVu
-Y3Rpb24gRDAoKXt9LApUNTpmdW5jdGlvbiBUNSgpe30sCmg0OmZ1bmN0aW9uIGg0KCl7fSwKYnI6ZnVu
-Y3Rpb24gYnIoKXt9LApWYjpmdW5jdGlvbiBWYigpe30sCmZKOmZ1bmN0aW9uIGZKKCl7fSwKYlU6ZnVu
-Y3Rpb24gYlUoYSl7dGhpcy5hPWF9LApoSDpmdW5jdGlvbiBoSChhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
-fSwKd2E6ZnVuY3Rpb24gd2EoKXt9LApTZzpmdW5jdGlvbiBTZygpe30sCnU4OmZ1bmN0aW9uIHU4KCl7
-fSwKT0s6ZnVuY3Rpb24gT0soKXt9LAplNzpmdW5jdGlvbiBlNyhhKXt0aGlzLmE9YX0sCnVIOmZ1bmN0
-aW9uIHVIKCl7fSwKQkg6ZnVuY3Rpb24gQkgoKXt9LApTTjpmdW5jdGlvbiBTTigpe30sCmV3OmZ1bmN0
-aW9uIGV3KCl7fSwKbHA6ZnVuY3Rpb24gbHAoKXt9LApUYjpmdW5jdGlvbiBUYigpe30sCkl2OmZ1bmN0
-aW9uIEl2KCl7fSwKV1A6ZnVuY3Rpb24gV1AoKXt9LAp5WTpmdW5jdGlvbiB5WSgpe30sCnc2OmZ1bmN0
-aW9uIHc2KCl7fSwKSzU6ZnVuY3Rpb24gSzUoKXt9LApDbTpmdW5jdGlvbiBDbSgpe30sCkNROmZ1bmN0
-aW9uIENRKCl7fSwKdzQ6ZnVuY3Rpb24gdzQoKXt9LApyaDpmdW5jdGlvbiByaCgpe30sCmNmOmZ1bmN0
-aW9uIGNmKCl7fSwKaTc6ZnVuY3Rpb24gaTcoYSl7dGhpcy5hPWF9LApTeTpmdW5jdGlvbiBTeShhKXt0
-aGlzLmE9YX0sCktTOmZ1bmN0aW9uIEtTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBMzpmdW5jdGlv
-biBBMyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSTQ6ZnVuY3Rpb24gSTQoYSl7dGhpcy5hPWF9LApG
-azpmdW5jdGlvbiBGayhhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApSTzpmdW5jdGlvbiBSTyhhLGIs
-YyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LApldTpmdW5jdGlvbiBldShh
-LGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAp4QzpmdW5jdGlvbiB4
-QyhhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZO
-OmZ1bmN0aW9uIHZOKGEpe3RoaXMuYT1hfSwKSlE6ZnVuY3Rpb24gSlEoYSl7dGhpcy5hPWF9LApHbTpm
-dW5jdGlvbiBHbSgpe30sCnZEOmZ1bmN0aW9uIHZEKGEpe3RoaXMuYT1hfSwKVXY6ZnVuY3Rpb24gVXYo
-YSl7dGhpcy5hPWF9LApFZzpmdW5jdGlvbiBFZyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5j
-PWN9LAptNjpmdW5jdGlvbiBtNigpe30sCkVvOmZ1bmN0aW9uIEVvKCl7fSwKV2s6ZnVuY3Rpb24gV2so
-KXt9LApjdDpmdW5jdGlvbiBjdChhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5lPWEKXy5hPWIKXy5iPWMK
-Xy5jPWQKXy5kPWV9LApJQTpmdW5jdGlvbiBJQSgpe30sCk93OmZ1bmN0aW9uIE93KCl7fSwKVzk6ZnVu
-Y3Rpb24gVzkoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPS0xCl8uZD1udWxsCl8uJHRp
-PWN9LApkVzpmdW5jdGlvbiBkVyhhKXt0aGlzLmE9YX0sCkZiOmZ1bmN0aW9uIEZiKCl7fSwKa0Y6ZnVu
-Y3Rpb24ga0YoKXt9LAptazpmdW5jdGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKS286ZnVu
-Y3Rpb24gS28oYSl7dGhpcy5hPWEKdGhpcy5iPSExfSwKZm06ZnVuY3Rpb24gZm0oYSl7dGhpcy5hPWF9
-LApMZTpmdW5jdGlvbiBMZSgpe30sCks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVuY3Rpb24gckIoKXt9
-LApYVzpmdW5jdGlvbiBYVygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7fX0sTT17Ck9YOmZ1bmN0aW9uKGEp
-e3N3aXRjaChhKXtjYXNlIEMuQWQ6cmV0dXJuIkFkZCAvKj8qLyBoaW50IgpjYXNlIEMubmU6cmV0dXJu
-IkFkZCAvKiEqLyBoaW50In1yZXR1cm4gbnVsbH0sCkg3OmZ1bmN0aW9uIEg3KGEsYil7dGhpcy5hPWEK
-dGhpcy5iPWJ9LApZRjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuCmZvcih0PWIubGVuZ3Ro
-LHM9MTtzPHQ7KytzKXtpZihiW3NdPT1udWxsfHxiW3MtMV0hPW51bGwpY29udGludWUKZm9yKDt0Pj0x
-O3Q9cil7cj10LTEKaWYoYltyXSE9bnVsbClicmVha31xPW5ldyBQLlJuKCIiKQpwPWErIigiCnEuYT1w
-Cm89SC5xQyhiLDAsdCxILnQ2KGIpLmMpCm49by4kdGkKbj1wK25ldyBILmxKKG8sbi5DKCJxVShhTC5F
-KSIpLmEobmV3IE0uTm8oKSksbi5DKCJsSjxhTC5FLHFVPiIpKS56VigwLCIsICIpCnEuYT1uCnEuYT1u
-KygiKTogcGFydCAiKyhzLTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0ICIrcysiIHdhcyBub3QuIikKdGhy
-b3cgSC5iKFAueFkocS5aKDApKSl9fSwKbEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5hPWF9LApNaTpmdW5j
-dGlvbiBNaSgpe30sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24gTm8oKXt9fSxVPXsKbno6
-ZnVuY3Rpb24oYSl7dmFyIHQ9SC5XWShhLnEoMCwibm9kZUlkIikpCnJldHVybiBuZXcgVS5MTChDLk5t
-Lkh0KEMubHIsbmV3IFUuTUQoYSkpLHQpfSwKTEw6ZnVuY3Rpb24gTEwoYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCk1EOmZ1bmN0aW9uIE1EKGEpe3RoaXMuYT1hfSwKamY6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHEKaWYoYT09bnVsbCl0PW51bGwKZWxzZXt0PUguVk0oW10sdS5mQSkKZm9yKHM9Si5JVCh1LlIuYShh
-KSk7cy5GKCk7KXtyPXMuZ2woKQpxPUouVTYocikKQy5ObS5pKHQsbmV3IFUuU2UoSC5jKHEucShyLCJk
-ZXNjcmlwdGlvbiIpKSxILmMocS5xKHIsImhyZWYiKSkpKX19cmV0dXJuIHR9LApOZDpmdW5jdGlvbihh
-KXt2YXIgdCxzCmlmKGE9PW51bGwpdD1udWxsCmVsc2V7dD1ILlZNKFtdLHUuaGgpCmZvcihzPUouSVQo
-dS5SLmEoYSkpO3MuRigpOylDLk5tLmkodCxVLkpqKHMuZ2woKSkpfXJldHVybiB0fSwKSmo6ZnVuY3Rp
-b24oYSl7dmFyIHQ9Si5VNihhKSxzPUguYyh0LnEoYSwiZGVzY3JpcHRpb24iKSkscj1ILlZNKFtdLHUu
-YUopCmZvcih0PUouSVQodS5SLmEodC5xKGEsImVudHJpZXMiKSkpO3QuRigpOylDLk5tLmkocixVLlJq
-KHQuZ2woKSkpCnJldHVybiBuZXcgVS55RChzLHIpfSwKUmo6ZnVuY3Rpb24oYSl7dmFyIHQscz1KLlU2
-KGEpLHI9SC5jKHMucShhLCJkZXNjcmlwdGlvbiIpKSxxPUguYyhzLnEoYSwiZnVuY3Rpb24iKSkscD1z
-LnEoYSwibGluayIpCmlmKHA9PW51bGwpcD1udWxsCmVsc2V7dD1KLlU2KHApCnA9bmV3IFUuTWwoSC5j
-KHQucShwLCJocmVmIikpLEguV1kodC5xKHAsImxpbmUiKSksSC5jKHQucShwLCJwYXRoIikpKX1zPXUu
-ai5hKHMucShhLCJoaW50QWN0aW9ucyIpKQpzPXM9PW51bGw/bnVsbDpKLk0xKHMsbmV3IFUuYU4oKSx1
-LkYpCnM9cz09bnVsbD9udWxsOnMuYnIoMCkKcmV0dXJuIG5ldyBVLndiKHIscSxwLHM9PW51bGw/Qy5k
-bjpzKX0sCmQyOmZ1bmN0aW9uIGQyKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
-YwpfLmQ9ZApfLmU9ZX0sClNlOmZ1bmN0aW9uIFNlKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNbDpm
-dW5jdGlvbiBNbChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp5RDpmdW5jdGlvbiB5
-RChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKd2I6ZnVuY3Rpb24gd2IoYSxiLGMsZCl7dmFyIF89dGhp
-cwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmFOOmZ1bmN0aW9uIGFOKCl7fSwKYjA6ZnVuY3Rpb24g
-YjAoKXt9fSxCPXsKWWY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPUguYyhhLnEoMCwi
-cmVnaW9ucyIpKSxrPUguYyhhLnEoMCwibmF2aWdhdGlvbkNvbnRlbnQiKSksaj1ILmMoYS5xKDAsInNv
-dXJjZUNvZGUiKSksaT1QLkZsKHUuTix1LmY0KQpmb3IodD11LlMuYShhLnEoMCwiZWRpdHMiKSksdD10
-LmdQdSh0KSx0PXQuZ2t6KHQpLHM9dS5SLHI9dS5naTt0LkYoKTspe3E9dC5nbCgpCnA9cS5hCm89SC5W
-TShbXSxyKQpmb3IocT1KLklUKHMuYShxLmIpKTtxLkYoKTspe249cS5nbCgpCm09Si5VNihuKQpDLk5t
-LmkobyxuZXcgQi5qOChILldZKG0ucShuLCJsaW5lIikpLEguYyhtLnEobiwiZXhwbGFuYXRpb24iKSks
-SC5XWShtLnEobiwib2Zmc2V0IikpKSl9aS5ZKDAscCxvKX1yZXR1cm4gbmV3IEIucXAobCxrLGosaSl9
-LApqODpmdW5jdGlvbiBqOChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApxcDpmdW5j
-dGlvbiBxcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKZnY6ZnVu
-Y3Rpb24gZnYoKXt9LApPUzpmdW5jdGlvbihhKXt2YXIgdAppZighKGE+PTY1JiZhPD05MCkpdD1hPj05
-NyYmYTw9MTIyCmVsc2UgdD0hMApyZXR1cm4gdH0sCll1OmZ1bmN0aW9uKGEsYil7dmFyIHQ9YS5sZW5n
-dGgscz1iKzIKaWYodDxzKXJldHVybiExCmlmKCFCLk9TKEMueEIubShhLGIpKSlyZXR1cm4hMQppZihD
-LnhCLm0oYSxiKzEpIT09NTgpcmV0dXJuITEKaWYodD09PXMpcmV0dXJuITAKcmV0dXJuIEMueEIubShh
-LHMpPT09NDd9fSxUPXttUTpmdW5jdGlvbiBtUSgpe319LEw9ewpJcTpmdW5jdGlvbigpe0MuQlouQihk
-b2N1bWVudCwiRE9NQ29udGVudExvYWRlZCIsbmV3IEwuZSgpKQpDLm9sLkIod2luZG93LCJwb3BzdGF0
-ZSIsbmV3IEwuTCgpKX0sCmt6OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dS5oLmEoYS5wYXJlbnROb2RlKS5x
-dWVyeVNlbGVjdG9yKCI6c2NvcGUgPiB1bCIpLHI9cy5zdHlsZSxxPSIiK0MuQ0QuelEocy5vZmZzZXRI
-ZWlnaHQpKjIrInB4IgpyLm1heEhlaWdodD1xCnI9Si5xRihhKQpxPXIuJHRpCnQ9cS5DKCJ+KDEpIiku
-YShuZXcgTC5XeChzLGEpKQp1Lk0uYShudWxsKQpXLkpFKHIuYSxyLmIsdCwhMSxxLmMpfSwKeVg6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89InF1ZXJ5U2VsZWN0b3JBbGwiLG49ZG9jdW1lbnQucXVl
-cnlTZWxlY3RvcihhKSxtPXUuaApuLnRvU3RyaW5nCkguRGgobSxtLCJUIixvKQp0PXUuVApzPW5ldyBX
-Lnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1saW5rIiksdCkKcy5LKHMsbmV3IEwuQU8oYikpCkgu
-RGgobSxtLCJUIixvKQpyPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLnJlZ2lvbiIpLHQpCmlm
-KHIuZ0EocikhPT0wKXtxPW4ucXVlcnlTZWxlY3RvcigidGFibGVbZGF0YS1wYXRoXSIpCnEudG9TdHJp
-bmcKci5LKHIsbmV3IEwuSG8ocS5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhx
-KSkuTygicGF0aCIpKSkpfUguRGgobSxtLCJUIixvKQpwPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3RvckFs
-bCgiLmFkZC1oaW50LWxpbmsiKSx0KQpwLksocCxuZXcgTC5JQygpKX0sClE2OmZ1bmN0aW9uKGEsYil7
-dmFyIHQ9dS5OCnJldHVybiBXLnFEKEwuUTQoYSxiKSxQLkVGKFsiQ29udGVudC1UeXBlIiwiYXBwbGlj
-YXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCJdLHQsdCkpfSwKdHk6ZnVuY3Rpb24oYSxiKXt2YXIgdD0w
-LHM9UC5GWCh1LlMpLHIscSxwLG8sbixtLGwsawp2YXIgJGFzeW5jJHR5PVAubHooZnVuY3Rpb24oYyxk
-KXtpZihjPT09MSlyZXR1cm4gUC5mMyhkLHMpCndoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2UgMDpuPW5l
-dyBQLnZzKCQuWDMsdS5ZKQptPW5ldyBQLlpmKG4sdS5FKQpsPW5ldyBYTUxIdHRwUmVxdWVzdCgpCms9
-dS5OCkMuRHQuZW8obCwiUE9TVCIsTC5RNChhLFAuRmwoayxrKSksITApCmwuc2V0UmVxdWVzdEhlYWRl
-cigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCIpCms9dS5hbgpx
-PWsuYShuZXcgTC5MMShtLGwpKQp1Lk0uYShudWxsKQpwPXUucApXLkpFKGwsImxvYWQiLHEsITEscCkK
-Vy5KRShsLCJlcnJvciIsay5hKG0uZ1lKKCkpLCExLHApCmwuc2VuZChiPT1udWxsP251bGw6Qy5DdC5P
-QihiLG51bGwpKQp0PTMKcmV0dXJuIFAualEobiwkYXN5bmMkdHkpCmNhc2UgMzpvPUMuQ3QucFcoMCxs
-LnJlc3BvbnNlVGV4dCxudWxsKQppZihsLnN0YXR1cz09PTIwMCl7cj11LlMuYShvKQp0PTEKYnJlYWt9
-ZWxzZSB0aHJvdyBILmIobykKY2FzZSAxOnJldHVybiBQLnlDKHIscyl9fSkKcmV0dXJuIFAuREkoJGFz
-eW5jJHR5LHMpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHQ9UC5oSyhhKS5naFkoKS5xKDAsImxpbmUiKQpy
-ZXR1cm4gdD09bnVsbD9udWxsOkguSHAodCxudWxsKX0sCkc2OmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEso
-YSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAodCxudWxsKX0sCmk2
-OmZ1bmN0aW9uKGEpe3JldHVybiBMLm5XKHUuVi5hKGEpKX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciB0PTAs
-cz1QLkZYKHUueikscj0xLHEscD1bXSxvLG4sbSxsLGsKdmFyICRhc3luYyRpNj1QLmx6KGZ1bmN0aW9u
-KGIsYyl7aWYoYj09PTEpe3E9Ywp0PXJ9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOmw9dS5oLmEo
-Vy5xYyhhLmN1cnJlbnRUYXJnZXQpKS5nZXRBdHRyaWJ1dGUoImhyZWYiKQphLnByZXZlbnREZWZhdWx0
-KCkKcj0zCnQ9NgpyZXR1cm4gUC5qUShMLnR5KGwsbnVsbCksJGFzeW5jJGk2KQpjYXNlIDY6dS5hXy5h
-KEouR3IoVy5Qdihkb2N1bWVudC5kZWZhdWx0VmlldykpKS5yZWxvYWQoKQpyPTEKdD01CmJyZWFrCmNh
-c2UgMzpyPTIKaz1xCm89SC5SdShrKQpuPUgudHMoaykKTC5DMigiQ291bGQgbm90IGFkZC9yZW1vdmUg
-aGludCIsbyxuKQp0PTUKYnJlYWsKY2FzZSAyOnQ9MQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVs
-bCxzKQpjYXNlIDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkaTYscyl9LApD
-MjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPSJleGNlcHRpb24iLHE9InN0YWNrVHJhY2UiLHA9dS5T
-LmIoYikmJkouUk0oYi5xKDAsInN1Y2Nlc3MiKSwhMSkmJkgub1QoYi54NChyKSkmJkgub1QoYi54NChx
-KSksbz1KLmlhKGIpCmlmKHApe3Q9SC5jKG8ucShiLHIpKQpjPW8ucShiLHEpfWVsc2UgdD1vLlooYikK
-cD1kb2N1bWVudApzPXAucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpzLnF1ZXJ5U2VsZWN0b3Io
-ImgyIikuaW5uZXJUZXh0PWEKcy5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PXQKcy5xdWVyeVNl
-bGVjdG9yKCJwcmUiKS5pbm5lclRleHQ9Si5BYyhjKQpvPXUuTgp1LmJxLmEocy5xdWVyeVNlbGVjdG9y
-KCJhLmJvdHRvbSIpKS5ocmVmPVAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9zZGsv
-aXNzdWVzL25ldyIsUC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVwb3J0ZWQgaXNzdWUgd2l0aCBOTkJE
-IG1pZ3JhdGlvbiB0b29sOiAiK2EsImxhYmVscyIsImFyZWEtYW5hbHl6ZXIsYW5hbHl6ZXItbm5iZC1t
-aWdyYXRpb24sdHlwZS1idWciLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5kKHQpKyJcblxuUGxlYXNl
-IGZpbGwgaW4gdGhlIGZvbGxvd2luZzpcblxuKipOYW1lIG9mIHBhY2thZ2UgYmVpbmcgbWlncmF0ZWQg
-KGlmIHB1YmxpYykqKjpcbioqV2hhdCBJIHdhcyBkb2luZyB3aGVuIHRoaXMgaXNzdWUgb2NjdXJyZWQq
-KjpcbioqSXMgaXQgcG9zc2libGUgdG8gd29yayBhcm91bmQgdGhpcyBpc3N1ZSoqOlxuKipIYXMgdGhp
-cyBpc3N1ZSBoYXBwZW5lZCBiZWZvcmUsIGFuZCBpZiBzbywgaG93IG9mdGVuKio6XG4qKkRhcnQgU0RL
-IHZlcnNpb24qKjogIitILmQocC5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVu
-dCkrIlxuKipBZGRpdGlvbmFsIGRldGFpbHMqKjpcblxuVGhhbmtzIGZvciBmaWxpbmchXG5cblN0YWNr
-dHJhY2U6IF9hdXRvIHBvcHVsYXRlZCBieSBtaWdyYXRpb24gcHJldmlldyB0b29sLl9cblxuYGBgXG4i
-K0guZChjKSsiXG5gYGBcbiJdLG8sbykpLlooMCkKbz1zLnN0eWxlCm8uZGlzcGxheT0iaW5pdGlhbCIK
-TC5xSihhKyI6ICIrSC5kKGIpLGMpfSwKdDI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxu
-PXt9LG09dS5oLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKQphLnByZXZlbnREZWZhdWx0KCkKdD1uLmE9
-bS5nZXRBdHRyaWJ1dGUoImhyZWYiKQppZihKLnpsKHQsIj8iKSl7cz1DLnhCLk5qKHQsMCxDLnhCLk9Z
-KHQsIj8iKSkKbi5hPXMKcj1zfWVsc2Ugcj10CmlmKGMhPW51bGwpe3E9JC5uVSgpCnI9bi5hPXEubzUo
-RC5ucihxLnpmKGMpLHIpKX1wPUwuRzYodCkKbz1MLmFLKHQpCmlmKHAhPW51bGwpTC5hZihyLHAsbyxi
-LG5ldyBMLm5UKG4scCxvKSkKZWxzZSBMLmFmKHIsbnVsbCxudWxsLGIsbmV3IEwuQloobikpfSwKdlU6
-ZnVuY3Rpb24oKXt2YXIgdD1kb2N1bWVudCxzPXUuaApILkRoKHMscywiVCIsInF1ZXJ5U2VsZWN0b3JB
-bGwiKQp0PW5ldyBXLnd6KHQucXVlcnlTZWxlY3RvckFsbCgiLmNvZGUiKSx1LlQpCnQuSyh0LG5ldyBM
-LkdIKCkpfSwKaFg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PXUuTgpMLlE2KGEsUC5FRihbInJlZ2lvbiIs
-InJlZ2lvbiIsIm9mZnNldCIsSC5kKGIpXSx0LHQpKS5XNyhuZXcgTC5EVChhLGIsYyksdS5QKS5PQShu
-ZXcgTC5lSChhKSl9LApHNzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0CmlmKCFKLnA0KGEsIi5kYXJ0
-Iikpe0wuQkUoYSxuZXcgQi5xcCgiIiwiIiwiIixDLkNNKSxkKQpMLkJYKGEsbnVsbCkKaWYoZSE9bnVs
-bCllLiQwKCkKcmV0dXJufXQ9dS5OCkwuUTYoYSxQLkVGKFsiaW5saW5lIiwidHJ1ZSJdLHQsdCkpLlc3
-KG5ldyBMLnl1KGEsZCxiLGMsZSksdS5QKS5PQShuZXcgTC56RChhKSl9LApHZTpmdW5jdGlvbigpe3Zh
-ciB0PSIvX3ByZXZpZXcvbmF2aWdhdGlvblRyZWUuanNvbiIKTC5RNih0LEMuV08pLlc3KG5ldyBMLlRX
-KCksdS5QKS5PQShuZXcgTC54cih0KSl9LApxSjpmdW5jdGlvbihhLGIpe3ZhciB0CndpbmRvdwppZih0
-eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUuZXJyb3IoYSkKd2luZG93CnQ9
-SC5kKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS5lcnJvcih0
-KX0sCnFPOmZ1bmN0aW9uKGEpe3ZhciB0LHM9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxyPUMuQ0Qu
-elEoJC5maSgpLm9mZnNldEhlaWdodCkscT13aW5kb3cuaW5uZXJIZWlnaHQscD1DLkNELnpRKCQuRFco
-KS5vZmZzZXRIZWlnaHQpCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIHEuSE4oKQp0PXMuYm90
-dG9tCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQub3MoKQppZih0PnEtKHArMTQpKUouZGgo
-YSkKZWxzZXtxPXMudG9wCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIHEuSigpCmlmKHE8cisx
-NClKLmRoKGEpfX0sCmZHOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmlmKGEhPW51bGwpe3Q9ZG9jdW1l
-bnQKcz10LmdldEVsZW1lbnRCeUlkKCJvIitILmQoYSkpCnI9dC5xdWVyeVNlbGVjdG9yKCIubGluZS0i
-K0guZChiKSkKaWYocyE9bnVsbCl7TC5xTyhzKQpKLmRSKHMpLmkoMCwidGFyZ2V0Iil9ZWxzZSBpZihy
-IT1udWxsKUwucU8oci5wYXJlbnRFbGVtZW50KQppZihyIT1udWxsKUouZFIodS5oLmEoci5wYXJlbnRO
-b2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNlIEwucU8oJC5EOSgpKX0sCmFmOmZ1bmN0aW9uKGEsYixj
-LGQsZSl7dmFyIHQscyxyPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpLHE9TC5hSyh3aW5kb3cubG9j
-YXRpb24uaHJlZikKaWYociE9bnVsbCl7dD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgibyIrSC5kKHIp
-KQppZih0IT1udWxsKUouZFIodCkuUigwLCJ0YXJnZXQiKX1pZihxIT1udWxsKXtzPWRvY3VtZW50LnF1
-ZXJ5U2VsZWN0b3IoIi5saW5lLSIrSC5kKHEpKQppZihzIT1udWxsKUouZFIocy5wYXJlbnRFbGVtZW50
-KS5SKDAsImhpZ2hsaWdodCIpfWlmKGE9PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSl7TC5mRyhiLGMp
-CmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0sClE0OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPVAu
-aEsoYSkscT11Lk4KcT1QLkZsKHEscSkKZm9yKHQ9ci5naFkoKSx0PXQuZ1B1KHQpLHQ9dC5na3oodCk7
-dC5GKCk7KXtzPXQuZ2woKQpxLlkoMCxzLmEscy5iKX1mb3IodD1iLmdQdShiKSx0PXQuZ2t6KHQpO3Qu
-RigpOyl7cz10LmdsKCkKcS5ZKDAscy5hLHMuYil9cS5ZKDAsImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1
-cm4gci5ubSgwLHEpLlooMCl9LApUMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsaz0k
-LmhMKCkKSi5sNShrLCIiKQppZihhPT1udWxsKXt0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInAiKQp0
-LnRleHRDb250ZW50PSJTZWUgZGV0YWlscyBhYm91dCBhIHByb3Bvc2VkIGVkaXQuIgpDLkx0LnNQKHQs
-SC5WTShbInBsYWNlaG9sZGVyIl0sdS5zKSkKay5hcHBlbmRDaGlsZCh0KQpDLkx0LkZGKHQpCnJldHVy
-bn1zPWEuZApyPSQublUoKQpxPXIuemYocykKcD1hLmIKbz1kb2N1bWVudApuPXIuSFAocyxKLlQwKG8u
-cXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpCm09YS5jCmw9by5jcmVhdGVFbGVtZW50
-KCJwIikKay5hcHBlbmRDaGlsZChsKQpsLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoSC5kKHAp
-KyIgYXQgIikpCnI9dS5OCnI9Vy5KNihMLlE0KHMsUC5FRihbImxpbmUiLEouQWMobSldLHIscikpKQpy
-LmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoSC5kKG4pKyI6IitILmQobSkrIi4iKSkKbC5hcHBl
-bmRDaGlsZChyKQpKLmRoKGwpCkwuQ0MoYSxrLHEpCkwuRnooYSxrKX0sCkxIOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnPSQueVAoKQpKLmw1KGcsIiIpCmlmKGIuZ0Eo
-Yik9PT0wKXt0PWRvY3VtZW50CnM9dC5jcmVhdGVFbGVtZW50KCJwIikKZy5hcHBlbmRDaGlsZChzKQpz
-LmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUoIk5vIHByb3Bvc2VkIGVkaXRzIikpfWVsc2UgZm9y
-KGc9Yi5nUHUoYiksZz1nLmdreihnKSx0PXUuUSxyPXQuQygifigxKSIpLHE9dS5NLHQ9dC5jO2cuRigp
-Oyl7cD1nLmdsKCkKbz1kb2N1bWVudApzPW8uY3JlYXRlRWxlbWVudCgicCIpCm49JC55UCgpCm4uYXBw
-ZW5kQ2hpbGQocykKcy5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKEguZChwLmEpKyI6IikpCm09
-by5jcmVhdGVFbGVtZW50KCJ1bCIpCm4uYXBwZW5kQ2hpbGQobSkKZm9yKHA9Si5JVChwLmIpO3AuRigp
-Oyl7bj1wLmdsKCkKbD1vLmNyZWF0ZUVsZW1lbnQoImxpIikKbS5hcHBlbmRDaGlsZChsKQpKLmRSKGwp
-LmkoMCwiZWRpdCIpCms9by5jcmVhdGVFbGVtZW50KCJhIikKbC5hcHBlbmRDaGlsZChrKQprLmNsYXNz
-TGlzdC5hZGQoImVkaXQtbGluayIpCmo9bi5jCmk9SC5kKGopCmsuc2V0QXR0cmlidXRlKCJkYXRhLSIr
-bmV3IFcuU3kobmV3IFcuaTcoaykpLk8oIm9mZnNldCIpLGkpCmg9bi5hCmk9SC5kKGgpCmsuc2V0QXR0
-cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcoaykpLk8oImxpbmUiKSxpKQprLmFwcGVuZENo
-aWxkKG8uY3JlYXRlVGV4dE5vZGUoImxpbmUgIitILmQoaCkpKQppPXIuYShuZXcgTC5FRShqLGgsYSkp
-CnEuYShudWxsKQpXLkpFKGssImNsaWNrIixpLCExLHQpCmwuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0
-Tm9kZSgiOiAiK0guZChuLmIpKSl9fWlmKGMpTC5UMShudWxsKX0sCkZyOmZ1bmN0aW9uKGEsYixjKXt2
-YXIgdCxzLHI9d2luZG93LmxvY2F0aW9uLHE9UC5oSygociYmQy5FeCkuZ0RyKHIpK0guZChhKSkKcj11
-Lk4Kcj1QLkZsKHIscikKaWYoYiE9bnVsbClyLlkoMCwib2Zmc2V0IixILmQoYikpCmlmKGMhPW51bGwp
-ci5ZKDAsImxpbmUiLEguZChjKSkKci5ZKDAsImF1dGhUb2tlbiIsJC5VRSgpKQpxPXEubm0oMCxyKQpy
-PXdpbmRvdy5oaXN0b3J5CnQ9dS56CnM9cS5aKDApCnIudG9TdHJpbmcKci5wdXNoU3RhdGUobmV3IFAu
-QmYoW10sW10pLlB2KFAuRmwodCx0KSksIiIscyl9LApFbjpmdW5jdGlvbihhKXt2YXIgdD1KLm0oZG9j
-dW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCwiLyIpCmlmKEMueEIubihhLHQp
-KXJldHVybiBDLnhCLkcoYSx0Lmxlbmd0aCkKZWxzZSByZXR1cm4gYX0sCkJYOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQokLkQ5KCkudGV4dENvbnRlbnQ9YQp0PWRv
-Y3VtZW50CnM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnQ9bmV3IFcud3oodC5x
-dWVyeVNlbGVjdG9yQWxsKCIubmF2LXBhbmVsIC5uYXYtbGluayIpLHUuVCkKdC5LKHQsbmV3IEwuVlMo
-cikpfSwKQkU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSIucmVnaW9ucyIscz1kb2N1bWVudCxyPXMucXVl
-cnlTZWxlY3Rvcih0KSxxPXMucXVlcnlTZWxlY3RvcigiLmNvZGUiKQpKLnRIKHIsYi5hLCQuS0coKSkK
-Si50SChxLGIuYiwkLktHKCkpCkwuTEgoYSxiLmQsYykKTC52VSgpCkwueVgoIi5jb2RlIiwhMCkKTC55
-WCh0LCEwKX0sCnRYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZz1k
-b2N1bWVudCxmPWcuY3JlYXRlRWxlbWVudCgidWwiKQphLmFwcGVuZENoaWxkKGYpCmZvcih0PWIubGVu
-Z3RoLHM9dS5NLHI9MDtyPGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAsSC5saykoYiksKytyKXtxPWJb
-cl0KcD1nLmNyZWF0ZUVsZW1lbnQoImxpIikKZi5hcHBlbmRDaGlsZChwKQpvPUouUkUocCkKaWYocS5h
-PT09Qy5ZMil7by5nUChwKS5pKDAsImRpciIpCm49Zy5jcmVhdGVFbGVtZW50KCJzcGFuIikKcC5hcHBl
-bmRDaGlsZChuKQpvPUouUkUobikKby5nUChuKS5pKDAsImFycm93IikKby5zaGYobiwiJiN4MjVCQzsi
-KQptPWcuY3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5kQ2hpbGQobSkKSi5sNShtLCImI3gxRjRD
-MTsiKQpwLmFwcGVuZENoaWxkKGcuY3JlYXRlVGV4dE5vZGUocS5iKSkKTC50WChwLHEuYykKTC5reihu
-KX1lbHNle28uc2hmKHAsIiYjeDFGNEM0OyIpCmw9Zy5jcmVhdGVFbGVtZW50KCJhIikKcC5hcHBlbmRD
-aGlsZChsKQpvPUouUkUobCkKby5nUChsKS5pKDAsIm5hdi1saW5rIikKbC5zZXRBdHRyaWJ1dGUoImRh
-dGEtIituZXcgVy5TeShuZXcgVy5pNyhsKSkuTygibmFtZSIpLHEuZCkKbC5zZXRBdHRyaWJ1dGUoImhy
-ZWYiLHEuZSkKbC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKHEuYikpCm89by5nVmwobCkKaz1v
-LiR0aQpqPWsuQygifigxKSIpLmEobmV3IEwuVEQoKSkKcy5hKG51bGwpClcuSkUoby5hLG8uYixqLCEx
-LGsuYykKaT1xLmYKaWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gaS5vcygpCmlmKGk+MCl7aD1n
-LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwLmFwcGVuZENoaWxkKGgpCkouZFIoaCkuaSgwLCJlZGl0LWNv
-dW50IikKbz0iIitpKyIgIgppZihpPT09MSlrPSJlZGl0IgplbHNlIGs9ImVkaXRzIgpoLnNldEF0dHJp
-YnV0ZSgidGl0bGUiLG8raykKaC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKEMuam4uWihpKSkp
-fX19fSwKRno6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGk9YS5hCmlmKGk9
-PW51bGwpcmV0dXJuCnQ9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1lbnQoInAiKQpyPWIuYXBwZW5kQ2hp
-bGQocykKcz10LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpxPXUucwpKLk11KHMsSC5WTShbInR5cGUtZGVz
-Y3JpcHRpb24iXSxxKSkKcy5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKCJBY3Rpb25zIikpCnIu
-YXBwZW5kQ2hpbGQocykKci5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKCI6IikpCnA9dC5jcmVh
-dGVFbGVtZW50KCJwIikKYi5hcHBlbmRDaGlsZChwKQpmb3Iocz1pLmxlbmd0aCxvPXUuWCxuPTA7bjxp
-Lmxlbmd0aDtpLmxlbmd0aD09PXN8fCgwLEgubGspKGkpLCsrbil7bT1pW25dCmw9dC5jcmVhdGVFbGVt
-ZW50KCJhIikKcC5hcHBlbmRDaGlsZChsKQpsLmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUobS5h
-KSkKbC5zZXRBdHRyaWJ1dGUoImhyZWYiLG0uYikKaz1vLmEoSC5WTShbImFkZC1oaW50LWxpbmsiLCJi
-ZWZvcmUtYXBwbHkiLCJidXR0b24iXSxxKSkKaj1KLmRSKGwpCmouVjEoMCkKai5GVigwLGspfX0sCkND
-OmZ1bmN0aW9uKGIwLGIxLGIyKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMs
-YixhLGEwLGExLGEyLGEzLGE0LGE1LGE2LGE3LGE4LGE5PW51bGwKZm9yKHQ9YjAuZSxzPXQubGVuZ3Ro
-LHI9dS5zLHE9dS5YLHA9dS5RLG89cC5DKCJ+KDEpIiksbj11Lk0scD1wLmMsbT0wO208dC5sZW5ndGg7
-dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK20pe2w9dFttXQprPWRvY3VtZW50Cmo9ay5jcmVhdGVF
-bGVtZW50KCJwIikKaT1xLmEoSC5WTShbInRyYWNlIl0scikpCmg9Si5kUihqKQpoLlYxKDApCmguRlYo
-MCxpKQpnPWIxLmFwcGVuZENoaWxkKGopCmo9ay5jcmVhdGVFbGVtZW50KCJzcGFuIikKaT1xLmEoSC5W
-TShbInR5cGUtZGVzY3JpcHRpb24iXSxyKSkKaD1KLmRSKGopCmguVjEoMCkKaC5GVigwLGkpCmouYXBw
-ZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZShsLmEpKQpnLmFwcGVuZENoaWxkKGopCmcuYXBwZW5kQ2hp
-bGQoay5jcmVhdGVUZXh0Tm9kZSgiOiIpKQpqPWsuY3JlYXRlRWxlbWVudCgidWwiKQppPXEuYShILlZN
-KFsidHJhY2UiXSxyKSkKaD1KLmRSKGopCmguVjEoMCkKaC5GVigwLGkpCmY9Zy5hcHBlbmRDaGlsZChq
-KQpmb3Ioaj1sLmIsaT1qLmxlbmd0aCxlPTA7ZTxqLmxlbmd0aDtqLmxlbmd0aD09PWl8fCgwLEgubGsp
-KGopLCsrZSl7ZD1qW2VdCmM9ay5jcmVhdGVFbGVtZW50KCJsaSIpCmYuYXBwZW5kQ2hpbGQoYykKYj1r
-LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQphPXEuYShILlZNKFsiZnVuY3Rpb24iXSxyKSkKaD1KLmRSKGIp
-CmguVjEoMCkKaC5GVigwLGEpCmE9ZC5iCkwua0QoYixhPT1udWxsPyJ1bmtub3duIjphKQpjLmFwcGVu
-ZENoaWxkKGIpCmEwPWQuYwppZihhMCE9bnVsbCl7Yy5hcHBlbmRDaGlsZChrLmNyZWF0ZVRleHROb2Rl
-KCIgKCIpKQphMT1hMC5iCmEyPWsuY3JlYXRlRWxlbWVudCgiYSIpCmEyLmFwcGVuZENoaWxkKGsuY3Jl
-YXRlVGV4dE5vZGUoSC5kKGEwLmMpKyI6IitILmQoYTEpKSkKYTM9YTAuYQpiPSQublUoKQphMi5zZXRB
-dHRyaWJ1dGUoImhyZWYiLGIubzUoYi5xNygwLGIyLGEzLGE5LGE5LGE5LGE5LGE5LGE5KSkpCmEyLmNs
-YXNzTGlzdC5hZGQoIm5hdi1saW5rIikKYy5hcHBlbmRDaGlsZChhMikKYy5hcHBlbmRDaGlsZChrLmNy
-ZWF0ZVRleHROb2RlKCIpIikpfWMuYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZSgiOiAiKSkKYj1k
-LmEKTC5rRChjLGI9PW51bGw/InVua25vd24iOmIpCmI9ZC5kCmlmKGIubGVuZ3RoIT09MCl7YT1rLmNy
-ZWF0ZUVsZW1lbnQoInAiKQphND1xLmEoSC5WTShbImRyYXdlciIsImJlZm9yZS1hcHBseSJdLHIpKQpo
-PUouZFIoYSkKaC5WMSgwKQpoLkZWKDAsYTQpCmE1PWMuYXBwZW5kQ2hpbGQoYSkKZm9yKGE9Yi5sZW5n
-dGgsYTY9MDthNjxiLmxlbmd0aDtiLmxlbmd0aD09PWF8fCgwLEgubGspKGIpLCsrYTYpe2E3PWJbYTZd
-CmE0PWsuY3JlYXRlRWxlbWVudCgiYnV0dG9uIikKYTg9by5hKG5ldyBMLkFTKGE3LGEwKSkKbi5hKG51
-bGwpClcuSkUoYTQsImNsaWNrIixhOCwhMSxwKQphNC5hcHBlbmRDaGlsZChrLmNyZWF0ZVRleHROb2Rl
-KE0uT1goYTcuYSkpKQphNS5hcHBlbmRDaGlsZChhNCl9fX19fSwKa0Q6ZnVuY3Rpb24oYSxiKXt2YXIg
-dCxzLHI9SC5WTShiLnNwbGl0KCIuIiksdS5zKSxxPUMuTm0uZ3RIKHIpLHA9ZG9jdW1lbnQKYS5hcHBl
-bmRDaGlsZChwLmNyZWF0ZVRleHROb2RlKHEpKQpmb3IocT1ILnFDKHIsMSxudWxsLHUuTikscT1uZXcg
-SC5hNyhxLHEuZ0EocSkscS4kdGkuQygiYTc8YUwuRT4iKSksdD1KLlJFKGEpO3EuRigpOyl7cz1xLmQK
-dC5ueihhLCJiZWZvcmVlbmQiLCImIzgyMDM7LiIsbnVsbCxudWxsKQphLmFwcGVuZENoaWxkKHAuY3Jl
-YXRlVGV4dE5vZGUocykpfX0sCmU6ZnVuY3Rpb24gZSgpe30sClZXOmZ1bmN0aW9uIFZXKGEsYixjKXt0
-aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCm9aOmZ1bmN0aW9uIG9aKCl7fSwKanI6ZnVuY3Rpb24g
-anIoKXt9LApxbDpmdW5jdGlvbiBxbCgpe30sCnk4OmZ1bmN0aW9uIHk4KCl7fSwKSGk6ZnVuY3Rpb24g
-SGkoKXt9LApCVDpmdW5jdGlvbiBCVCgpe30sCkw6ZnVuY3Rpb24gTCgpe30sCld4OmZ1bmN0aW9uIFd4
-KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBTzpmdW5jdGlvbiBBTyhhKXt0aGlzLmE9YX0sCmROOmZ1
-bmN0aW9uIGROKGEpe3RoaXMuYT1hfSwKSG86ZnVuY3Rpb24gSG8oYSl7dGhpcy5hPWF9LAp4ejpmdW5j
-dGlvbiB4eihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSUM6ZnVuY3Rpb24gSUMoKXt9LApMMTpmdW5j
-dGlvbiBMMShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMu
-YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKQlo6ZnVuY3Rpb24gQlooYSl7dGhpcy5hPWF9LApHSDpmdW5j
-dGlvbiBHSCgpe30sCkRUOmZ1bmN0aW9uIERUKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
-Y30sCmVIOmZ1bmN0aW9uIGVIKGEpe3RoaXMuYT1hfSwKeXU6ZnVuY3Rpb24geXUoYSxiLGMsZCxlKXt2
-YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKekQ6ZnVuY3Rpb24gekQoYSl7
-dGhpcy5hPWF9LApUVzpmdW5jdGlvbiBUVygpe30sCnhyOmZ1bmN0aW9uIHhyKGEpe3RoaXMuYT1hfSwK
-RUU6ZnVuY3Rpb24gRUUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUUw6ZnVuY3Rp
-b24gUUwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClZTOmZ1bmN0aW9uIFZTKGEpe3RoaXMuYT1hfSwK
-VEQ6ZnVuY3Rpb24gVEQoKXt9LApBUzpmdW5jdGlvbiBBUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
-WEE6ZnVuY3Rpb24gWEEoKXt9LAptSzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbj1ILlZNKFtd
-LHUuZmgpCmZvcih0PUouSVQodS5SLmEoYSkpO3QuRigpOyl7cz10LmdsKCkKcj1KLlU2KHMpCnE9TC5w
-MihILmMoci5xKHMsInR5cGUiKSkpCnA9SC5jKHIucShzLCJuYW1lIikpCm89ci5xKHMsInN1YnRyZWUi
-KQpvPW89PW51bGw/bnVsbDpMLm1LKG8pCkMuTm0uaShuLG5ldyBMLlpaKHEscCxvLEguYyhyLnEocywi
-cGF0aCIpKSxILmMoci5xKHMsImhyZWYiKSksSC5XWShyLnEocywiZWRpdENvdW50IikpKSl9cmV0dXJu
-IG59LApWRDpmdW5jdGlvbihhKXt2YXIgdCxzLHI9SC5WTShbXSx1LkopCmZvcih0PWEubGVuZ3RoLHM9
-MDtzPGEubGVuZ3RoO2EubGVuZ3RoPT09dHx8KDAsSC5saykoYSksKytzKUMuTm0uaShyLGFbc10uTHQo
-KSkKcmV0dXJuIHJ9LApwMjpmdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2FzZSJkaXJlY3RvcnkiOnJldHVy
-biBDLlkyCmNhc2UiZmlsZSI6cmV0dXJuIEMucmYKZGVmYXVsdDp0aHJvdyBILmIoUC5QVigiVW5yZWNv
-Z25pemVkIG5hdmlnYXRpb24gdHJlZSBub2RlIHR5cGU6ICIrSC5kKGEpKSl9fSwKdnk6ZnVuY3Rpb24o
-YSl7c3dpdGNoKGEpe2Nhc2UgQy5ZMjpyZXR1cm4iZGlyZWN0b3J5IgpjYXNlIEMucmY6cmV0dXJuImZp
-bGUifXRocm93IEguYihQLlBWKCJVbnJlY29nbml6ZWQgbmF2aWdhdGlvbiB0cmVlIG5vZGUgdHlwZTog
-IithLlooMCkpKX0sClpaOmZ1bmN0aW9uIFpaKGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8u
-Yj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKTzk6ZnVuY3Rpb24gTzkoYSl7dGhpcy5iPWF9LApJ
-VjpmdW5jdGlvbiBJVihhLGIsYyxkKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0s
-WD17CkNMOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPWIueFooYSkKYi5oSyhhKQppZihvIT1u
-dWxsKWE9Si5LVihhLG8ubGVuZ3RoKQp0PXUucwpzPUguVk0oW10sdCkKcj1ILlZNKFtdLHQpCnQ9YS5s
-ZW5ndGgKaWYodCE9PTAmJmIucjQoQy54Qi5XKGEsMCkpKXtpZigwPj10KXJldHVybiBILmsoYSwwKQpD
-Lk5tLmkocixhWzBdKQpxPTF9ZWxzZXtDLk5tLmkociwiIikKcT0wfWZvcihwPXE7cDx0OysrcClpZihi
-LnI0KEMueEIuVyhhLHApKSl7Qy5ObS5pKHMsQy54Qi5OaihhLHEscCkpCkMuTm0uaShyLGFbcF0pCnE9
-cCsxfWlmKHE8dCl7Qy5ObS5pKHMsQy54Qi5HKGEscSkpCkMuTm0uaShyLCIiKX1yZXR1cm4gbmV3IFgu
-V0QoYixvLHMscil9LApXRDpmdW5jdGlvbiBXRChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
-Cl8uZD1jCl8uZT1kfSwKcVI6ZnVuY3Rpb24gcVIoYSl7dGhpcy5hPWF9LApJNzpmdW5jdGlvbihhKXty
-ZXR1cm4gbmV3IFguZHYoYSl9LApkdjpmdW5jdGlvbiBkdihhKXt0aGlzLmE9YX19LE89ewpSaDpmdW5j
-dGlvbigpe3ZhciB0LHM9bnVsbAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJuICQuRWIoKQp0
-PVAudW8oKQppZighQy54Qi5UYyh0LmdJaSh0KSwiLyIpKXJldHVybiAkLkViKCkKaWYoUC5LTChzLCJh
-L2IiLHMscyxzLHMscykudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAkLmJEKCl9LAp6
-TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9YQp0aGlzLmU9
-Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5l
-PWIKXy5mPWMKXy5yPWR9fSxEPXsKUlg6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPW51bGwKdHJ5e3A9
-UC51bygpfWNhdGNoKHQpe2lmKHUuZzguYihILlJ1KHQpKSl7cz0kLkZmCmlmKHMhPW51bGwpcmV0dXJu
-IHMKdGhyb3cgdH1lbHNlIHRocm93IHR9aWYoSi5STShwLCQuSTYpKXJldHVybiAkLkZmCiQuSTY9cApp
-ZigkLkhrKCk9PSQuRWIoKSlzPSQuRmY9cC5aSSgiLiIpLlooMCkKZWxzZXtyPXAudDQoKQpxPXIubGVu
-Z3RoLTEKcz0kLkZmPXE9PT0wP3I6Qy54Qi5OaihyLDAscSl9cmV0dXJuIHN9LApucjpmdW5jdGlvbihh
-LGIpe3ZhciB0PW51bGwKcmV0dXJuICQublUoKS5xNygwLGEsYix0LHQsdCx0LHQsdCl9fQp2YXIgdz1b
-QyxILEosUCxXLE0sVSxCLFQsTCxYLE8sRSxGLERdCmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJ
-Zk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILkZLLnByb3RvdHlwZT17fQpKLnZCLnByb3RvdHlwZT17CkRO
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEp
-fSwKWjpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEgubGgoYSkpKyInIn0sCmU3
-OmZ1bmN0aW9uKGEsYil7dS5vLmEoYikKdGhyb3cgSC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5n
-Vm0oKSkpfX0KSi55RS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApn
-aU86ZnVuY3Rpb24oYSl7cmV0dXJuIGE/NTE5MDE4OjIxODE1OX0sCiRpYTI6MX0KSi5ZRS5wcm90b3R5
-cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsPT1ifSwKWjpmdW5jdGlvbihhKXtyZXR1cm4i
-bnVsbCJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0
-aGlzLlNqKGEsdS5vLmEoYikpfSwKJGljODoxfQpKLk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihh
-KXtyZXR1cm4gMH0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5w
-cm90b3R5cGU9e30KSi5rZC5wcm90b3R5cGU9e30KSi5jNS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEp
-e3ZhciB0PWFbJC53USgpXQppZih0PT1udWxsKXJldHVybiB0aGlzLnQoYSkKcmV0dXJuIkphdmFTY3Jp
-cHQgZnVuY3Rpb24gZm9yICIrSC5kKEouQWModCkpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm57ZnVuYzox
-LG9wdDpbLCwsLCwsLCwsLCwsLCwsLF19fSwKJGlFSDoxfQpKLmpkLnByb3RvdHlwZT17Cmk6ZnVuY3Rp
-b24oYSxiKXtILnQ2KGEpLmMuYShiKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiYWRkIikp
-CmEucHVzaChiKX0sClc0OmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoISFhLmZpeGVkJGxlbmd0aClILnZo
-KFAuTDQoInJlbW92ZUF0IikpCnQ9YS5sZW5ndGgKaWYoYj49dCl0aHJvdyBILmIoUC5PNyhiLG51bGwp
-KQpyZXR1cm4gYS5zcGxpY2UoYiwxKVswXX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKSC50
-NihhKS5DKCJjWDwxPiIpLmEoYykKaWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImluc2VydEFs
-bCIpKQp0PWEubGVuZ3RoClAud0EoYiwwLHQsImluZGV4IikKcz1jLmxlbmd0aAp0aGlzLnNBKGEsdCtz
-KQpyPWIrcwp0aGlzLllXKGEscixhLmxlbmd0aCxhLGIpCnRoaXMudmcoYSxiLHIsYyl9LAptdjpmdW5j
-dGlvbihhKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgicmVtb3ZlTGFzdCIpKQppZihhLmxl
-bmd0aD09PTApdGhyb3cgSC5iKEguSFkoYSwtMSkpCnJldHVybiBhLnBvcCgpfSwKRlY6ZnVuY3Rpb24o
-YSxiKXt2YXIgdApILnQ2KGEpLkMoImNYPDE+IikuYShiKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgo
-UC5MNCgiYWRkQWxsIikpCmZvcih0PUouSVQoYik7dC5GKCk7KWEucHVzaCh0LmdsKCkpfSwKSzpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMKSC50NihhKS5DKCJ+KDEpIikuYShiKQp0PWEubGVuZ3RoCmZvcihzPTA7
-czx0Oysrcyl7Yi4kMShhW3NdKQppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCkUy
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILnQ2KGEpCnJldHVybiBuZXcgSC5sSihhLHQuS3EoYykuQygi
-MSgyKSIpLmEoYiksdC5DKCJAPDE+IikuS3EoYykuQygibEo8MSwyPiIpKX0sCnpWOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscz1uZXcgQXJyYXkoYS5sZW5ndGgpCnMuZml4ZWQkbGVuZ3RoPUFycmF5CmZvcih0PTA7
-dDxhLmxlbmd0aDsrK3QpdGhpcy5ZKHMsdCxILmQoYVt0XSkpCnJldHVybiBzLmpvaW4oYil9LApOMDpm
-dW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIKZC5hKGIpCkgudDYoYSkuS3EoZCkuQygiMSgxLDIpIiku
-YShjKQp0PWEubGVuZ3RoCmZvcihzPWIscj0wO3I8dDsrK3Ipe3M9Yy4kMihzLGFbcl0pCmlmKGEubGVu
-Z3RoIT09dCl0aHJvdyBILmIoUC5hNChhKSl9cmV0dXJuIHN9LApIdDpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscixxLHAsbz1ILnQ2KGEpCm8uQygiYTIoMSkiKS5hKGIpCm8uQygiMSgpIikuYShudWxsKQp0PWEu
-bGVuZ3RoCmZvcihzPW51bGwscj0hMSxxPTA7cTx0OysrcSl7cD1hW3FdCmlmKEgub1QoYi4kMShwKSkp
-e2lmKHIpdGhyb3cgSC5iKEguZFUoKSkKcz1wCnI9ITB9aWYodCE9PWEubGVuZ3RoKXRocm93IEguYihQ
-LmE0KGEpKX1pZihyKXJldHVybiBzCnRocm93IEguYihILldwKCkpfSwKRTpmdW5jdGlvbihhLGIpe2lm
-KGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguayhhLGIpCnJldHVybiBhW2JdfSwKRDY6ZnVuY3Rpb24o
-YSxiLGMpe2lmKGI8MHx8Yj5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShiLDAsYS5sZW5ndGgsInN0YXJ0
-IixudWxsKSkKaWYoYzxifHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsYixhLmxlbmd0aCwiZW5k
-IixudWxsKSkKaWYoYj09PWMpcmV0dXJuIEguVk0oW10sSC50NihhKSkKcmV0dXJuIEguVk0oYS5zbGlj
-ZShiLGMpLEgudDYoYSkpfSwKZ3RIOmZ1bmN0aW9uKGEpe2lmKGEubGVuZ3RoPjApcmV0dXJuIGFbMF0K
-dGhyb3cgSC5iKEguV3AoKSl9LApnclo6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKaWYodD4wKXJl
-dHVybiBhW3QtMV0KdGhyb3cgSC5iKEguV3AoKSl9LApZVzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0
-LHMscj1ILnQ2KGEpCnIuQygiY1g8MT4iKS5hKGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnZoKFAu
-TDQoInNldFJhbmdlIikpClAuakIoYixjLGEubGVuZ3RoKQp0PWMtYgppZih0PT09MClyZXR1cm4KUC5r
-MShlLCJza2lwQ291bnQiKQpyLkMoInpNPDE+IikuYShkKQpyPUouVTYoZCkKaWYoZSt0PnIuZ0EoZCkp
-dGhyb3cgSC5iKEguYXIoKSkKaWYoZTxiKWZvcihzPXQtMTtzPj0wOy0tcylhW2Irc109ci5xKGQsZStz
-KQplbHNlIGZvcihzPTA7czx0OysrcylhW2Irc109ci5xKGQsZStzKX0sCnZnOmZ1bmN0aW9uKGEsYixj
-LGQpe3JldHVybiB0aGlzLllXKGEsYixjLGQsMCl9LApWcjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC50
-NihhKS5DKCJhMigxKSIpLmEoYikKdD1hLmxlbmd0aApmb3Iocz0wO3M8dDsrK3Mpe2lmKEgub1QoYi4k
-MShhW3NdKSkpcmV0dXJuITAKaWYoYS5sZW5ndGghPT10KXRocm93IEguYihQLmE0KGEpKX1yZXR1cm4h
-MX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9MDt0PGEubGVuZ3RoOysrdClpZihKLlJNKGFb
-dF0sYikpcmV0dXJuITAKcmV0dXJuITF9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RoPT09
-MH0sCmdvcjpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGghPT0wfSwKWjpmdW5jdGlvbihhKXtyZXR1
-cm4gUC5XRShhLCJbIiwiXSIpfSwKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSi5tMShhLGEubGVu
-Z3RoLEgudDYoYSkuQygibTE8MT4iKSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEoYSl9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApzQTpmdW5jdGlvbihhLGIpe2lmKCEhYS5maXhl
-ZCRsZW5ndGgpSC52aChQLkw0KCJzZXQgbGVuZ3RoIikpCmlmKGI8MCl0aHJvdyBILmIoUC5URShiLDAs
-bnVsbCwibmV3TGVuZ3RoIixudWxsKSkKYS5sZW5ndGg9Yn0sCnE6ZnVuY3Rpb24oYSxiKXtILldZKGIp
-CmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0dXJuIGFbYl19LApZOmZ1
-bmN0aW9uKGEsYixjKXtILnQ2KGEpLmMuYShjKQppZighIWEuaW1tdXRhYmxlJGxpc3QpSC52aChQLkw0
-KCJpbmRleGVkIHNldCIpKQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCmFb
-Yl09Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkouUG8ucHJvdG90eXBlPXt9CkoubTEucHJvdG90
-eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHM9dGhp
-cyxyPXMuYSxxPXIubGVuZ3RoCmlmKHMuYiE9PXEpdGhyb3cgSC5iKEgubGsocikpCnQ9cy5jCmlmKHQ+
-PXEpe3Muc0gobnVsbCkKcmV0dXJuITF9cy5zSChyW3RdKTsrK3MuYwpyZXR1cm4hMH0sCnNIOmZ1bmN0
-aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5jLmEoYSl9LAokaUFuOjF9CkoucUkucHJvdG90eXBlPXsKeXU6
-ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT49LTIxNDc0ODM2NDgmJmE8PTIxNDc0ODM2NDcpcmV0dXJuIGF8
-MAppZihpc0Zpbml0ZShhKSl7dD1hPDA/TWF0aC5jZWlsKGEpOk1hdGguZmxvb3IoYSkKcmV0dXJuIHQr
-MH10aHJvdyBILmIoUC5MNCgiIithKyIudG9JbnQoKSIpKX0sCnpROmZ1bmN0aW9uKGEpe2lmKGE+MCl7
-aWYoYSE9PTEvMClyZXR1cm4gTWF0aC5yb3VuZChhKX1lbHNlIGlmKGE+LTEvMClyZXR1cm4gMC1NYXRo
-LnJvdW5kKDAtYSkKdGhyb3cgSC5iKFAuTDQoIiIrYSsiLnJvdW5kKCkiKSl9LApXWjpmdW5jdGlvbihh
-LGIpe3ZhciB0LHMscixxCmlmKGI8Mnx8Yj4zNil0aHJvdyBILmIoUC5URShiLDIsMzYsInJhZGl4Iixu
-dWxsKSkKdD1hLnRvU3RyaW5nKGIpCmlmKEMueEIubSh0LHQubGVuZ3RoLTEpIT09NDEpcmV0dXJuIHQK
-cz0vXihbXGRhLXpdKykoPzpcLihbXGRhLXpdKykpP1woZVwrKFxkKylcKSQvLmV4ZWModCkKaWYocz09
-bnVsbClILnZoKFAuTDQoIlVuZXhwZWN0ZWQgdG9TdHJpbmcgcmVzdWx0OiAiK3QpKQpyPXMubGVuZ3Ro
-CmlmKDE+PXIpcmV0dXJuIEguayhzLDEpCnQ9c1sxXQppZigzPj1yKXJldHVybiBILmsocywzKQpxPStz
-WzNdCnI9c1syXQppZihyIT1udWxsKXt0Kz1yCnEtPXIubGVuZ3RofXJldHVybiB0K0MueEIuSXgoIjAi
-LHEpfSwKWjpmdW5jdGlvbihhKXtpZihhPT09MCYmMS9hPDApcmV0dXJuIi0wLjAiCmVsc2UgcmV0dXJu
-IiIrYX0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPWF8MAppZihhPT09cClyZXR1cm4gNTM2
-ODcwOTExJnAKdD1NYXRoLmFicyhhKQpzPU1hdGgubG9nKHQpLzAuNjkzMTQ3MTgwNTU5OTQ1M3wwCnI9
-TWF0aC5wb3coMixzKQpxPXQ8MT90L3I6ci90CnJldHVybiA1MzY4NzA5MTEmKChxKjkwMDcxOTkyNTQ3
-NDA5OTJ8MCkrKHEqMzU0MjI0MzE4MTE3NjUyMXwwKSkqNTk5MTk3K3MqMTI1OX0sCnpZOmZ1bmN0aW9u
-KGEsYil7dmFyIHQ9YSViCmlmKHQ9PT0wKXJldHVybiAwCmlmKHQ+MClyZXR1cm4gdAppZihiPDApcmV0
-dXJuIHQtYgplbHNlIHJldHVybiB0K2J9LAp3RzpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE+MCl0PXRo
-aXMucDMoYSxiKQplbHNle3Q9Yj4zMT8zMTpiCnQ9YT4+dD4+PjB9cmV0dXJuIHR9LApiZjpmdW5jdGlv
-bihhLGIpe2lmKGI8MCl0aHJvdyBILmIoSC5JKGIpKQpyZXR1cm4gdGhpcy5wMyhhLGIpfSwKcDM6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gYj4zMT8wOmE+Pj5ifSwKJGlDUDoxLAokaWxmOjF9CkoudXIucHJvdG90
-eXBlPXskaUlmOjF9CkouVkEucHJvdG90eXBlPXt9CkouRHIucHJvdG90eXBlPXsKbTpmdW5jdGlvbihh
-LGIpe2lmKGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQppZihiPj1hLmxlbmd0aClILnZoKEguSFkoYSxi
-KSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sClc6ZnVuY3Rpb24oYSxiKXtpZihiPj1hLmxlbmd0aCl0
-aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKZGQ6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gbmV3IEguTkYoYixhLDApfSwKaDpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiIT0ic3Ry
-aW5nIil0aHJvdyBILmIoUC5MMyhiLG51bGwsbnVsbCkpCnJldHVybiBhK2J9LApUYzpmdW5jdGlvbihh
-LGIpe3ZhciB0PWIubGVuZ3RoLHM9YS5sZW5ndGgKaWYodD5zKXJldHVybiExCnJldHVybiBiPT09dGhp
-cy5HKGEscy10KX0sCmk3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMKYz1QLmpCKGIsYyxhLmxlbmd0
-aCkKdD1hLnN1YnN0cmluZygwLGIpCnM9YS5zdWJzdHJpbmcoYykKcmV0dXJuIHQrZCtzfSwKUWk6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0CmlmKCFILm9rKGMpKUgudmgoSC5JKGMpKQppZih0eXBlb2YgYyE9PSJu
-dW1iZXIiKXJldHVybiBjLkooKQppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEu
-bGVuZ3RoLG51bGwsbnVsbCkpCnQ9YytiLmxlbmd0aAppZih0PmEubGVuZ3RoKXJldHVybiExCnJldHVy
-biBiPT09YS5zdWJzdHJpbmcoYyx0KX0sCm46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5RaShhLGIs
-MCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYoIUgub2soYikpSC52aChILkkoYikpCmlmKGM9PW51bGwp
-Yz1hLmxlbmd0aAppZih0eXBlb2YgYiE9PSJudW1iZXIiKXJldHVybiBiLkooKQppZihiPDApdGhyb3cg
-SC5iKFAuTzcoYixudWxsKSkKaWYoYj5jKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlmKGM+YS5sZW5n
-dGgpdGhyb3cgSC5iKFAuTzcoYyxudWxsKSkKcmV0dXJuIGEuc3Vic3RyaW5nKGIsYyl9LApHOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIHRoaXMuTmooYSxiLG51bGwpfSwKaGM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-dG9Mb3dlckNhc2UoKX0sCmJTOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPWEudHJpbSgpLHA9cS5sZW5n
-dGgKaWYocD09PTApcmV0dXJuIHEKaWYodGhpcy5XKHEsMCk9PT0xMzMpe3Q9Si5tbShxLDEpCmlmKHQ9
-PT1wKXJldHVybiIifWVsc2UgdD0wCnM9cC0xCnI9dGhpcy5tKHEscyk9PT0xMzM/Si5jMShxLHMpOnAK
-aWYodD09PTAmJnI9PT1wKXJldHVybiBxCnJldHVybiBxLnN1YnN0cmluZyh0LHIpfSwKSXg6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzCmlmKDA+PWIpcmV0dXJuIiIKaWYoYj09PTF8fGEubGVuZ3RoPT09MClyZXR1
-cm4gYQppZihiIT09Yj4+PjApdGhyb3cgSC5iKEMuRXEpCmZvcih0PWEscz0iIjshMDspe2lmKChiJjEp
-PT09MSlzPXQrcwpiPWI+Pj4xCmlmKGI9PT0wKWJyZWFrCnQrPXR9cmV0dXJuIHN9LApYVTpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQKaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0
-aCxudWxsLG51bGwpKQp0PWEuaW5kZXhPZihiLGMpCnJldHVybiB0fSwKT1k6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gdGhpcy5YVShhLGIsMCl9LApQazpmdW5jdGlvbihhLGIsYyl7dmFyIHQscwppZihjPT1udWxs
-KWM9YS5sZW5ndGgKZWxzZSBpZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVu
-Z3RoLG51bGwsbnVsbCkpCnQ9Yi5sZW5ndGgKcz1hLmxlbmd0aAppZihjK3Q+cyljPXMtdApyZXR1cm4g
-YS5sYXN0SW5kZXhPZihiLGMpfSwKY246ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5QayhhLGIsbnVs
-bCl9LApJczpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9YS5sZW5ndGgKaWYoYz50KXRocm93IEguYihQLlRF
-KGMsMCx0LG51bGwsbnVsbCkpCnJldHVybiBILm0yKGEsYixjKX0sCnRnOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIHRoaXMuSXMoYSxiLDApfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gYX0sCmdpTzpmdW5jdGlvbihh
-KXt2YXIgdCxzLHIKZm9yKHQ9YS5sZW5ndGgscz0wLHI9MDtyPHQ7KytyKXtzPTUzNjg3MDkxMSZzK2Eu
-Y2hhckNvZGVBdChyKQpzPTUzNjg3MDkxMSZzKygoNTI0Mjg3JnMpPDwxMCkKc149cz4+Nn1zPTUzNjg3
-MDkxMSZzKygoNjcxMDg4NjMmcyk8PDMpCnNePXM+PjExCnJldHVybiA1MzY4NzA5MTEmcysoKDE2Mzgz
-JnMpPDwxNSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7
-SC5XWShiKQppZihiPj1hLmxlbmd0aHx8ITEpdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0dXJuIGFbYl19
-LAokaXZYOjEsCiRpcVU6MX0KSC5xai5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gQy54Qi5tKHRoaXMuYSxILldZKGIpKX19
-CkguYlEucHJvdG90eXBlPXt9CkguYUwucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMKcmV0dXJuIG5ldyBILmE3KHQsdC5nQSh0KSxILkxoKHQpLkMoImE3PGFMLkU+IikpfSwKZ2wwOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09MH0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQs
-cyxyLHE9dGhpcyxwPXEuZ0EocSkKaWYoYi5sZW5ndGghPT0wKXtpZihwPT09MClyZXR1cm4iIgp0PUgu
-ZChxLkUoMCwwKSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpCmZvcihzPXQscj0xO3I8
-cDsrK3Ipe3M9cytiK0guZChxLkUoMCxyKSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkp
-fXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfWVsc2V7Zm9yKHI9MCxzPSIiO3I8cDsrK3Ipe3Mr
-PUguZChxLkUoMCxyKSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNo
-YXJDb2RlQXQoMCk9PTA/czpzfX0sCmV2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxo
-KHRoaXMpLkMoImEyKGFMLkUpIikuYShiKSl9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0
-aGlzKQpyZXR1cm4gbmV3IEgubEoodGhpcyx0LktxKGMpLkMoIjEoYUwuRSkiKS5hKGIpLHQuQygiQDxh
-TC5FPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9LAp0dDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcyxy
-PUguVk0oW10sSC5MaChzKS5DKCJqZDxhTC5FPiIpKQpDLk5tLnNBKHIscy5nQShzKSkKZm9yKHQ9MDt0
-PHMuZ0Eocyk7Kyt0KUMuTm0uWShyLHQscy5FKDAsdCkpCnJldHVybiByfSwKYnI6ZnVuY3Rpb24oYSl7
-cmV0dXJuIHRoaXMudHQoYSwhMCl9fQpILm5ILnByb3RvdHlwZT17CmdVRDpmdW5jdGlvbigpe3ZhciB0
-PUouSCh0aGlzLmEpLHM9dGhpcy5jCmlmKHM9PW51bGx8fHM+dClyZXR1cm4gdApyZXR1cm4gc30sCmdB
-czpmdW5jdGlvbigpe3ZhciB0PUouSCh0aGlzLmEpLHM9dGhpcy5iCmlmKHM+dClyZXR1cm4gdApyZXR1
-cm4gc30sCmdBOmZ1bmN0aW9uKGEpe3ZhciB0LHM9Si5IKHRoaXMuYSkscj10aGlzLmIKaWYocj49cyly
-ZXR1cm4gMAp0PXRoaXMuYwppZih0PT1udWxsfHx0Pj1zKXJldHVybiBzLXIKaWYodHlwZW9mIHQhPT0i
-bnVtYmVyIilyZXR1cm4gdC5ITigpCnJldHVybiB0LXJ9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10
-aGlzLHI9cy5nQXMoKStiCmlmKGI+PTApe3Q9cy5nVUQoKQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJl
-dHVybiBILnBZKHQpCnQ9cj49dH1lbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIoUC50KGIscywiaW5kZXgi
-LG51bGwsbnVsbCkpCnJldHVybiBKLkdBKHMuYSxyKX19CkguYTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYo
-cikscD1xLmdBKHIpCmlmKHMuYiE9PXApdGhyb3cgSC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Mu
-c0kobnVsbCkKcmV0dXJuITF9cy5zSShxLkUocix0KSk7KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlv
-bihhKXt0aGlzLmQ9dGhpcy4kdGkuYy5hKGEpfSwKJGlBbjoxfQpILmkxLnByb3RvdHlwZT17Cmdrejpm
-dW5jdGlvbihhKXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhp
-cy5iLHQuQygiQDwxPiIpLktxKHQuUVsxXSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBKLkgodGhpcy5hKX19CkgueHkucHJvdG90eXBlPXskaWJROjF9CkguTUgucHJvdG90eXBlPXsK
-RjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmIKaWYocy5GKCkpe3Quc0kodC5jLiQxKHMuZ2woKSkp
-CnJldHVybiEwfXQuc0kobnVsbCkKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9
-LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuUVsxXS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9
-ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IKHRoaXMuYSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IHRoaXMuYi4kMShKLkdBKHRoaXMuYSxiKSl9fQpILlU1LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihh
-KXtyZXR1cm4gbmV3IEgudkcoSi5JVCh0aGlzLmEpLHRoaXMuYix0aGlzLiR0aS5DKCJ2RzwxPiIpKX19
-CkgudkcucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0LHMKZm9yKHQ9dGhpcy5hLHM9dGhpcy5i
-O3QuRigpOylpZihILm9UKHMuJDEodC5nbCgpKSkpcmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlv
-bigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguU1UucHJvdG90eXBlPXt9CkguUmUucHJvdG90eXBlPXsK
-WTpmdW5jdGlvbihhLGIsYyl7SC5MaCh0aGlzKS5DKCJSZS5FIikuYShjKQp0aHJvdyBILmIoUC5MNCgi
-Q2Fubm90IG1vZGlmeSBhbiB1bm1vZGlmaWFibGUgbGlzdCIpKX19CkgudzIucHJvdG90eXBlPXt9Ckgu
-d3YucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuX2hhc2hDb2RlCmlmKHQhPW51
-bGwpcmV0dXJuIHQKdD01MzY4NzA5MTEmNjY0NTk3KkouaGYodGhpcy5hKQp0aGlzLl9oYXNoQ29kZT10
-CnJldHVybiB0fSwKWjpmdW5jdGlvbihhKXtyZXR1cm4nU3ltYm9sKCInK0guZCh0aGlzLmEpKyciKSd9
-LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBI
-Lnd2JiZ0aGlzLmE9PWIuYX0sCiRpR0Q6MX0KSC5QRC5wcm90b3R5cGU9e30KSC5XVS5wcm90b3R5cGU9
-ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKWjpmdW5jdGlvbihhKXty
-ZXR1cm4gUC5uTyh0aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdC5jLmEo
-YikKdC5RWzFdLmEoYykKcmV0dXJuIEguZGMoKX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5x
-NChhLEguTGgodGhpcykuQygiTjM8MSwyPiIpKX0sCnE0OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwpy
-ZXR1cm4gUC5sMChmdW5jdGlvbigpe3ZhciBzPWEKdmFyIHI9MCxxPTEscCxvLG4sbQpyZXR1cm4gZnVu
-Y3Rpb24gJGFzeW5jJGdQdShjLGQpe2lmKGM9PT0xKXtwPWQKcj1xfXdoaWxlKHRydWUpc3dpdGNoKHIp
-e2Nhc2UgMDpvPXQuZ1YoKSxvPW8uZ2t6KG8pLG49SC5MaCh0KSxuPW4uQygiQDwxPiIpLktxKG4uUVsx
-XSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighby5GKCkpe3I9MwpicmVha31tPW8uZ2woKQpyPTQKcmV0
-dXJuIG5ldyBQLk4zKG0sdC5xKDAsbSksbikKY2FzZSA0OnI9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAu
-VGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0ocCl9fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsK
-Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0i
-c3RyaW5nIilyZXR1cm4hMQppZigiX19wcm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5o
-YXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVs
-bApyZXR1cm4gdGhpcy5EKGIpfSwKRDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0guYyhhKV19LApL
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD1ILkxoKHRoaXMpCnAuQygifigxLDIpIikuYShiKQp0
-PXRoaXMuYwpmb3Iocz10Lmxlbmd0aCxwPXAuUVsxXSxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxw
-LmEodGhpcy5EKHEpKSl9fSwKZ1Y6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRo
-aXMpLkMoIlhSPDE+IikpfX0KSC5YUi5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
-cy5hLmMKcmV0dXJuIG5ldyBKLm0xKHQsdC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX0sCmdBOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5j
-dGlvbigpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdH0sCmduZDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9
-dGhpcwppZihwLmM9PT0xKXJldHVybiBDLmhVCnQ9cC5kCnM9dC5sZW5ndGgtcC5lLmxlbmd0aC1wLmYK
-aWYocz09PTApcmV0dXJuIEMuaFUKcj1bXQpmb3IocT0wO3E8czsrK3Epe2lmKHE+PXQubGVuZ3RoKXJl
-dHVybiBILmsodCxxKQpyLnB1c2godFtxXSl9cmV0dXJuIEoudW4ocil9LApnVm06ZnVuY3Rpb24oKXt2
-YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwppZihsLmMhPT0wKXJldHVybiBDLkR4CnQ9bC5lCnM9dC5s
-ZW5ndGgKcj1sLmQKcT1yLmxlbmd0aC1zLWwuZgppZihzPT09MClyZXR1cm4gQy5EeApwPW5ldyBILk41
-KHUuZW8pCmZvcihvPTA7bzxzOysrbyl7aWYobz49dC5sZW5ndGgpcmV0dXJuIEguayh0LG8pCm49dFtv
-XQptPXErbwppZihtPDB8fG0+PXIubGVuZ3RoKXJldHVybiBILmsocixtKQpwLlkoMCxuZXcgSC53dihu
-KSxyW21dKX1yZXR1cm4gbmV3IEguUEQocCx1LmdGKX0sCiRpdlE6MX0KSC5Dai5wcm90b3R5cGU9ewok
-MjpmdW5jdGlvbihhLGIpe3ZhciB0CkguYyhhKQp0PXRoaXMuYQp0LmI9dC5iKyIkIitILmQoYSkKQy5O
-bS5pKHRoaXMuYixhKQpDLk5tLmkodGhpcy5jLGIpOysrdC5hfSwKJFM6MTR9CkguZjkucHJvdG90eXBl
-PXsKcVM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1uZXcgUmVnRXhwKHIuYSkuZXhlYyhhKQpp
-ZihxPT1udWxsKXJldHVybiBudWxsCnQ9T2JqZWN0LmNyZWF0ZShudWxsKQpzPXIuYgppZihzIT09LTEp
-dC5hcmd1bWVudHM9cVtzKzFdCnM9ci5jCmlmKHMhPT0tMSl0LmFyZ3VtZW50c0V4cHI9cVtzKzFdCnM9
-ci5kCmlmKHMhPT0tMSl0LmV4cHI9cVtzKzFdCnM9ci5lCmlmKHMhPT0tMSl0Lm1ldGhvZD1xW3MrMV0K
-cz1yLmYKaWYocyE9PS0xKXQucmVjZWl2ZXI9cVtzKzFdCnJldHVybiB0fX0KSC5XMC5wcm90b3R5cGU9
-ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RF
-cnJvcjogIitILmQodGhpcy5hKQpyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91
-bmQ6ICciK3QrIicgb24gbnVsbCJ9fQpILmF6LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQs
-cz10aGlzLHI9Ik5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixxPXMuYgppZihx
-PT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILmQocy5hKQp0PXMuYwppZih0PT1udWxs
-KXJldHVybiByK3ErIicgKCIrSC5kKHMuYSkrIikiCnJldHVybiByK3ErIicgb24gJyIrdCsiJyAoIitI
-LmQocy5hKSsiKSJ9fQpILnZWLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJl
-dHVybiB0Lmxlbmd0aD09PTA/IkVycm9yIjoiRXJyb3I6ICIrdH19CkguYnEucHJvdG90eXBlPXt9Ckgu
-QW0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7aWYodS5XLmIoYSkpaWYoYS4kdGhyb3duSnNFcnJv
-cj09bnVsbClhLiR0aHJvd25Kc0Vycm9yPXRoaXMuYQpyZXR1cm4gYX0sCiRTOjJ9CkguWE8ucHJvdG90
-eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuYgppZihzIT1udWxsKXJldHVybiBzCnM9dGhp
-cy5hCnQ9cyE9PW51bGwmJnR5cGVvZiBzPT09Im9iamVjdCI/cy5zdGFjazpudWxsCnJldHVybiB0aGlz
-LmI9dD09bnVsbD8iIjp0fSwKJGlHejoxfQpILlRwLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFy
-IHQ9dGhpcy5jb25zdHJ1Y3RvcixzPXQ9PW51bGw/bnVsbDp0Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIr
-SC5OUShzPT1udWxsPyJ1bmtub3duIjpzKSsiJyJ9LAokaUVIOjEsCmdRbDpmdW5jdGlvbigpe3JldHVy
-biB0aGlzfSwKJEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90
-b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuJHN0YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0
-dXJuIkNsb3N1cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5R
-KHQpKyInIn19CkguankucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKGI9
-PW51bGwpcmV0dXJuITEKaWYodD09PWIpcmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5qeSkpcmV0
-dXJuITEKcmV0dXJuIHQuYT09PWIuYSYmdC5iPT09Yi5iJiZ0LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24o
-YSl7dmFyIHQscz10aGlzLmMKaWYocz09bnVsbCl0PUguZVEodGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMh
-PT0ib2JqZWN0Ij9KLmhmKHMpOkguZVEocykKcmV0dXJuKHReSC5lUSh0aGlzLmIpKT4+PjB9LApaOmZ1
-bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXQ9dGhpcy5hCnJldHVybiJDbG9zdXJlICci
-K0guZCh0aGlzLmQpKyInIG9mICIrKCJJbnN0YW5jZSBvZiAnIitILmQoSC5saCh0KSkrIiciKX19Ckgu
-RXEucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK0guZCh0aGlz
-LmEpfX0KSC5rWS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRpb24gZmFpbGVk
-OiAiK1AuaCh0aGlzLmEpfX0KSC5ONS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy5hfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmE9PT0wfSwKZ1Y6ZnVuY3Rpb24oKXtyZXR1
-cm4gbmV3IEguaTUodGhpcyxILkxoKHRoaXMpLkMoImk1PDE+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7dmFy
-IHQscwppZih0eXBlb2YgYT09InN0cmluZyIpe3Q9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0
-dXJuIHRoaXMuWHUodCxhKX1lbHNle3M9dGhpcy5DWChhKQpyZXR1cm4gc319LApDWDpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLmQKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5GaCh0aGlzLkJ0KHQs
-Si5oZihhKSYweDNmZmZmZmYpLGEpPj0wfSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhp
-cyxvPW51bGwKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PXAuYgppZih0PT1udWxsKXJldHVybiBvCnM9
-cC5qMih0LGIpCnI9cz09bnVsbD9vOnMuYgpyZXR1cm4gcn1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVy
-IiYmKGImMHgzZmZmZmZmKT09PWIpe3E9cC5jCmlmKHE9PW51bGwpcmV0dXJuIG8Kcz1wLmoyKHEsYikK
-cj1zPT1udWxsP286cy5iCnJldHVybiByfWVsc2UgcmV0dXJuIHAuYWEoYil9LAphYTpmdW5jdGlvbihh
-KXt2YXIgdCxzLHI9dGhpcy5kCmlmKHI9PW51bGwpcmV0dXJuIG51bGwKdD10aGlzLkJ0KHIsSi5oZihh
-KSYweDNmZmZmZmYpCnM9dGhpcy5GaCh0LGEpCmlmKHM8MClyZXR1cm4gbnVsbApyZXR1cm4gdFtzXS5i
-fSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxtPUguTGgobikKbS5jLmEo
-YikKbS5RWzFdLmEoYykKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PW4uYgpuLkVIKHQ9PW51bGw/bi5i
-PW4ueksoKTp0LGIsYyl9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1i
-KXtzPW4uYwpuLkVIKHM9PW51bGw/bi5jPW4ueksoKTpzLGIsYyl9ZWxzZXtyPW4uZAppZihyPT1udWxs
-KXI9bi5kPW4ueksoKQpxPUouaGYoYikmMHgzZmZmZmZmCnA9bi5CdChyLHEpCmlmKHA9PW51bGwpbi5F
-SShyLHEsW24uSG4oYixjKV0pCmVsc2V7bz1uLkZoKHAsYikKaWYobz49MClwW29dLmI9YwplbHNlIHAu
-cHVzaChuLkhuKGIsYykpfX19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKSC5MaChyKS5D
-KCJ+KDEsMikiKS5hKGIpCnQ9ci5lCnM9ci5yCmZvcig7dCE9bnVsbDspe2IuJDIodC5hLHQuYikKaWYo
-cyE9PXIucil0aHJvdyBILmIoUC5hNChyKSkKdD10LmN9fSwKRUg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHM9dGhpcyxyPUguTGgocykKci5jLmEoYikKci5RWzFdLmEoYykKdD1zLmoyKGEsYikKaWYodD09bnVs
-bClzLkVJKGEsYixzLkhuKGIsYykpCmVsc2UgdC5iPWN9LAprczpmdW5jdGlvbigpe3RoaXMucj10aGlz
-LnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9SC5MaChzKSxxPW5l
-dyBILmRiKHIuYy5hKGEpLHIuUVsxXS5hKGIpKQppZihzLmU9PW51bGwpcy5lPXMuZj1xCmVsc2V7dD1z
-LmYKcS5kPXQKcy5mPXQuYz1xfSsrcy5hCnMua3MoKQpyZXR1cm4gcX0sCkZoOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscwppZihhPT1udWxsKXJldHVybi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEou
-Uk0oYVtzXS5hLGIpKXJldHVybiBzCnJldHVybi0xfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0
-aGlzKX0sCmoyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19LApCdDpmdW5jdGlvbihhLGIpe3JldHVy
-biBhW2JdfSwKRUk6ZnVuY3Rpb24oYSxiLGMpe2FbYl09Y30sCnJuOmZ1bmN0aW9uKGEsYil7ZGVsZXRl
-IGFbYl19LApYdTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmoyKGEsYikhPW51bGx9LAp6SzpmdW5j
-dGlvbigpe3ZhciB0PSI8bm9uLWlkZW50aWZpZXIta2V5PiIscz1PYmplY3QuY3JlYXRlKG51bGwpCnRo
-aXMuRUkocyx0LHMpCnRoaXMucm4ocyx0KQpyZXR1cm4gc30sCiRpRm86MX0KSC5kYi5wcm90b3R5cGU9
-e30KSC5pNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmF9LApnbDA6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hPT09MH0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEs
-cz1uZXcgSC5ONih0LHQucix0aGlzLiR0aS5DKCJONjwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKdGc6
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KSC5ONi5wcm90b3R5cGU9ewpnbDpmdW5j
-dGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYQppZih0LmIh
-PT1zLnIpdGhyb3cgSC5iKFAuYTQocykpCmVsc2V7cz10LmMKaWYocz09bnVsbCl7dC5zcVkobnVsbCkK
-cmV0dXJuITF9ZWxzZXt0LnNxWShzLmEpCnQuYz10LmMuYwpyZXR1cm4hMH19fSwKc3FZOmZ1bmN0aW9u
-KGEpe3RoaXMuZD10aGlzLiR0aS5jLmEoYSl9LAokaUFuOjF9Ckguci5wcm90b3R5cGU9ewokMTpmdW5j
-dGlvbihhKXtyZXR1cm4gdGhpcy5hKGEpfSwKJFM6Mn0KSC5kQy5wcm90b3R5cGU9ewokMjpmdW5jdGlv
-bihhLGIpe3JldHVybiB0aGlzLmEoYSxiKX0sCiRTOjI2fQpILndOLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3JldHVybiB0aGlzLmEoSC5jKGEpKX0sCiRTOjMwfQpILlZSLnByb3RvdHlwZT17Clo6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIlJlZ0V4cC8iK3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1bmN0
-aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYwppZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0LmM9
-SC52NCh0LmEscy5tdWx0aWxpbmUsIXMuaWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITApfSwK
-ZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24oYSxi
-KXt2YXIgdCxzPXRoaXMuZ0hjKCkKcy5sYXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxsKXJl
-dHVybiBudWxsCnJldHVybiBuZXcgSC5FSyh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3RvdHlw
-ZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILldZKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3RoKXJl
-dHVybiBILmsodCxiKQpyZXR1cm4gdFtiXX0sCiRpT2Q6MSwKJGlpYjoxfQpILktXLnByb3RvdHlwZT17
-CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguUGIodGhpcy5hLHRoaXMuYix0aGlzLmMpfX0KSC5Q
-Yi5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFy
-IHQscyxyLHEscD10aGlzLG89cC5iCmlmKG89PW51bGwpcmV0dXJuITEKdD1wLmMKaWYodDw9by5sZW5n
-dGgpe3M9cC5hCnI9cy5VWihvLHQpCmlmKHIhPW51bGwpe3AuZD1yCm89ci5iCnQ9by5pbmRleApxPXQr
-b1swXS5sZW5ndGgKaWYodD09PXEpe2lmKHMuYi51bmljb2RlKXtvPXAuYwp0PW8rMQpzPXAuYgppZih0
-PHMubGVuZ3RoKXtvPUouclkocykubShzLG8pCmlmKG8+PTU1Mjk2JiZvPD01NjMxOSl7bz1DLnhCLm0o
-cyx0KQpvPW8+PTU2MzIwJiZvPD01NzM0M31lbHNlIG89ITF9ZWxzZSBvPSExfWVsc2Ugbz0hMQpxPShv
-P3ErMTpxKSsxfXAuYz1xCnJldHVybiEwfX1wLmI9cC5kPW51bGwKcmV0dXJuITF9LAokaUFuOjF9Ckgu
-dFEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYiE9PTApSC52aChQLk83KGIs
-bnVsbCkpCnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkguTkYucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9u
-KGEpe3JldHVybiBuZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17
-CkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5hLG09
-bi5sZW5ndGgKaWYocStvPm0pe3IuZD1udWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYodDww
-KXtyLmM9bSsxCnIuZD1udWxsCnJldHVybiExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1zPT09
-ci5jP3MrMTpzCnJldHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjoxfQpI
-LnBGLnByb3RvdHlwZT17JGlwRjoxLCRpZXE6MX0KSC5MWi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihh
-KXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIp
-e0guV1koYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7
-SC5kaihjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0K
-SC5QZy5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXtILldZKGMpCkgub2QoYixhLGEubGVuZ3Ro
-KQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpILnhqLnByb3RvdHlwZT17CnE6ZnVuY3Rp
-b24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZEUucHJvdG90
-eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2Jd
-fX0KSC5aQS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0
-aCkKcmV0dXJuIGFbYl19fQpILndmLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgu
-b2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguUHEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihh
-LGIpe0guV1koYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5lRS5wcm90b3R5cGU9
-ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpI
-Lm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlY2LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9u
-KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVu
-Z3RoKQpyZXR1cm4gYVtiXX0sCiRpVjY6MSwKJGluNjoxfQpILlJHLnByb3RvdHlwZT17fQpILlZQLnBy
-b3RvdHlwZT17fQpILldCLnByb3RvdHlwZT17fQpILlpHLnByb3RvdHlwZT17fQpILkpjLnByb3RvdHlw
-ZT17CkM6ZnVuY3Rpb24oYSl7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsdGhpcyxhKX0sCktxOmZ1
-bmN0aW9uKGEpe3JldHVybiBILnY1KHYudHlwZVVuaXZlcnNlLHRoaXMsYSl9fQpILkVULnByb3RvdHlw
-ZT17fQpILnU5LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX19CkgueC5wcm90
-b3R5cGU9e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz10LmEK
-dC5hPW51bGwKcy4kMCgpfSwKJFM6MTN9ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHQscwp0aGlzLmEuYT11Lk0uYShhKQp0PXRoaXMuYgpzPXRoaXMuYwp0LmZpcnN0Q2hpbGQ/dC5yZW1v
-dmVDaGlsZChzKTp0LmFwcGVuZENoaWxkKHMpfSwKJFM6NDd9ClAuVnMucHJvdG90eXBlPXsKJDA6ZnVu
-Y3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuRnQucHJvdG90eXBlPXsK
-JDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuVzMucHJvdG90
-eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVvdXQhPW51bGwpc2VsZi5zZXRUaW1l
-b3V0KEgudFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRocm93IEguYihQLkw0KCJgc2V0VGlt
-ZW91dCgpYCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMu
-Yi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6M30KUC5paC5wcm90b3R5cGU9ewphTTpmdW5jdGlvbihh
-LGIpe3ZhciB0LHMscj10aGlzLiR0aQpyLkMoIjEvIikuYShiKQp0PSF0aGlzLmJ8fHIuQygiYjg8MT4i
-KS5iKGIpCnM9dGhpcy5hCmlmKHQpcy5YZihiKQplbHNlIHMuWDIoci5jLmEoYikpfSwKdzA6ZnVuY3Rp
-b24oYSxiKXt2YXIgdAppZihiPT1udWxsKWI9UC52MChhKQp0PXRoaXMuYQppZih0aGlzLmIpdC5aTChh
-LGIpCmVsc2UgdC5OayhhLGIpfX0KUC5XTS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5hLiQyKDAsYSl9LAokUzo1MX0KUC5TWC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Ro
-aXMuYS4kMigxLG5ldyBILmJxKGEsdS5sLmEoYikpKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjQ1fQpQLkdz
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hKEguV1koYSksYil9LAokUzo0Nn0KUC5G
-eS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJJdGVyYXRpb25NYXJrZXIoIit0aGlzLmIr
-IiwgIitILmQodGhpcy5hKSsiKSJ9fQpQLkdWLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHQ9
-dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJuIHRoaXMuYgpyZXR1cm4gdGhpcy4kdGkuYy5hKHQuZ2woKSl9
-LApGOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzCmZvcig7ITA7KXt0PXAuYwppZih0IT1udWxs
-KWlmKHQuRigpKXJldHVybiEwCmVsc2UgcC5jPW51bGwKcz1mdW5jdGlvbihhLGIsYyl7dmFyIG8sbj1i
-CndoaWxlKHRydWUpdHJ5e3JldHVybiBhKG4sbyl9Y2F0Y2gobSl7bz1tCm49Y319KHAuYSwwLDEpCmlm
-KHMgaW5zdGFuY2VvZiBQLkZ5KXtyPXMuYgppZihyPT09Mil7dD1wLmQKaWYodD09bnVsbHx8dC5sZW5n
-dGg9PT0wKXtwLnNFQyhudWxsKQpyZXR1cm4hMX1pZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEp
-CnAuYT10LnBvcCgpCmNvbnRpbnVlfWVsc2V7dD1zLmEKaWYocj09PTMpdGhyb3cgdAplbHNle3E9Si5J
-VCh0KQppZihxIGluc3RhbmNlb2YgUC5HVil7dD1wLmQKaWYodD09bnVsbCl0PXAuZD1bXQpDLk5tLmko
-dCxwLmEpCnAuYT1xLmEKY29udGludWV9ZWxzZXtwLmM9cQpjb250aW51ZX19fX1lbHNle3Auc0VDKHMp
-CnJldHVybiEwfX1yZXR1cm4hMX0sCnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuYy5hKGEp
-fSwKJGlBbjoxfQpQLnE0LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuR1Yo
-dGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8MT4iKSl9fQpQLmI4LnByb3RvdHlwZT17fQpQLlBmLnByb3Rv
-dHlwZT17CncwOmZ1bmN0aW9uKGEsYil7dmFyIHQKUC5VSShhLCJlcnJvciIsdS5LKQp0PXRoaXMuYQpp
-Zih0LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5Oayhh
-LGI9PW51bGw/UC52MChhKTpiKX0sCnBtOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLncwKGEsbnVsbCl9
-fQpQLlpmLnByb3RvdHlwZT17CmFNOmZ1bmN0aW9uKGEsYil7dmFyIHQKdGhpcy4kdGkuQygiMS8iKS5h
-KGIpCnQ9dGhpcy5hCmlmKHQuYSE9PTApdGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBs
-ZXRlZCIpKQp0LlhmKGIpfX0KUC5GZS5wcm90b3R5cGU9ewpIUjpmdW5jdGlvbihhKXtpZigodGhpcy5j
-JjE1KSE9PTYpcmV0dXJuITAKcmV0dXJuIHRoaXMuYi5iLmJ2KHUuYWwuYSh0aGlzLmQpLGEuYSx1Lnks
-dS5LKX0sCkt3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZSxzPXUueixyPXUuSyxxPXRoaXMuJHRpLkMo
-IjIvIikscD10aGlzLmIuYgppZih1LmFnLmIodCkpcmV0dXJuIHEuYShwLnJwKHQsYS5hLGEuYixzLHIs
-dS5sKSkKZWxzZSByZXR1cm4gcS5hKHAuYnYodS5iSS5hKHQpLGEuYSxzLHIpKX19ClAudnMucHJvdG90
-eXBlPXsKU3E6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPXRoaXMuJHRpCnEuS3EoYykuQygiMS8o
-MikiKS5hKGEpCnQ9JC5YMwppZih0IT09Qy5OVSl7Yy5DKCJAPDAvPiIpLktxKHEuYykuQygiMSgyKSIp
-LmEoYSkKaWYoYiE9bnVsbCliPVAuVkgoYix0KX1zPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpy
-PWI9PW51bGw/MTozCnRoaXMueGYobmV3IFAuRmUocyxyLGEsYixxLkMoIkA8MT4iKS5LcShjKS5DKCJG
-ZTwxLDI+IikpKQpyZXR1cm4gc30sClc3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxs
-LGIpfSwKUWQ6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9dGhpcy4kdGkKcy5LcShjKS5DKCIxLygyKSIp
-LmEoYSkKdD1uZXcgUC52cygkLlgzLGMuQygidnM8MD4iKSkKdGhpcy54ZihuZXcgUC5GZSh0LDE5LGEs
-YixzLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gdH0sCk9BOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscgp1LmJmLmEobnVsbCkKdD10aGlzLiR0aQpzPSQuWDMKcj1uZXcgUC52cyhzLHQpCmlm
-KHMhPT1DLk5VKWE9UC5WSChhLHMpCnRoaXMueGYobmV3IFAuRmUociwyLG51bGwsYSx0LkMoIkA8MT4i
-KS5LcSh0LmMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiByfSwKeGY6ZnVuY3Rpb24oYSl7dmFyIHQscz10
-aGlzLHI9cy5hCmlmKHI8PTEpe2EuYT11LnguYShzLmMpCnMuYz1hfWVsc2V7aWYocj09PTIpe3Q9dS5f
-LmEocy5jKQpyPXQuYQppZihyPDQpe3QueGYoYSkKcmV0dXJufXMuYT1yCnMuYz10LmN9UC5UayhudWxs
-LG51bGwscy5iLHUuTS5hKG5ldyBQLmRhKHMsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2YXIgdCxzLHIs
-cSxwLG89dGhpcyxuPXt9Cm4uYT1hCmlmKGE9PW51bGwpcmV0dXJuCnQ9by5hCmlmKHQ8PTEpe3M9dS54
-LmEoby5jKQpyPW8uYz1hCmlmKHMhPW51bGwpe2Zvcig7cT1yLmEscSE9bnVsbDtyPXEpO3IuYT1zfX1l
-bHNle2lmKHQ9PT0yKXtwPXUuXy5hKG8uYykKdD1wLmEKaWYodDw0KXtwLmpRKGEpCnJldHVybn1vLmE9
-dApvLmM9cC5jfW4uYT1vLk44KGEpClAuVGsobnVsbCxudWxsLG8uYix1Lk0uYShuZXcgUC5vUShuLG8p
-KSl9fSwKYWg6ZnVuY3Rpb24oKXt2YXIgdD11LnguYSh0aGlzLmMpCnRoaXMuYz1udWxsCnJldHVybiB0
-aGlzLk44KHQpfSwKTjg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEscz1udWxsO3QhPW51bGw7
-cz10LHQ9cil7cj10LmEKdC5hPXN9cmV0dXJuIHN9LApISDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMs
-cj1zLiR0aQpyLkMoIjEvIikuYShhKQppZihyLkMoImI4PDE+IikuYihhKSlpZihyLmIoYSkpUC5BOShh
-LHMpCmVsc2UgUC5rMyhhLHMpCmVsc2V7dD1zLmFoKCkKci5jLmEoYSkKcy5hPTQKcy5jPWEKUC5IWihz
-LHQpfX0sClgyOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcwpzLiR0aS5jLmEoYSkKdD1zLmFoKCkKcy5h
-PTQKcy5jPWEKUC5IWihzLHQpfSwKWkw6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwp1LmwuYShi
-KQp0PXIuYWgoKQpzPVAuVGwoYSxiKQpyLmE9OApyLmM9cwpQLkhaKHIsdCl9LApYZjpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLHM9dC4kdGkKcy5DKCIxLyIpLmEoYSkKaWYocy5DKCJiODwxPiIpLmIoYSkpe3Qu
-Y1UoYSkKcmV0dXJufXQuYT0xClAuVGsobnVsbCxudWxsLHQuYix1Lk0uYShuZXcgUC5ySCh0LGEpKSl9
-LApjVTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9dC4kdGkKcy5DKCJiODwxPiIpLmEoYSkKaWYocy5i
-KGEpKXtpZihhLmE9PT04KXt0LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmEobmV3IFAuS0YodCxh
-KSkpfWVsc2UgUC5BOShhLHQpCnJldHVybn1QLmszKGEsdCl9LApOazpmdW5jdGlvbihhLGIpe3RoaXMu
-YT0xClAuVGsobnVsbCxudWxsLHRoaXMuYix1Lk0uYShuZXcgUC5aTCh0aGlzLGEsYikpKX0sCiRpYjg6
-MX0KUC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5hLHRoaXMuYil9LAokUzow
-fQpQLm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIsdGhpcy5hLmEpfSwKJFM6
-MH0KUC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKdC5hPTAKdC5ISChh
-KX0sCiRTOjEzfQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dS5sLmEoYikKdGhpcy5h
-LlpMKGEsYil9LAokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJEM6IiQyIiwK
-JEQ6ZnVuY3Rpb24oKXtyZXR1cm5bbnVsbF19LAokUzoyNX0KUC52ci5wcm90b3R5cGU9ewokMDpmdW5j
-dGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuckgucHJvdG90eXBlPXsKJDA6
-ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmEKdC5YMih0LiR0aS5jLmEodGhpcy5iKSl9LAokUzowfQpQLktG
-LnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5BOSh0aGlzLmIsdGhpcy5hKX0sCiRTOjB9ClAuWkwu
-cHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQ
-LlJULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxtPW51bGwK
-dHJ5e3I9bi5jCm09ci5iLmIuenoodS5mTy5hKHIuZCksdS56KX1jYXRjaChxKXt0PUguUnUocSkKcz1I
-LnRzKHEpCmlmKG4uZCl7cj11Lm4uYShuLmEuYS5jKS5hCnA9dApwPXI9PW51bGw/cD09bnVsbDpyPT09
-cApyPXB9ZWxzZSByPSExCnA9bi5iCmlmKHIpcC5iPXUubi5hKG4uYS5hLmMpCmVsc2UgcC5iPVAuVGwo
-dCxzKQpwLmE9ITAKcmV0dXJufWlmKHUuYy5iKG0pKXtpZihtIGluc3RhbmNlb2YgUC52cyYmbS5hPj00
-KXtpZihtLmE9PT04KXtyPW4uYgpyLmI9dS5uLmEobS5jKQpyLmE9ITB9cmV0dXJufW89bi5hLmEKcj1u
-LmIKci5iPW0uVzcobmV3IFAualoobyksdS56KQpyLmE9ITF9fSwKJFM6M30KUC5qWi5wcm90b3R5cGU9
-ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJFM6Mjl9ClAucnEucHJvdG90eXBlPXsKJDA6
-ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMKdHJ5e3I9bS5iCnE9ci4kdGkKcD1xLmMK
-bz1wLmEobS5jKQptLmEuYj1yLmIuYi5idihxLkMoIjIvKDEpIikuYShyLmQpLG8scS5DKCIyLyIpLHAp
-fWNhdGNoKG4pe3Q9SC5SdShuKQpzPUgudHMobikKcj1tLmEKci5iPVAuVGwodCxzKQpyLmE9ITB9fSwK
-JFM6M30KUC5SVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10
-aGlzCnRyeXt0PXUubi5hKGwuYS5hLmMpCnE9bC5jCmlmKEgub1QocS5IUih0KSkmJnEuZSE9bnVsbCl7
-cD1sLmIKcC5iPXEuS3codCkKcC5hPSExfX1jYXRjaChvKXtzPUguUnUobykKcj1ILnRzKG8pCnE9dS5u
-LmEobC5hLmEuYykKcD1xLmEKbj1zCm09bC5iCmlmKHA9PW51bGw/bj09bnVsbDpwPT09biltLmI9cQpl
-bHNlIG0uYj1QLlRsKHMscikKbS5hPSEwfX0sCiRTOjN9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJv
-dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT17fSxwPW5ldyBQLnZzKCQuWDMs
-dS5mSikKcS5hPTAKdD1ILkxoKHIpCnM9dC5DKCJ+KDEpIikuYShuZXcgUC5CNShxLHIpKQp1Lk0uYShu
-ZXcgUC51TyhxLHApKQpXLkpFKHIuYSxyLmIscywhMSx0LmMpCnJldHVybiBwfX0KUC5CNS5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXtILkxoKHRoaXMuYikuYy5hKGEpOysrdGhpcy5hLmF9LAokUzpmdW5j
-dGlvbigpe3JldHVybiBILkxoKHRoaXMuYikuQygiYzgoMSkiKX19ClAudU8ucHJvdG90eXBlPXsKJDA6
-ZnVuY3Rpb24oKXt0aGlzLmIuSEgodGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5cGU9e30KUC5r
-VC5wcm90b3R5cGU9e30KUC54SS5wcm90b3R5cGU9e30KUC5PSC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9u
-KGEpe3JldHVybiBILmQodGhpcy5hKX0sCiRpWFM6MSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMu
-Yn19ClAubTAucHJvdG90eXBlPXskaUpCOjF9ClAucEsucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2
-YXIgdCxzPXRoaXMuYSxyPXMuYgppZihyPT1udWxsKXRocm93IEguYihzLmEpCnQ9SC5iKHMuYSkKdC5z
-dGFjaz1yLlooMCkKdGhyb3cgdH0sCiRTOjB9ClAuSmkucHJvdG90eXBlPXsKYkg6ZnVuY3Rpb24oYSl7
-dmFyIHQscyxyLHE9bnVsbAp1Lk0uYShhKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDAoKQpyZXR1cm59
-UC5UOChxLHEsdGhpcyxhLHUuSCl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQLkwyKHEscSx0
-aGlzLHQsdS5sLmEocykpfX0sCkRsOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT1udWxsCmMuQygi
-figwKSIpLmEoYSkKYy5hKGIpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMShiKQpyZXR1cm59UC55dihx
-LHEsdGhpcyxhLGIsdS5ILGMpfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5MMihxLHEsdGhp
-cyx0LHUubC5hKHMpKX19LApSVDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5oaih0aGlzLGIuQygi
-MCgpIikuYShhKSxiKX0sCkdZOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5WcCh0aGlzLHUuTS5hKGEp
-KX0sClB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLk9SKHRoaXMsYi5DKCJ+KDApIikuYShhKSxi
-KX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbH0sCnp6OmZ1bmN0aW9uKGEsYil7Yi5DKCIwKCki
-KS5hKGEpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQwKCkKcmV0dXJuIFAuVDgobnVsbCxudWxsLHRo
-aXMsYSxiKX0sCmJ2OmZ1bmN0aW9uKGEsYixjLGQpe2MuQygiQDwwPiIpLktxKGQpLkMoIjEoMikiKS5h
-KGEpCmQuYShiKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMShiKQpyZXR1cm4gUC55dihudWxsLG51
-bGwsdGhpcyxhLGIsYyxkKX0sCnJwOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXtkLkMoIkA8MD4iKS5LcShl
-KS5LcShmKS5DKCIxKDIsMykiKS5hKGEpCmUuYShiKQpmLmEoYykKaWYoJC5YMz09PUMuTlUpcmV0dXJu
-IGEuJDIoYixjKQpyZXR1cm4gUC5ReChudWxsLG51bGwsdGhpcyxhLGIsYyxkLGUsZil9LApMajpmdW5j
-dGlvbihhLGIsYyxkKXtyZXR1cm4gYi5DKCJAPDA+IikuS3EoYykuS3EoZCkuQygiMSgyLDMpIikuYShh
-KX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLnp6KHRoaXMuYix0
-aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jLkMoIjAoKSIpfX0KUC5WcC5wcm90b3R5
-cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuYkgodGhpcy5iKX0sCiRTOjN9ClAuT1IucHJv
-dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0aGlzLmEuRGwodGhpcy5i
-LHQuYShhKSx0KX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCJ+KDApIil9fQpQLmI2LnBy
-b3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9bmV3IFAubG0odCx0LnIsSC5MaCh0
-KS5DKCJsbTwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-YX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19w
-cm90b19fIil7dD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5ELmEodFtiXSkhPW51
-bGx9ZWxzZXtzPXRoaXMuUFIoYikKcmV0dXJuIHN9fSwKUFI6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5k
-CmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuREYodFt0aGlzLk4oYSldLGEpPj0wfSwKaTpm
-dW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzCkguTGgocikuYy5hKGIpCmlmKHR5cGVvZiBiPT0ic3Ry
-aW5nIiYmYiE9PSJfX3Byb3RvX18iKXt0PXIuYgpyZXR1cm4gci5TKHQ9PW51bGw/ci5iPVAuVDIoKTp0
-LGIpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3M9ci5jCnJl
-dHVybiByLlMocz09bnVsbD9yLmM9UC5UMigpOnMsYil9ZWxzZSByZXR1cm4gci5CNyhiKX0sCkI3OmZ1
-bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMKSC5MaChxKS5jLmEoYSkKdD1xLmQKaWYodD09bnVsbCl0
-PXEuZD1QLlQyKCkKcz1xLk4oYSkKcj10W3NdCmlmKHI9PW51bGwpdFtzXT1bcS55byhhKV0KZWxzZXtp
-ZihxLkRGKHIsYSk+PTApcmV0dXJuITEKci5wdXNoKHEueW8oYSkpfXJldHVybiEwfSwKUjpmdW5jdGlv
-bihhLGIpe3ZhciB0PXRoaXMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpcmV0
-dXJuIHQuSDQodC5iLGIpCmVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09
-PWIpcmV0dXJuIHQuSDQodC5jLGIpCmVsc2UgcmV0dXJuIHQucWcoYil9LApxZzpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIscSxwPXRoaXMsbz1wLmQKaWYobz09bnVsbClyZXR1cm4hMQp0PXAuTihhKQpzPW9bdF0K
-cj1wLkRGKHMsYSkKaWYocjwwKXJldHVybiExCnE9cy5zcGxpY2UociwxKVswXQppZigwPT09cy5sZW5n
-dGgpZGVsZXRlIG9bdF0KcC5HUyhxKQpyZXR1cm4hMH0sClM6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMp
-LmMuYShiKQppZih1LkQuYShhW2JdKSE9bnVsbClyZXR1cm4hMQphW2JdPXRoaXMueW8oYikKcmV0dXJu
-ITB9LApINDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuITEKdD11LkQuYShhW2Jd
-KQppZih0PT1udWxsKXJldHVybiExCnRoaXMuR1ModCkKZGVsZXRlIGFbYl0KcmV0dXJuITB9LApYOmZ1
-bmN0aW9uKCl7dGhpcy5yPTEwNzM3NDE4MjMmdGhpcy5yKzF9LAp5bzpmdW5jdGlvbihhKXt2YXIgdCxz
-PXRoaXMscj1uZXcgUC5ibihILkxoKHMpLmMuYShhKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9cgplbHNl
-e3Q9cy5mCnIuYz10CnMuZj10LmI9cn0rK3MuYQpzLlgoKQpyZXR1cm4gcn0sCkdTOmZ1bmN0aW9uKGEp
-e3ZhciB0PXRoaXMscz1hLmMscj1hLmIKaWYocz09bnVsbCl0LmU9cgplbHNlIHMuYj1yCmlmKHI9PW51
-bGwpdC5mPXMKZWxzZSByLmM9czstLXQuYQp0LlgoKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJuIEouaGYo
-YSkmMTA3Mzc0MTgyM30sCkRGOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJldHVybi0x
-CnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBzCnJldHVy
-bi0xfX0KUC5ibi5wcm90b3R5cGU9e30KUC5sbS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVy
-biB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYQppZih0LmIhPT1zLnIpdGhyb3cg
-SC5iKFAuYTQocykpCmVsc2V7cz10LmMKaWYocz09bnVsbCl7dC5zaihudWxsKQpyZXR1cm4hMX1lbHNl
-e3Quc2oodC4kdGkuYy5hKHMuYSkpCnQuYz10LmMuYgpyZXR1cm4hMH19fSwKc2o6ZnVuY3Rpb24oYSl7
-dGhpcy5kPXRoaXMuJHRpLmMuYShhKX0sCiRpQW46MX0KUC5tVy5wcm90b3R5cGU9e30KUC5MVS5wcm90
-b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxfQpQLmxELnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihh
-KXtyZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgucShhKS5DKCJhNzxsRC5FPiIpKX0sCkU6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5xKGEsYil9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnEo
-YSkuQygifihsRC5FKSIpLmEoYikKdD10aGlzLmdBKGEpCmZvcihzPTA7czx0Oysrcyl7Yi4kMSh0aGlz
-LnEoYSxzKSkKaWYodCE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCmdvcjpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5nQShhKSE9PTB9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5xKGEp
-CnJldHVybiBuZXcgSC5sSihhLHQuS3EoYykuQygiMShsRC5FKSIpLmEoYiksdC5DKCJAPGxELkU+Iiku
-S3EoYykuQygibEo8MSwyPiIpKX0sCmR1OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0CkgucShhKS5DKCJs
-RC5FIikuYShkKQpQLmpCKGIsYyx0aGlzLmdBKGEpKQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxk
-KX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9
-ClAucmEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRo
-aXMuYi5hKz0iLCAiCnMuYT0hMQpzPXRoaXMuYgp0PXMuYSs9SC5kKGEpCnMuYT10KyI6ICIKcy5hKz1I
-LmQoYil9LAokUzoxfQpQLllrLnByb3RvdHlwZT17Cks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkguTGgo
-dGhpcykuQygifihZay5LLFlrLlYpIikuYShiKQpmb3IodD1KLklUKHRoaXMuZ1YoKSk7dC5GKCk7KXtz
-PXQuZ2woKQpiLiQyKHMsdGhpcy5xKDAscykpfX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gSi5NMSh0
-aGlzLmdWKCksbmV3IFAueVEodGhpcyksSC5MaCh0aGlzKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKeDQ6
-ZnVuY3Rpb24oYSl7cmV0dXJuIEouemwodGhpcy5nVigpLGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEouSCh0aGlzLmdWKCkpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLkNpKHRoaXMuZ1YoKSl9LApa
-OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKJGlaMDoxfQpQLnlRLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPUguTGgodCkKcy5DKCJZay5LIikuYShhKQpyZXR1cm4g
-bmV3IFAuTjMoYSx0LnEoMCxhKSxzLkMoIkA8WWsuSz4iKS5LcShzLkMoIllrLlYiKSkuQygiTjM8MSwy
-PiIpKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5hKS5DKCJOMzxZay5LLFlrLlY+KFlr
-LkspIil9fQpQLktQLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykK
-dC5jLmEoYikKdC5RWzFdLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlh
-YmxlIG1hcCIpKX19ClAuUG4ucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEu
-cSgwLGIpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0aGlzLmEuWSgwLHQuYy5h
-KGIpLHQuUVsxXS5hKGMpKX0sCng0OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEueDQoYSl9LApLOmZ1
-bmN0aW9uKGEsYil7dGhpcy5hLksoMCxILkxoKHRoaXMpLkMoIn4oMSwyKSIpLmEoYikpfSwKZ2wwOmZ1
-bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nbDAodCl9LApnQTpmdW5jdGlvbihhKXt2YXIg
-dD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBKLkFjKHRoaXMuYSl9
-LApnUHU6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdQdSh0KX0sCiRpWjA6MX0KUC5H
-ai5wcm90b3R5cGU9e30KUC5NYS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKHRo
-aXMsInsiLCJ9Iil9fQpQLlZqLnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXh1OjF9ClAuWHYucHJv
-dG90eXBlPXsKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3IodD1KLklUKEguTGgodGhpcykuQygiY1g8
-MT4iKS5hKGIpKTt0LkYoKTspdGhpcy5pKDAsdC5nbCgpKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAu
-V0UodGhpcywieyIsIn0iKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1QLnJqKHRoaXMsdGhpcy5y
-LEguTGgodGhpcykuYykKaWYoIXMuRigpKXJldHVybiIiCmlmKGI9PT0iIil7dD0iIgpkbyB0Kz1ILmQo
-cy5kKQp3aGlsZShzLkYoKSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5GKCk7KXQ9dCtiK0guZChzLmQp
-fXJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGliUToxLAokaWNYOjEsCiRpeHU6MX0KUC5u
-WS5wcm90b3R5cGU9e30KUC5UQy5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC51dy5wcm90
-b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09bnVsbClyZXR1cm4gdGhp
-cy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4gbnVsbAplbHNle3Q9c1ti
-XQpyZXR1cm4gdHlwZW9mIHQ9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6dH19LApnQTpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5ndGh9LApnbDA6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKZ1Y6ZnVuY3Rpb24oKXtpZih0aGlzLmI9PW51
-bGwpe3ZhciB0PXRoaXMuYwpyZXR1cm4gbmV3IEguaTUodCxILkxoKHQpLkMoImk1PDE+IikpfXJldHVy
-biBuZXcgUC5pOCh0aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj10aGlzCmlmKHIuYj09
-bnVsbClyLmMuWSgwLGIsYykKZWxzZSBpZihyLng0KGIpKXt0PXIuYgp0W2JdPWMKcz1yLmEKaWYocz09
-bnVsbD90IT1udWxsOnMhPT10KXNbYl09bnVsbH1lbHNlIHIuWEsoKS5ZKDAsYixjKX0sCng0OmZ1bmN0
-aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0KGEpCnJldHVybiBPYmplY3QucHJv
-dG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscixxLHA9dGhpcwp1LmNBLmEoYikKaWYocC5iPT1udWxsKXJldHVybiBwLmMuSygwLGIpCnQ9cC5D
-ZigpCmZvcihzPTA7czx0Lmxlbmd0aDsrK3Mpe3I9dFtzXQpxPXAuYltyXQppZih0eXBlb2YgcT09InVu
-ZGVmaW5lZCIpe3E9UC5RZShwLmFbcl0pCnAuYltyXT1xfWIuJDIocixxKQppZih0IT09cC5jKXRocm93
-IEguYihQLmE0KHApKX19LApDZjpmdW5jdGlvbigpe3ZhciB0PXUuai5hKHRoaXMuYykKaWYodD09bnVs
-bCl0PXRoaXMuYz1ILlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdS5zKQpyZXR1cm4gdH0sClhLOmZ1bmN0
-aW9uKCl7dmFyIHQscyxyLHEscCxvPXRoaXMKaWYoby5iPT1udWxsKXJldHVybiBvLmMKdD1QLkZsKHUu
-Tix1LnopCnM9by5DZigpCmZvcihyPTA7cT1zLmxlbmd0aCxyPHE7KytyKXtwPXNbcl0KdC5ZKDAscCxv
-LnEoMCxwKSl9aWYocT09PTApQy5ObS5pKHMsbnVsbCkKZWxzZSBDLk5tLnNBKHMsMCkKby5hPW8uYj1u
-dWxsCnJldHVybiBvLmM9dH0sCmZiOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCFPYmplY3QucHJvdG90eXBl
-Lmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpKXJldHVybiBudWxsCnQ9UC5RZSh0aGlzLmFbYV0p
-CnJldHVybiB0aGlzLmJbYV09dH19ClAuaTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcy5hCnJldHVybiB0LmdBKHQpfSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZih0LmI9
-PW51bGwpdD10LmdWKCkuRSgwLGIpCmVsc2V7dD10LkNmKCkKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1
-cm4gSC5rKHQsYikKdD10W2JdfXJldHVybiB0fSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpp
-Zih0LmI9PW51bGwpe3Q9dC5nVigpCnQ9dC5na3oodCl9ZWxzZXt0PXQuQ2YoKQp0PW5ldyBKLm0xKHQs
-dC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX1yZXR1cm4gdH0sCnRnOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIHRoaXMuYS54NChiKX19ClAuQ1YucHJvdG90eXBlPXsKeXI6ZnVuY3Rpb24oYSxhMCxhMSl7dmFy
-IHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGI9IkludmFsaWQgYmFzZTY0IGVuY29k
-aW5nIGxlbmd0aCAiCmExPVAuakIoYTAsYTEsYS5sZW5ndGgpCnQ9JC5WNygpCmZvcihzPWEwLHI9cyxx
-PW51bGwscD0tMSxvPS0xLG49MDtzPGExO3M9bSl7bT1zKzEKbD1DLnhCLlcoYSxzKQppZihsPT09Mzcp
-e2s9bSsyCmlmKGs8PWExKXtqPUgub28oQy54Qi5XKGEsbSkpCmk9SC5vbyhDLnhCLlcoYSxtKzEpKQpo
-PWoqMTYraS0oaSYyNTYpCmlmKGg9PT0zNyloPS0xCm09a31lbHNlIGg9LTF9ZWxzZSBoPWwKaWYoMDw9
-aCYmaDw9MTI3KXtpZihoPDB8fGg+PXQubGVuZ3RoKXJldHVybiBILmsodCxoKQpnPXRbaF0KaWYoZz49
-MCl7aD1DLnhCLm0oIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1
-dnd4eXowMTIzNDU2Nzg5Ky8iLGcpCmlmKGg9PT1sKWNvbnRpbnVlCmw9aH1lbHNle2lmKGc9PT0tMSl7
-aWYocDwwKXtmPXE9PW51bGw/bnVsbDpxLmEubGVuZ3RoCmlmKGY9PW51bGwpZj0wCnA9Zisocy1yKQpv
-PXN9KytuCmlmKGw9PT02MSljb250aW51ZX1sPWh9aWYoZyE9PS0yKXtpZihxPT1udWxsKXE9bmV3IFAu
-Um4oIiIpCnEuYSs9Qy54Qi5OaihhLHIscykKcS5hKz1ILkx3KGwpCnI9bQpjb250aW51ZX19dGhyb3cg
-SC5iKFAucnIoIkludmFsaWQgYmFzZTY0IGRhdGEiLGEscykpfWlmKHEhPW51bGwpe2Y9cS5hKz1DLnhC
-Lk5qKGEscixhMSkKZT1mLmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAsbixlKQplbHNle2Q9Qy5q
-bi56WShlLTEsNCkrMQppZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEpKQpmb3IoO2Q8NDspe2Yr
-PSI9IgpxLmE9ZjsrK2R9fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEsZi5jaGFyQ29kZUF0KDAp
-PT0wP2Y6Zil9Yz1hMS1hMAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQplbHNle2Q9Qy5qbi56WShj
-LDQpCmlmKGQ9PT0xKXRocm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlhPUMueEIuaTcoYSxhMSxh
-MSxkPT09Mj8iPT0iOiI9Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlw
-ZT17fQpQLndJLnByb3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLlVkLnByb3RvdHlwZT17Clo6
-ZnVuY3Rpb24oYSl7dmFyIHQ9UC5oKHRoaXMuYSkKcmV0dXJuKHRoaXMuYiE9bnVsbD8iQ29udmVydGlu
-ZyBvYmplY3QgdG8gYW4gZW5jb2RhYmxlIG9iamVjdCBmYWlsZWQ6IjoiQ29udmVydGluZyBvYmplY3Qg
-ZGlkIG5vdCByZXR1cm4gYW4gZW5jb2RhYmxlIG9iamVjdDoiKSsiICIrdH19ClAuSzgucHJvdG90eXBl
-PXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iQ3ljbGljIGVycm9yIGluIEpTT04gc3RyaW5naWZ5In19ClAu
-YnkucHJvdG90eXBlPXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnUuZXAuYShjKQp0PVAuQlMoYix0
-aGlzLmdIZSgpLmEpCnJldHVybiB0fSwKT0I6ZnVuY3Rpb24oYSxiKXt2YXIgdAp1LmJjLmEoYikKdD1Q
-LnVYKGEsdGhpcy5nWkUoKS5iLG51bGwpCnJldHVybiB0fSwKZ1pFOmZ1bmN0aW9uKCl7cmV0dXJuIEMu
-blh9LApnSGU6ZnVuY3Rpb24oKXtyZXR1cm4gQy5BM319ClAub2oucHJvdG90eXBlPXt9ClAuTXgucHJv
-dG90eXBlPXt9ClAuU2gucHJvdG90eXBlPXsKdnA6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49
-YS5sZW5ndGgKZm9yKHQ9Si5yWShhKSxzPXRoaXMuYyxyPTAscT0wO3E8bjsrK3Epe3A9dC5XKGEscSkK
-aWYocD45Miljb250aW51ZQppZihwPDMyKXtpZihxPnIpcy5hKz1DLnhCLk5qKGEscixxKQpyPXErMQpz
-LmErPUguTHcoOTIpCnN3aXRjaChwKXtjYXNlIDg6cy5hKz1ILkx3KDk4KQpicmVhawpjYXNlIDk6cy5h
-Kz1ILkx3KDExNikKYnJlYWsKY2FzZSAxMDpzLmErPUguTHcoMTEwKQpicmVhawpjYXNlIDEyOnMuYSs9
-SC5MdygxMDIpCmJyZWFrCmNhc2UgMTM6cy5hKz1ILkx3KDExNCkKYnJlYWsKZGVmYXVsdDpzLmErPUgu
-THcoMTE3KQpzLmErPUguTHcoNDgpCnMuYSs9SC5Mdyg0OCkKbz1wPj4+NCYxNQpzLmErPUguTHcobzwx
-MD80OCtvOjg3K28pCm89cCYxNQpzLmErPUguTHcobzwxMD80OCtvOjg3K28pCmJyZWFrfX1lbHNlIGlm
-KHA9PT0zNHx8cD09PTkyKXtpZihxPnIpcy5hKz1DLnhCLk5qKGEscixxKQpyPXErMQpzLmErPUguTHco
-OTIpCnMuYSs9SC5MdyhwKX19aWYocj09PTApcy5hKz1ILmQoYSkKZWxzZSBpZihyPG4pcy5hKz10Lk5q
-KGEscixuKX0sCkpuOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxCmZvcih0PXRoaXMuYSxzPXQubGVuZ3Ro
-LHI9MDtyPHM7KytyKXtxPXRbcl0KaWYoYT09bnVsbD9xPT1udWxsOmE9PT1xKXRocm93IEguYihuZXcg
-UC5LOChhLG51bGwpKX1DLk5tLmkodCxhKX0sCmlVOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9dGhp
-cwppZihwLnRNKGEpKXJldHVybgpwLkpuKGEpCnRyeXt0PXAuYi4kMShhKQppZighcC50TSh0KSl7cj1Q
-Lkd5KGEsbnVsbCxwLmdWSygpKQp0aHJvdyBILmIocil9cj1wLmEKaWYoMD49ci5sZW5ndGgpcmV0dXJu
-IEguayhyLC0xKQpyLnBvcCgpfWNhdGNoKHEpe3M9SC5SdShxKQpyPVAuR3koYSxzLHAuZ1ZLKCkpCnRo
-cm93IEguYihyKX19LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcwppZih0eXBlb2YgYT09Im51
-bWJlciIpe2lmKCFpc0Zpbml0ZShhKSlyZXR1cm4hMQpyLmMuYSs9Qy5DRC5aKGEpCnJldHVybiEwfWVs
-c2UgaWYoYT09PSEwKXtyLmMuYSs9InRydWUiCnJldHVybiEwfWVsc2UgaWYoYT09PSExKXtyLmMuYSs9
-ImZhbHNlIgpyZXR1cm4hMH1lbHNlIGlmKGE9PW51bGwpe3IuYy5hKz0ibnVsbCIKcmV0dXJuITB9ZWxz
-ZSBpZih0eXBlb2YgYT09InN0cmluZyIpe3Q9ci5jCnQuYSs9JyInCnIudnAoYSkKdC5hKz0nIicKcmV0
-dXJuITB9ZWxzZSBpZih1LmouYihhKSl7ci5KbihhKQpyLmxLKGEpCnQ9ci5hCmlmKDA+PXQubGVuZ3Ro
-KXJldHVybiBILmsodCwtMSkKdC5wb3AoKQpyZXR1cm4hMH1lbHNlIGlmKHUuRy5iKGEpKXtyLkpuKGEp
-CnM9ci5qdyhhKQp0PXIuYQppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEpCnQucG9wKCkKcmV0
-dXJuIHN9ZWxzZSByZXR1cm4hMX0sCmxLOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLmMKci5hKz0i
-WyIKdD1KLlU2KGEpCmlmKHQuZ29yKGEpKXt0aGlzLmlVKHQucShhLDApKQpmb3Iocz0xO3M8dC5nQShh
-KTsrK3Mpe3IuYSs9IiwiCnRoaXMuaVUodC5xKGEscykpfX1yLmErPSJdIn0sCmp3OmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscixxLHAsbyxuPXRoaXMsbT17fQppZihhLmdsMChhKSl7bi5jLmErPSJ7fSIKcmV0dXJu
-ITB9dD1hLmdBKGEpKjIKcz1uZXcgQXJyYXkodCkKcy5maXhlZCRsZW5ndGg9QXJyYXkKcj1tLmE9MApt
-LmI9ITAKYS5LKDAsbmV3IFAudGkobSxzKSkKaWYoIW0uYilyZXR1cm4hMQpxPW4uYwpxLmErPSJ7Igpm
-b3IocD0nIic7cjx0O3IrPTIscD0nLCInKXtxLmErPXAKbi52cChILmMoc1tyXSkpCnEuYSs9JyI6Jwpv
-PXIrMQppZihvPj10KXJldHVybiBILmsocyxvKQpuLmlVKHNbb10pfXEuYSs9In0iCnJldHVybiEwfX0K
-UC50aS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYodHlwZW9mIGEhPSJzdHJp
-bmciKXRoaXMuYS5iPSExCnQ9dGhpcy5iCnM9dGhpcy5hCkMuTm0uWSh0LHMuYSsrLGEpCkMuTm0uWSh0
-LHMuYSsrLGIpfSwKJFM6MX0KUC50dS5wcm90b3R5cGU9ewpnVks6ZnVuY3Rpb24oKXt2YXIgdD10aGlz
-LmMuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH19ClAudTUucHJvdG90eXBlPXsKZ1pFOmZ1
-bmN0aW9uKCl7cmV0dXJuIEMuUWt9fQpQLkUzLnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0
-LHMscj1QLmpCKDAsbnVsbCxhLmxlbmd0aCkscT1yLTAKaWYocT09PTApcmV0dXJuIG5ldyBVaW50OEFy
-cmF5KDApCnQ9bmV3IFVpbnQ4QXJyYXkocSozKQpzPW5ldyBQLlJ3KHQpCmlmKHMuR3goYSwwLHIpIT09
-cilzLk82KEouYTYoYSxyLTEpLDApCnJldHVybiBuZXcgVWludDhBcnJheSh0LnN1YmFycmF5KDAsSC5y
-TSgwLHMuYix0Lmxlbmd0aCkpKX19ClAuUncucHJvdG90eXBlPXsKTzY6ZnVuY3Rpb24oYSxiKXt2YXIg
-dCxzPXRoaXMscj1zLmMscT1zLmIscD1xKzEsbz1yLmxlbmd0aAppZigoYiY2NDUxMik9PT01NjMyMCl7
-dD02NTUzNisoKGEmMTAyMyk8PDEwKXxiJjEwMjMKcy5iPXAKaWYocT49bylyZXR1cm4gSC5rKHIscSkK
-cltxXT0yNDB8dD4+PjE4CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHx0
-Pj4+MTImNjMKcD1zLmI9cSsxCmlmKHE+PW8pcmV0dXJuIEguayhyLHEpCnJbcV09MTI4fHQ+Pj42JjYz
-CnMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5rKHIscCkKcltwXT0xMjh8dCY2MwpyZXR1cm4hMH1lbHNl
-e3MuYj1wCmlmKHE+PW8pcmV0dXJuIEguayhyLHEpCnJbcV09MjI0fGE+Pj4xMgpxPXMuYj1wKzEKaWYo
-cD49bylyZXR1cm4gSC5rKHIscCkKcltwXT0xMjh8YT4+PjYmNjMKcy5iPXErMQppZihxPj1vKXJldHVy
-biBILmsocixxKQpyW3FdPTEyOHxhJjYzCnJldHVybiExfX0sCkd4OmZ1bmN0aW9uKGEsYixjKXt2YXIg
-dCxzLHIscSxwLG8sbixtPXRoaXMKaWYoYiE9PWMmJihDLnhCLm0oYSxjLTEpJjY0NTEyKT09PTU1Mjk2
-KS0tYwpmb3IodD1tLmMscz10Lmxlbmd0aCxyPWI7cjxjOysrcil7cT1DLnhCLlcoYSxyKQppZihxPD0x
-Mjcpe3A9bS5iCmlmKHA+PXMpYnJlYWsKbS5iPXArMQp0W3BdPXF9ZWxzZSBpZigocSY2NDUxMik9PT01
-NTI5Nil7aWYobS5iKzM+PXMpYnJlYWsKbz1yKzEKaWYobS5PNihxLEMueEIuVyhhLG8pKSlyPW99ZWxz
-ZSBpZihxPD0yMDQ3KXtwPW0uYgpuPXArMQppZihuPj1zKWJyZWFrCm0uYj1uCmlmKHA+PXMpcmV0dXJu
-IEguayh0LHApCnRbcF09MTkyfHE+Pj42Cm0uYj1uKzEKdFtuXT0xMjh8cSY2M31lbHNle3A9bS5iCmlm
-KHArMj49cylicmVhawpuPW0uYj1wKzEKaWYocD49cylyZXR1cm4gSC5rKHQscCkKdFtwXT0yMjR8cT4+
-PjEyCnA9bS5iPW4rMQppZihuPj1zKXJldHVybiBILmsodCxuKQp0W25dPTEyOHxxPj4+NiY2MwptLmI9
-cCsxCmlmKHA+PXMpcmV0dXJuIEguayh0LHApCnRbcF09MTI4fHEmNjN9fXJldHVybiByfX0KUC5HWS5w
-cm90b3R5cGU9ewpXSjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwKdS5MLmEoYSkKdD1Q
-Lmt5KCExLGEsMCxudWxsKQppZih0IT1udWxsKXJldHVybiB0CnM9UC5qQigwLG51bGwsSi5IKGEpKQpy
-PVAuY1AoYSwwLHMpCmlmKHI+MCl7cT1QLkhNKGEsMCxyKQppZihyPT09cylyZXR1cm4gcQpwPW5ldyBQ
-LlJuKHEpCm89cgpuPSExfWVsc2V7bz0wCnA9bnVsbApuPSEwfWlmKHA9PW51bGwpcD1uZXcgUC5Sbigi
-IikKbT1uZXcgUC5ieighMSxwKQptLmM9bgptLk1FKGEsbyxzKQppZihtLmU+MCl7SC52aChQLnJyKCJV
-bmZpbmlzaGVkIFVURi04IG9jdGV0IHNlcXVlbmNlIixhLHMpKQpwLmErPUguTHcoNjU1MzMpCm0uZj1t
-LmU9bS5kPTB9bD1wLmEKcmV0dXJuIGwuY2hhckNvZGVBdCgwKT09MD9sOmx9fQpQLmJ6LnByb3RvdHlw
-ZT17Ck1FOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaD10aGlzLGc9
-IkJhZCBVVEYtOCBlbmNvZGluZyAweCIKdS5MLmEoYSkKdD1oLmQKcz1oLmUKcj1oLmYKaC5mPWguZT1o
-LmQ9MAokbGFiZWwwJDA6Zm9yKHE9Si5VNihhKSxwPWguYixvPWI7ITA7bz1qKXskbGFiZWwxJDE6aWYo
-cz4wKXtkb3tpZihvPT09YylicmVhayAkbGFiZWwwJDAKbj1xLnEoYSxvKQppZih0eXBlb2YgbiE9PSJu
-dW1iZXIiKXJldHVybiBuLnpNKCkKaWYoKG4mMTkyKSE9PTEyOCl7bT1QLnJyKGcrQy5qbi5XWihuLDE2
-KSxhLG8pCnRocm93IEguYihtKX1lbHNle3Q9KHQ8PDZ8biY2Myk+Pj4wOy0tczsrK299fXdoaWxlKHM+
-MCkKbT1yLTEKaWYobTwwfHxtPj00KXJldHVybiBILmsoQy5HYixtKQppZih0PD1DLkdiW21dKXttPVAu
-cnIoIk92ZXJsb25nIGVuY29kaW5nIG9mIDB4IitDLmpuLldaKHQsMTYpLGEsby1yLTEpCnRocm93IEgu
-YihtKX1pZih0PjExMTQxMTEpe209UC5ycigiQ2hhcmFjdGVyIG91dHNpZGUgdmFsaWQgVW5pY29kZSBy
-YW5nZTogMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0pfWlmKCFoLmN8fHQhPT02
-NTI3OSlwLmErPUguTHcodCkKaC5jPSExfWZvcihtPW88YzttOyl7bD1QLmNQKGEsbyxjKQppZihsPjAp
-e2guYz0hMQprPW8rbApwLmErPVAuSE0oYSxvLGspCmlmKGs9PT1jKWJyZWFrfWVsc2Ugaz1vCmo9aysx
-Cm49cS5xKGEsaykKaWYodHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5KKCkKaWYobjwwKXtpPVAu
-cnIoIk5lZ2F0aXZlIFVURi04IGNvZGUgdW5pdDogLTB4IitDLmpuLldaKC1uLDE2KSxhLGotMSkKdGhy
-b3cgSC5iKGkpfWVsc2V7aWYoKG4mMjI0KT09PTE5Mil7dD1uJjMxCnM9MQpyPTEKY29udGludWUgJGxh
-YmVsMCQwfWlmKChuJjI0MCk9PT0yMjQpe3Q9biYxNQpzPTIKcj0yCmNvbnRpbnVlICRsYWJlbDAkMH1p
-ZigobiYyNDgpPT09MjQwJiZuPDI0NSl7dD1uJjcKcz0zCnI9Mwpjb250aW51ZSAkbGFiZWwwJDB9aT1Q
-LnJyKGcrQy5qbi5XWihuLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfX1icmVhayAkbGFiZWwwJDB9aWYo
-cz4wKXtoLmQ9dApoLmU9cwpoLmY9cn19fQpQLldGLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscyxyCnUuZm8uYShhKQp0PXRoaXMuYgpzPXRoaXMuYQp0LmErPXMuYQpyPXQuYSs9SC5kKGEu
-YSkKdC5hPXIrIjogIgp0LmErPVAuaChiKQpzLmE9IiwgIn0sCiRTOjQxfQpQLmEyLnByb3RvdHlwZT17
-fQpQLmlQLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1
-cm4gYiBpbnN0YW5jZW9mIFAuaVAmJnRoaXMuYT09PWIuYSYmITB9LApnaU86ZnVuY3Rpb24oYSl7dmFy
-IHQ9dGhpcy5hCnJldHVybih0XkMuam4ud0codCwzMCkpJjEwNzM3NDE4MjN9LApaOmZ1bmN0aW9uKGEp
-e3ZhciB0PXRoaXMscz1QLkdxKEgudEoodCkpLHI9UC5oMChILk5TKHQpKSxxPVAuaDAoSC5qQSh0KSks
-cD1QLmgwKEguSVgodCkpLG89UC5oMChILmNoKHQpKSxuPVAuaDAoSC5KZCh0KSksbT1QLlZ4KEguVmEo
-dCkpLGw9cysiLSIrcisiLSIrcSsiICIrcCsiOiIrbysiOiIrbisiLiIrbQpyZXR1cm4gbH19ClAuQ1Au
-cHJvdG90eXBlPXt9ClAuWFMucHJvdG90eXBlPXsKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIEgudHModGhp
-cy4kdGhyb3duSnNFcnJvcil9fQpQLkM2LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
-cy5hCmlmKHQhPW51bGwpcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5oKHQpCnJldHVybiJBc3Nl
-cnRpb24gZmFpbGVkIn19ClAuTEsucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iVGhyb3cg
-b2YgbnVsbC4ifX0KUC5BVC5wcm90b3R5cGU9ewpnTDpmdW5jdGlvbigpe3JldHVybiJJbnZhbGlkIGFy
-Z3VtZW50IisoIXRoaXMuYT8iKHMpIjoiIil9LApndTpmdW5jdGlvbigpe3JldHVybiIifSwKWjpmdW5j
-dGlvbihhKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1wLmMsbj1vIT1udWxsPyIgKCIrbysiKSI6IiIKbz1w
-LmQKdD1vPT1udWxsPyIiOiI6ICIrSC5kKG8pCnM9cC5nTCgpK24rdAppZighcC5hKXJldHVybiBzCnI9
-cC5ndSgpCnE9UC5oKHAuYikKcmV0dXJuIHMrcisiOiAiK3F9fQpQLmJKLnByb3RvdHlwZT17CmdMOmZ1
-bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5l
-CmlmKHI9PW51bGwpe3I9dGhpcy5mCnQ9ciE9bnVsbD8iOiBOb3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRv
-ICIrSC5kKHIpOiIifWVsc2V7cz10aGlzLmYKaWYocz09bnVsbCl0PSI6IE5vdCBncmVhdGVyIHRoYW4g
-b3IgZXF1YWwgdG8gIitILmQocikKZWxzZSBpZihzPnIpdD0iOiBOb3QgaW4gcmFuZ2UgIitILmQocikr
-Ii4uIitILmQocykrIiwgaW5jbHVzaXZlIgplbHNlIHQ9czxyPyI6IFZhbGlkIHZhbHVlIHJhbmdlIGlz
-IGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5kKHIpfXJldHVybiB0fX0KUC5lWS5wcm90
-b3R5cGU9ewpnTDpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFy
-IHQscz1ILldZKHRoaXMuYikKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5KKCkKaWYoczww
-KXJldHVybiI6IGluZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZlIgp0PXRoaXMuZgppZih0PT09MClyZXR1
-cm4iOiBubyBpbmRpY2VzIGFyZSB2YWxpZCIKcmV0dXJuIjogaW5kZXggc2hvdWxkIGJlIGxlc3MgdGhh
-biAiK0guZCh0KX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmZ9fQpQLm1wLnByb3RvdHlwZT17
-Clo6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPXRoaXMsaz17fSxqPW5ldyBQLlJuKCIi
-KQprLmE9IiIKZm9yKHQ9bC5jLHM9dC5sZW5ndGgscj0wLHE9IiIscD0iIjtyPHM7KytyLHA9IiwgIil7
-bz10W3JdCmouYT1xK3AKcT1qLmErPVAuaChvKQprLmE9IiwgIn1sLmQuSygwLG5ldyBQLldGKGssaikp
-Cm49UC5oKGwuYSkKbT1qLlooMCkKdD0iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6
-ICciK0guZChsLmIuYSkrIidcblJlY2VpdmVyOiAiK24rIlxuQXJndW1lbnRzOiBbIittKyJdIgpyZXR1
-cm4gdH19ClAudWIucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iVW5zdXBwb3J0ZWQgb3Bl
-cmF0aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-LmEKcmV0dXJuIHQhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIit0OiJVbmltcGxlbWVudGVkRXJy
-b3IifX0KUC5sai5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJCYWQgc3RhdGU6ICIrdGhp
-cy5hfX0KUC5VVi5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0PT1udWxs
-KXJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9uLiIKcmV0dXJuIkNv
-bmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5oKHQpKyIuIn19ClAuazUu
-cHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9LApnSUk6ZnVuY3Rp
-b24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3Jl
-dHVybiJTdGFjayBPdmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0K
-UC50Ny5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdD09bnVsbD8i
-UmVhZGluZyBzdGF0aWMgdmFyaWFibGUgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiI6IlJlYWRpbmcg
-c3RhdGljIHZhcmlhYmxlICciK3QrIicgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiJ9fQpQLkNELnBy
-b3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIkV4Y2VwdGlvbjogIit0aGlzLmF9LAokaVJ6OjF9
-ClAuYUUucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGks
-aD10aGlzLmEsZz1oIT1udWxsJiYiIiE9PWg/IkZvcm1hdEV4Y2VwdGlvbjogIitILmQoaCk6IkZvcm1h
-dEV4Y2VwdGlvbiIsZj10aGlzLmMsZT10aGlzLmIKaWYodHlwZW9mIGU9PSJzdHJpbmciKXtpZihmIT1u
-dWxsKWg9ZjwwfHxmPmUubGVuZ3RoCmVsc2UgaD0hMQppZihoKWY9bnVsbAppZihmPT1udWxsKXt0PWUu
-bGVuZ3RoPjc4P0MueEIuTmooZSwwLDc1KSsiLi4uIjplCnJldHVybiBnKyJcbiIrdH1mb3Iocz0xLHI9
-MCxxPSExLHA9MDtwPGY7KytwKXtvPUMueEIuVyhlLHApCmlmKG89PT0xMCl7aWYociE9PXB8fCFxKSsr
-cwpyPXArMQpxPSExfWVsc2UgaWYobz09PTEzKXsrK3MKcj1wKzEKcT0hMH19Zz1zPjE/ZysoIiAoYXQg
-bGluZSAiK3MrIiwgY2hhcmFjdGVyICIrKGYtcisxKSsiKVxuIik6ZysoIiAoYXQgY2hhcmFjdGVyICIr
-KGYrMSkrIilcbiIpCm49ZS5sZW5ndGgKZm9yKHA9ZjtwPG47KytwKXtvPUMueEIubShlLHApCmlmKG89
-PT0xMHx8bz09PTEzKXtuPXAKYnJlYWt9fWlmKG4tcj43OClpZihmLXI8NzUpe209cis3NQpsPXIKaz0i
-IgpqPSIuLi4ifWVsc2V7aWYobi1mPDc1KXtsPW4tNzUKbT1uCmo9IiJ9ZWxzZXtsPWYtMzYKbT1mKzM2
-Cmo9Ii4uLiJ9az0iLi4uIn1lbHNle209bgpsPXIKaz0iIgpqPSIifWk9Qy54Qi5OaihlLGwsbSkKcmV0
-dXJuIGcraytpK2orIlxuIitDLnhCLkl4KCIgIixmLWwray5sZW5ndGgpKyJeXG4ifWVsc2UgcmV0dXJu
-IGYhPW51bGw/ZysoIiAoYXQgb2Zmc2V0ICIrSC5kKGYpKyIpIik6Z30sCiRpUno6MX0KUC5FSC5wcm90
-b3R5cGU9e30KUC5JZi5wcm90b3R5cGU9e30KUC5jWC5wcm90b3R5cGU9ewpFMjpmdW5jdGlvbihhLGIs
-Yyl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gSC5LMSh0aGlzLHQuS3EoYykuQygiMShjWC5FKSIpLmEo
-YiksdC5DKCJjWC5FIiksYyl9LApldjpmdW5jdGlvbihhLGIpe3ZhciB0PUguTGgodGhpcykKcmV0dXJu
-IG5ldyBILlU1KHRoaXMsdC5DKCJhMihjWC5FKSIpLmEoYiksdC5DKCJVNTxjWC5FPiIpKX0sCmdBOmZ1
-bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5na3oodGhpcykKZm9yKHQ9MDtzLkYoKTspKyt0CnJldHVybiB0
-fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdreih0aGlzKS5GKCl9LApncjg6ZnVuY3Rpb24o
-YSl7dmFyIHQscz10aGlzLmdreih0aGlzKQppZighcy5GKCkpdGhyb3cgSC5iKEguV3AoKSkKdD1zLmds
-KCkKaWYocy5GKCkpdGhyb3cgSC5iKEguZFUoKSkKcmV0dXJuIHR9LApFOmZ1bmN0aW9uKGEsYil7dmFy
-IHQscyxyLHE9ImluZGV4IgpQLlVJKGIscSx1LnEpClAuazEoYixxKQpmb3IodD10aGlzLmdreih0aGlz
-KSxzPTA7dC5GKCk7KXtyPXQuZ2woKQppZihiPT09cylyZXR1cm4gcjsrK3N9dGhyb3cgSC5iKFAudChi
-LHRoaXMscSxudWxsLHMpKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuRVAodGhpcywiKCIsIikiKX19
-ClAuQW4ucHJvdG90eXBlPXt9ClAuek0ucHJvdG90eXBlPXskaWJROjEsJGljWDoxfQpQLlowLnByb3Rv
-dHlwZT17fQpQLk4zLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIk1hcEVudHJ5KCIrSC5k
-KHRoaXMuYSkrIjogIitILmQodGhpcy5iKSsiKSJ9fQpQLmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlv
-bihhKXtyZXR1cm4gUC5NaC5wcm90b3R5cGUuZ2lPLmNhbGwodGhpcyx0aGlzKX0sClo6ZnVuY3Rpb24o
-YSl7cmV0dXJuIm51bGwifX0KUC5sZi5wcm90b3R5cGU9e30KUC5NaC5wcm90b3R5cGU9e2NvbnN0cnVj
-dG9yOlAuTWgsJGlNaDoxLApETjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzPT09Yn0sCmdpTzpmdW5j
-dGlvbihhKXtyZXR1cm4gSC5lUSh0aGlzKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIkluc3RhbmNlIG9m
-ICciK0guZChILmxoKHRoaXMpKSsiJyJ9LAplNzpmdW5jdGlvbihhLGIpe3Uuby5hKGIpCnRocm93IEgu
-YihQLmxyKHRoaXMsYi5nV2EoKSxiLmduZCgpLGIuZ1ZtKCkpKX0sCnRvU3RyaW5nOmZ1bmN0aW9uKCl7
-cmV0dXJuIHRoaXMuWih0aGlzKX19ClAuT2QucHJvdG90eXBlPXt9ClAuaWIucHJvdG90eXBlPXskaU9k
-OjF9ClAueHUucHJvdG90eXBlPXt9ClAuR3oucHJvdG90eXBlPXt9ClAuWmQucHJvdG90eXBlPXsKWjpm
-dW5jdGlvbihhKXtyZXR1cm4iIn0sCiRpR3o6MX0KUC5xVS5wcm90b3R5cGU9eyRpdlg6MX0KUC5Sbi5w
-cm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sClo6ZnVuY3Rpb24o
-YSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGlCTDoxfQpQLkdE
-LnByb3RvdHlwZT17fQpQLm4xLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEK
-dS5mLmEoYSkKSC5jKGIpCnQ9Si5yWShiKS5PWShiLCI9IikKaWYodD09PS0xKXtpZihiIT09IiIpYS5Z
-KDAsUC5rdShiLDAsYi5sZW5ndGgsdGhpcy5hLCEwKSwiIil9ZWxzZSBpZih0IT09MCl7cz1DLnhCLk5q
-KGIsMCx0KQpyPUMueEIuRyhiLHQrMSkKcT10aGlzLmEKYS5ZKDAsUC5rdShzLDAscy5sZW5ndGgscSwh
-MCksUC5rdShyLDAsci5sZW5ndGgscSwhMCkpfXJldHVybiBhfSwKJFM6Mjd9ClAuY1MucHJvdG90eXBl
-PXsKJDI6ZnVuY3Rpb24oYSxiKXt0aHJvdyBILmIoUC5ycigiSWxsZWdhbCBJUHY0IGFkZHJlc3MsICIr
-YSx0aGlzLmEsYikpfSwKJFM6NDN9ClAuVkMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aHJv
-dyBILmIoUC5ycigiSWxsZWdhbCBJUHY2IGFkZHJlc3MsICIrYSx0aGlzLmEsYikpfSwKJDE6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuJDIoYSxudWxsKX0sCiRTOjM3fQpQLkpULnByb3RvdHlwZT17CiQyOmZ1
-bmN0aW9uKGEsYil7dmFyIHQKaWYoYi1hPjQpdGhpcy5hLiQyKCJhbiBJUHY2IHBhcnQgY2FuIG9ubHkg
-Y29udGFpbiBhIG1heGltdW0gb2YgNCBoZXggZGlnaXRzIixhKQp0PVAuUUEoQy54Qi5Oaih0aGlzLmIs
-YSxiKSxudWxsLDE2KQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PDB8fHQ+
-NjU1MzUpdGhpcy5hLiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2Ugb2YgYDB4MC4uMHhG
-RkZGYCIsYSkKcmV0dXJuIHR9LAokUzo0MH0KUC5Ebi5wcm90b3R5cGU9ewpna3U6ZnVuY3Rpb24oKXty
-ZXR1cm4gdGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVy
-biIiCmlmKEMueEIubih0LCJbIikpcmV0dXJuIEMueEIuTmoodCwxLHQubGVuZ3RoLTEpCnJldHVybiB0
-fSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZAppZih0PT1udWxsKXJldHVybiBQLndLKHRoaXMu
-YSkKcmV0dXJuIHR9LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYKcmV0dXJuIHQ9PW51bGw/IiI6
-dH0sCmdLYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMucgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKbm06ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwp1LlguYShudWxsKQp1LmIuYShiKQp0
-PWwuYQpzPXQ9PT0iZmlsZSIKcj1sLmIKcT1sLmQKcD1sLmMKaWYoIShwIT1udWxsKSlwPXIubGVuZ3Ro
-IT09MHx8cSE9bnVsbHx8cz8iIjpudWxsCm89bC5lCmlmKCFzKW49cCE9bnVsbCYmby5sZW5ndGghPT0w
-CmVsc2Ugbj0hMAppZihuJiYhQy54Qi5uKG8sIi8iKSlvPSIvIitvCm09UC5sZShudWxsLDAsMCxiKQpy
-ZXR1cm4gbmV3IFAuRG4odCxyLHAscSxvLG0sbC5yKX0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHM9dGhp
-cy54CmlmKHMhPW51bGwpcmV0dXJuIHMKdD10aGlzLmUKaWYodC5sZW5ndGghPT0wJiZDLnhCLlcodCww
-KT09PTQ3KXQ9Qy54Qi5HKHQsMSkKcz10PT09IiI/Qy54RDpQLkFGKG5ldyBILmxKKEguVk0odC5zcGxp
-dCgiLyIpLHUucyksdS5kTy5hKFAuUEgoKSksdS5kbyksdS5OKQp0aGlzLnNvNihzKQpyZXR1cm4gc30s
-CmdoWTpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcwppZihzLlE9PW51bGwpe3Q9cy5mCnMuc1JIKG5ldyBQ
-LkdqKFAuV1godD09bnVsbD8iIjp0KSx1LmR3KSl9cmV0dXJuIHMuUX0sCkpoOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscyxyLHEscCxvCmZvcih0PTAscz0wO0MueEIuUWkoYiwiLi4vIixzKTspe3MrPTM7Kyt0fXI9
-Qy54Qi5jbihhLCIvIikKd2hpbGUoITApe2lmKCEocj4wJiZ0PjApKWJyZWFrCnE9Qy54Qi5QayhhLCIv
-IixyLTEpCmlmKHE8MClicmVhawpwPXItcQpvPXAhPT0yCmlmKCFvfHxwPT09MylpZihDLnhCLm0oYSxx
-KzEpPT09NDYpbz0hb3x8Qy54Qi5tKGEscSsyKT09PTQ2CmVsc2Ugbz0hMQplbHNlIG89ITEKaWYobyli
-cmVhazstLXQKcj1xfXJldHVybiBDLnhCLmk3KGEscisxLG51bGwsQy54Qi5HKGIscy0zKnQpKX0sClpJ
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24oYSl7dmFyIHQs
-cyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPW51bGwKaWYoYS5nRmkoKS5sZW5ndGghPT0wKXt0PWEuZ0Zp
-KCkKaWYoYS5nY2ooKSl7cz1hLmdrdSgpCnI9YS5nSmYoYSkKcT1hLmd4QSgpP2EuZ3RwKGEpOmp9ZWxz
-ZXtxPWoKcj1xCnM9IiJ9cD1QLnhlKGEuZ0lpKGEpKQpvPWEuZ1FEKCk/YS5ndFAoKTpqfWVsc2V7dD1r
-LmEKaWYoYS5nY2ooKSl7cz1hLmdrdSgpCnI9YS5nSmYoYSkKcT1QLndCKGEuZ3hBKCk/YS5ndHAoYSk6
-aix0KQpwPVAueGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UCgpOmp9ZWxzZXtzPWsuYgpyPWsuYwpx
-PWsuZAppZihhLmdJaShhKT09PSIiKXtwPWsuZQpvPWEuZ1FEKCk/YS5ndFAoKTprLmZ9ZWxzZXtpZihh
-Lmd0VCgpKXA9UC54ZShhLmdJaShhKSkKZWxzZXtuPWsuZQppZihuLmxlbmd0aD09PTApaWYocj09bnVs
-bClwPXQubGVuZ3RoPT09MD9hLmdJaShhKTpQLnhlKGEuZ0lpKGEpKQplbHNlIHA9UC54ZSgiLyIrYS5n
-SWkoYSkpCmVsc2V7bT1rLkpoKG4sYS5nSWkoYSkpCmw9dC5sZW5ndGg9PT0wCmlmKCFsfHxyIT1udWxs
-fHxDLnhCLm4obiwiLyIpKXA9UC54ZShtKQplbHNlIHA9UC53RihtLCFsfHxyIT1udWxsKX19bz1hLmdR
-RCgpP2EuZ3RQKCk6an19fXJldHVybiBuZXcgUC5Ebih0LHMscixxLHAsbyxhLmdaOCgpP2EuZ0thKCk6
-ail9LApnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jIT1udWxsfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
-dXJuIHRoaXMuZCE9bnVsbH0sCmdRRDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmYhPW51bGx9LApnWjg6
-ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yIT1udWxsfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIu
-bih0aGlzLmUsIi8iKX0sCnQ0OmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMscT1yLmEKaWYocSE9PSIi
-JiZxIT09ImZpbGUiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9t
-IGEgIitILmQocSkrIiBVUkkiKSkKcT1yLmYKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0aHJvdyBILmIo
-UC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgcXVlcnkgY29t
-cG9uZW50IikpCnE9ci5yCmlmKChxPT1udWxsPyIiOnEpIT09IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5v
-dCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNvbXBvbmVudCIp
-KQp0PSQuT3goKQppZihILm9UKHQpKXE9UC5tbihyKQplbHNle2lmKHIuYyE9bnVsbCYmci5nSmYocikh
-PT0iIilILnZoKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZyb20g
-YSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0eSIpKQpzPXIuZ0ZqKCkKUC5rRShzLCExKQpxPVAudmco
-Qy54Qi5uKHIuZSwiLyIpPyIvIjoiIixzLCIvIikKcT1xLmNoYXJDb2RlQXQoMCk9PTA/cTpxfXJldHVy
-biBxfSwKWjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9cS55CmlmKHA9PW51bGwpe3A9cS5h
-CnQ9cC5sZW5ndGghPT0wP3ArIjoiOiIiCnM9cS5jCnI9cz09bnVsbAppZighcnx8cD09PSJmaWxlIil7
-cD10KyIvLyIKdD1xLmIKaWYodC5sZW5ndGghPT0wKXA9cCt0KyJAIgppZighcilwKz1zCnQ9cS5kCmlm
-KHQhPW51bGwpcD1wKyI6IitILmQodCl9ZWxzZSBwPXQKcCs9cS5lCnQ9cS5mCmlmKHQhPW51bGwpcD1w
-KyI/Iit0CnQ9cS5yCmlmKHQhPW51bGwpcD1wKyIjIit0CnA9cS55PXAuY2hhckNvZGVBdCgwKT09MD9w
-OnB9cmV0dXJuIHB9LApETjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzCmlmKGI9PW51bGwpcmV0
-dXJuITEKaWYocj09PWIpcmV0dXJuITAKaWYodS5kRC5iKGIpKWlmKHIuYT09Yi5nRmkoKSlpZihyLmMh
-PW51bGw9PT1iLmdjaigpKWlmKHIuYj09Yi5na3UoKSlpZihyLmdKZihyKT09Yi5nSmYoYikpaWYoci5n
-dHAocik9PWIuZ3RwKGIpKWlmKHIuZT09PWIuZ0lpKGIpKXt0PXIuZgpzPXQ9PW51bGwKaWYoIXM9PT1i
-LmdRRCgpKXtpZihzKXQ9IiIKaWYodD09PWIuZ3RQKCkpe3Q9ci5yCnM9dD09bnVsbAppZighcz09PWIu
-Z1o4KCkpe2lmKHMpdD0iIgp0PXQ9PT1iLmdLYSgpfWVsc2UgdD0hMX1lbHNlIHQ9ITF9ZWxzZSB0PSEx
-fWVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSEx
-CmVsc2UgdD0hMQpyZXR1cm4gdH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLnoKcmV0dXJuIHQ9
-PW51bGw/dGhpcy56PUMueEIuZ2lPKHRoaXMuWigwKSk6dH0sCnNvNjpmdW5jdGlvbihhKXt0aGlzLng9
-dS5hLmEoYSl9LApzUkg6ZnVuY3Rpb24oYSl7dGhpcy5RPXUuZi5hKGEpfSwKJGlpRDoxLApnRmk6ZnVu
-Y3Rpb24oKXtyZXR1cm4gdGhpcy5hfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmV9fQpQLmUx
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Rocm93IEguYihQLnJyKCJJbnZhbGlkIHBvcnQiLHRo
-aXMuYSx0aGlzLmIrMSkpfSwKJFM6MTV9ClAuTlkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHQ9IklsbGVnYWwgcGF0aCBjaGFyYWN0ZXIgIgpILmMoYSkKaWYoSi56bChhLCIvIikpaWYodGhpcy5h
-KXRocm93IEguYihQLnhZKHQrYSkpCmVsc2UgdGhyb3cgSC5iKFAuTDQodCthKSl9LAokUzoxNX0KUC5S
-Wi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gUC5lUChDLlpKLEguYyhhKSxDLnhNLCEx
-KX0sCiRTOjV9ClAuTUUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmIscz10
-aGlzLmEKdC5hKz1zLmEKcy5hPSImIgpzPXQuYSs9SC5kKFAuZVAoQy5GMyxhLEMueE0sITApKQppZihi
-IT1udWxsJiZiLmxlbmd0aCE9PTApe3QuYT1zKyI9Igp0LmErPUguZChQLmVQKEMuRjMsYixDLnhNLCEw
-KSl9fSwKJFM6MjJ9ClAueTUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkguYyhh
-KQppZihiPT1udWxsfHx0eXBlb2YgYj09InN0cmluZyIpdGhpcy5hLiQyKGEsSC5jKGIpKQplbHNlIGZv
-cih0PUouSVQodS5SLmEoYikpLHM9dGhpcy5hO3QuRigpOylzLiQyKGEsSC5jKHQuZ2woKSkpfSwKJFM6
-MTR9ClAuUEUucHJvdG90eXBlPXsKZ2xSOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89bnVs
-bCxuPXAuYwppZihuIT1udWxsKXJldHVybiBuCm49cC5iCmlmKDA+PW4ubGVuZ3RoKXJldHVybiBILmso
-biwwKQp0PXAuYQpuPW5bMF0rMQpzPUMueEIuWFUodCwiPyIsbikKcj10Lmxlbmd0aAppZihzPj0wKXtx
-PVAuUEkodCxzKzEscixDLlZDLCExKQpyPXN9ZWxzZSBxPW8KcmV0dXJuIHAuYz1uZXcgUC5xZSgiZGF0
-YSIsbyxvLG8sUC5QSSh0LG4scixDLldkLCExKSxxLG8pfSwKWjpmdW5jdGlvbihhKXt2YXIgdCxzPXRo
-aXMuYgppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5rKHMsMCkKdD10aGlzLmEKcmV0dXJuIHNbMF09PT0t
-MT8iZGF0YToiK3Q6dH19ClAucTMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBV
-aW50OEFycmF5KDk2KX0sCiRTOjIzfQpQLnlJLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFy
-IHQ9dGhpcy5hCmlmKGE+PXQubGVuZ3RoKXJldHVybiBILmsodCxhKQp0PXRbYV0KSi5DTSh0LDAsOTYs
-YikKcmV0dXJuIHR9LAokUzoyNH0KUC5jNi5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFy
-IHQscyxyLHEKZm9yKHQ9Yi5sZW5ndGgscz1hLmxlbmd0aCxyPTA7cjx0Oysrcil7cT1DLnhCLlcoYixy
-KV45NgppZihxPj1zKXJldHVybiBILmsoYSxxKQphW3FdPWN9fX0KUC5xZC5wcm90b3R5cGU9ewokMzpm
-dW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKZm9yKHQ9Qy54Qi5XKGIsMCkscz1DLnhCLlcoYiwxKSxy
-PWEubGVuZ3RoO3Q8PXM7Kyt0KXtxPSh0Xjk2KT4+PjAKaWYocT49cilyZXR1cm4gSC5rKGEscSkKYVtx
-XT1jfX19ClAuVWYucHJvdG90eXBlPXsKZ2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYz4wfSwKZ3hB
-OmZ1bmN0aW9uKCl7dmFyIHQscwppZih0aGlzLmM+MCl7dD10aGlzLmQKaWYodHlwZW9mIHQhPT0ibnVt
-YmVyIilyZXR1cm4gdC5oKCkKcz10aGlzLmUKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gSC5w
-WShzKQpzPXQrMTxzCnQ9c31lbHNlIHQ9ITEKcmV0dXJuIHR9LApnUUQ6ZnVuY3Rpb24oKXt2YXIgdD10
-aGlzLmYKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5KKCkKcmV0dXJuIHQ8dGhpcy5yfSwK
-Z1o4OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucjx0aGlzLmEubGVuZ3RofSwKZ053OmZ1bmN0aW9uKCl7
-cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubih0aGlzLmEsImZpbGUiKX0sCmd2aDpmdW5jdGlvbigpe3Jl
-dHVybiB0aGlzLmI9PT00JiZDLnhCLm4odGhpcy5hLCJodHRwIil9LApnUmU6ZnVuY3Rpb24oKXtyZXR1
-cm4gdGhpcy5iPT09NSYmQy54Qi5uKHRoaXMuYSwiaHR0cHMiKX0sCmd0VDpmdW5jdGlvbigpe3JldHVy
-biBDLnhCLlFpKHRoaXMuYSwiLyIsdGhpcy5lKX0sCmdGaTpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxy
-PSJwYWNrYWdlIixxPXMuYgppZihxPD0wKXJldHVybiIiCnQ9cy54CmlmKHQhPW51bGwpcmV0dXJuIHQK
-aWYocy5ndmgoKSlxPXMueD0iaHR0cCIKZWxzZSBpZihzLmdSZSgpKXtzLng9Imh0dHBzIgpxPSJodHRw
-cyJ9ZWxzZSBpZihzLmdOdygpKXtzLng9ImZpbGUiCnE9ImZpbGUifWVsc2UgaWYocT09PTcmJkMueEIu
-bihzLmEscikpe3MueD1yCnE9cn1lbHNle3E9Qy54Qi5OaihzLmEsMCxxKQpzLng9cX1yZXR1cm4gcX0s
-CmdrdTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYyxzPXRoaXMuYiszCnJldHVybiB0PnM/Qy54Qi5Oaih0
-aGlzLmEscyx0LTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpyZXR1cm4gdD4wP0Mu
-eEIuTmoodGhpcy5hLHQsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMKaWYo
-cy5neEEoKSl7dD1zLmQKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5oKCkKcmV0dXJuIFAu
-UUEoQy54Qi5OaihzLmEsdCsxLHMuZSksbnVsbCxudWxsKX1pZihzLmd2aCgpKXJldHVybiA4MAppZihz
-LmdSZSgpKXJldHVybiA0NDMKcmV0dXJuIDB9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIuTmoo
-dGhpcy5hLHRoaXMuZSx0aGlzLmYpfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mLHM9dGhpcy5y
-CmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCnJldHVybiB0PHM/Qy54Qi5Oaih0aGlz
-LmEsdCsxLHMpOiIifSwKZ0thOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5yLHM9dGhpcy5hCnJldHVybiB0
-PHMubGVuZ3RoP0MueEIuRyhzLHQrMSk6IiJ9LApnRmo6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5l
-LHE9dGhpcy5mLHA9dGhpcy5hCmlmKEMueEIuUWkocCwiLyIscikpe2lmKHR5cGVvZiByIT09Im51bWJl
-ciIpcmV0dXJuIHIuaCgpOysrcn1pZihyPT1xKXJldHVybiBDLnhECnQ9SC5WTShbXSx1LnMpCnM9cgp3
-aGlsZSghMCl7aWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5KKCkKaWYodHlwZW9mIHEhPT0i
-bnVtYmVyIilyZXR1cm4gSC5wWShxKQppZighKHM8cSkpYnJlYWsKaWYoQy54Qi5tKHAscyk9PT00Nyl7
-Qy5ObS5pKHQsQy54Qi5OaihwLHIscykpCnI9cysxfSsrc31DLk5tLmkodCxDLnhCLk5qKHAscixxKSkK
-cmV0dXJuIFAuQUYodCx1Lk4pfSwKZ2hZOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mCmlmKHR5cGVvZiB0
-IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ+PXRoaXMucilyZXR1cm4gQy5XTwpyZXR1cm4gbmV3
-IFAuR2ooUC5XWCh0aGlzLmd0UCgpKSx1LmR3KX0sCmtYOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5k
-CmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuaCgpCnQ9cysxCnJldHVybiB0K2EubGVuZ3Ro
-PT09dGhpcy5lJiZDLnhCLlFpKHRoaXMuYSxhLHQpfSwKTjk6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9
-dC5yLHI9dC5hCmlmKHM+PXIubGVuZ3RoKXJldHVybiB0CnJldHVybiBuZXcgUC5VZihDLnhCLk5qKHIs
-MCxzKSx0LmIsdC5jLHQuZCx0LmUsdC5mLHMsdC54KX0sCm5tOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
-LHEscCxvLG4sbSxsLGssaj10aGlzLGk9bnVsbAp1LlguYShudWxsKQp1LmIuYShiKQp0PWouZ0ZpKCkK
-cz10PT09ImZpbGUiCnI9ai5jCnE9cj4wP0MueEIuTmooai5hLGouYiszLHIpOiIiCnA9ai5neEEoKT9q
-Lmd0cChqKTppCnI9ai5jCmlmKHI+MClvPUMueEIuTmooai5hLHIsai5kKQplbHNlIG89cS5sZW5ndGgh
-PT0wfHxwIT1udWxsfHxzPyIiOmkKcj1qLmEKbj1DLnhCLk5qKHIsai5lLGouZikKaWYoIXMpbT1vIT1u
-dWxsJiZuLmxlbmd0aCE9PTAKZWxzZSBtPSEwCmlmKG0mJiFDLnhCLm4obiwiLyIpKW49Ii8iK24KbD1Q
-LmxlKGksMCwwLGIpCm09ai5yCms9bTxyLmxlbmd0aD9DLnhCLkcocixtKzEpOmkKcmV0dXJuIG5ldyBQ
-LkRuKHQscSxvLHAsbixsLGspfSwKWkk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9
-LAptUzpmdW5jdGlvbihhKXtpZihhIGluc3RhbmNlb2YgUC5VZilyZXR1cm4gdGhpcy51MSh0aGlzLGEp
-CnJldHVybiB0aGlzLnZzKCkubVMoYSl9LAp1MTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxu
-LG0sbCxrLGosaSxoLGcsZixlPWIuYgppZihlPjApcmV0dXJuIGIKdD1iLmMKaWYodD4wKXtzPWEuYgpp
-ZihzPD0wKXJldHVybiBiCmlmKGEuZ053KCkpcj1iLmUhPWIuZgplbHNlIGlmKGEuZ3ZoKCkpcj0hYi5r
-WCgiODAiKQplbHNlIHI9IWEuZ1JlKCl8fCFiLmtYKCI0NDMiKQppZihyKXtxPXMrMQpwPUMueEIuTmoo
-YS5hLDAscSkrQy54Qi5HKGIuYSxlKzEpCmU9Yi5kCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJu
-IGUuaCgpCm89Yi5lCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8uaCgpCm49Yi5mCmlmKHR5
-cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4uaCgpCnJldHVybiBuZXcgUC5VZihwLHMsdCtxLGUrcSxv
-K3EsbitxLGIucitxLGEueCl9ZWxzZSByZXR1cm4gdGhpcy52cygpLm1TKGIpfW09Yi5lCmU9Yi5mCmlm
-KG09PWUpe3Q9Yi5yCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuSigpCmlmKGU8dCl7cz1h
-LmYKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5ITigpCnE9cy1lCnJldHVybiBuZXcgUC5V
-ZihDLnhCLk5qKGEuYSwwLHMpK0MueEIuRyhiLmEsZSksYS5iLGEuYyxhLmQsYS5lLGUrcSx0K3EsYS54
-KX1lPWIuYQppZih0PGUubGVuZ3RoKXtzPWEucgpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxz
-KStDLnhCLkcoZSx0KSxhLmIsYS5jLGEuZCxhLmUsYS5mLHQrKHMtdCksYS54KX1yZXR1cm4gYS5OOSgp
-fXQ9Yi5hCmlmKEMueEIuUWkodCwiLyIsbSkpe3M9YS5lCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0
-dXJuIHMuSE4oKQppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCnE9cy1tCnA9Qy54
-Qi5OaihhLmEsMCxzKStDLnhCLkcodCxtKQppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgo
-KQpyZXR1cm4gbmV3IFAuVWYocCxhLmIsYS5jLGEuZCxzLGUrcSxiLnIrcSxhLngpfWw9YS5lCms9YS5m
-CmlmKGw9PWsmJmEuYz4wKXtmb3IoO0MueEIuUWkodCwiLi4vIixtKTspe2lmKHR5cGVvZiBtIT09Im51
-bWJlciIpcmV0dXJuIG0uaCgpCm0rPTN9aWYodHlwZW9mIGwhPT0ibnVtYmVyIilyZXR1cm4gbC5ITigp
-CmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIEgucFkobSkKcT1sLW0rMQpwPUMueEIuTmooYS5h
-LDAsbCkrIi8iK0MueEIuRyh0LG0pCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCnJl
-dHVybiBuZXcgUC5VZihwLGEuYixhLmMsYS5kLGwsZStxLGIucitxLGEueCl9aj1hLmEKZm9yKGk9bDtD
-LnhCLlFpKGosIi4uLyIsaSk7KXtpZih0eXBlb2YgaSE9PSJudW1iZXIiKXJldHVybiBpLmgoKQppKz0z
-fWg9MAp3aGlsZSghMCl7aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5oKCkKZz1tKzMKaWYo
-dHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShlKQppZighKGc8PWUmJkMueEIuUWkodCwiLi4v
-IixtKSkpYnJlYWs7KytoCm09Z31mPSIiCndoaWxlKCEwKXtpZih0eXBlb2YgayE9PSJudW1iZXIiKXJl
-dHVybiBrLm9zKCkKaWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShpKQppZighKGs+aSkp
-YnJlYWs7LS1rCmlmKEMueEIubShqLGspPT09NDcpe2lmKGg9PT0wKXtmPSIvIgpicmVha30tLWgKZj0i
-LyJ9fWlmKGs9PT1pJiZhLmI8PTAmJiFDLnhCLlFpKGosIi8iLGwpKXttLT1oKjMKZj0iIn1xPWstbStm
-Lmxlbmd0aApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihqLDAsaykrZitDLnhCLkcodCxtKSxhLmIsYS5j
-LGEuZCxsLGUrcSxiLnIrcSxhLngpfSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMKaWYo
-cC5iPj0wJiYhcC5nTncoKSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGgg
-ZnJvbSBhICIrSC5kKHAuZ0ZpKCkpKyIgVVJJIikpCnQ9cC5mCnM9cC5hCmlmKHR5cGVvZiB0IT09Im51
-bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ8cy5sZW5ndGgpe2lmKHQ8cC5yKXRocm93IEguYihQLkw0KCJD
-YW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQi
-KSkKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0
-aCBhIGZyYWdtZW50IGNvbXBvbmVudCIpKX1yPSQuT3goKQppZihILm9UKHIpKXQ9UC5tbihwKQplbHNl
-e3E9cC5kCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIEgucFkocSkKaWYocC5jPHEpSC52aChQ
-Lkw0KCJDYW5ub3QgZXh0cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkg
-d2l0aCBhbiBhdXRob3JpdHkiKSkKdD1DLnhCLk5qKHMscC5lLHQpfXJldHVybiB0fSwKZ2lPOmZ1bmN0
-aW9uKGEpe3ZhciB0PXRoaXMueQpyZXR1cm4gdD09bnVsbD90aGlzLnk9Qy54Qi5naU8odGhpcy5hKTp0
-fSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCmlmKHRoaXM9PT1iKXJldHVybiEw
-CnJldHVybiB1LmRELmIoYikmJnRoaXMuYT09PWIuWigwKX0sCnZzOmZ1bmN0aW9uKCl7dmFyIHQ9dGhp
-cyxzPW51bGwscj10LmdGaSgpLHE9dC5na3UoKSxwPXQuYz4wP3QuZ0pmKHQpOnMsbz10Lmd4QSgpP3Qu
-Z3RwKHQpOnMsbj10LmEsbT10LmYsbD1DLnhCLk5qKG4sdC5lLG0pLGs9dC5yCmlmKHR5cGVvZiBtIT09
-Im51bWJlciIpcmV0dXJuIG0uSigpCm09bTxrP3QuZ3RQKCk6cwpyZXR1cm4gbmV3IFAuRG4ocixxLHAs
-byxsLG0sazxuLmxlbmd0aD90LmdLYSgpOnMpfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwK
-JGlpRDoxfQpQLnFlLnByb3RvdHlwZT17fQpXLnFFLnByb3RvdHlwZT17fQpXLkdoLnByb3RvdHlwZT17
-Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpR2g6MX0KVy5mWS5wcm90b3R5cGU9ewpa
-OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9fQpXLm5CLnByb3RvdHlwZT17JGluQjoxfQpXLkF6
-LnByb3RvdHlwZT17JGlBejoxfQpXLlFQLnByb3RvdHlwZT17JGlRUDoxfQpXLm54LnByb3RvdHlwZT17
-CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19Clcub0oucHJvdG90eXBlPXsKZ0E6ZnVuY3Rp
-b24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5pZC5wcm90b3R5cGU9e30KVy5RRi5wcm90b3R5cGU9e30K
-Vy5OaC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9fQpXLklCLnByb3Rv
-dHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIlJlY3RhbmdsZSAoIitILmQoYS5sZWZ0KSsiLCAiK0gu
-ZChhLnRvcCkrIikgIitILmQoYS53aWR0aCkrIiB4ICIrSC5kKGEuaGVpZ2h0KX0sCkROOmZ1bmN0aW9u
-KGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5PLmIoYikmJmEubGVmdD09Yi5sZWZ0JiZh
-LnRvcD09Yi50b3AmJmEud2lkdGg9PWIud2lkdGgmJmEuaGVpZ2h0PT1iLmhlaWdodH0sCmdpTzpmdW5j
-dGlvbihhKXtyZXR1cm4gVy5yRShKLmhmKGEubGVmdCksSi5oZihhLnRvcCksSi5oZihhLndpZHRoKSxK
-LmhmKGEuaGVpZ2h0KSl9LAokaXRuOjF9ClcubjcucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RofX0KVy53ei5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
-Lmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILldZKGIpCnQ9dGhpcy5hCmlmKGI8MHx8Yj49
-dC5sZW5ndGgpcmV0dXJuIEguayh0LGIpCnJldHVybiB0aGlzLiR0aS5jLmEodFtiXSl9LApZOmZ1bmN0
-aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlz
-dCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhhKX0s
-CmdQOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0sCnNQOmZ1bmN0aW9uKGEsYil7dmFyIHQK
-dS5YLmEoYikKdD10aGlzLmdQKGEpCnQuVjEoMCkKdC5GVigwLGIpfSwKWjpmdW5jdGlvbihhKXtyZXR1
-cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlvbihhKXt2YXIgdD0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5l
-ZWRlZAppZih0KWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmlldygp
-fSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNoKGIu
-dG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmViZWdpbiI6YS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShz
-LGEpCmJyZWFrCmNhc2UiYWZ0ZXJiZWdpbiI6dD1hLmNoaWxkTm9kZXMKYS5pbnNlcnRCZWZvcmUocyx0
-Lmxlbmd0aD4wP3RbMF06bnVsbCkKYnJlYWsKY2FzZSJiZWZvcmVlbmQiOmEuYXBwZW5kQ2hpbGQocykK
-YnJlYWsKY2FzZSJhZnRlcmVuZCI6YS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzLGEubmV4dFNpYmxp
-bmcpCmJyZWFrCmRlZmF1bHQ6SC52aChQLnhZKCJJbnZhbGlkIHBvc2l0aW9uICIrYikpfX0sCnI2OmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKGM9PW51bGwpe2lmKGQ9PW51bGwpe3Q9JC5sdApp
-Zih0PT1udWxsKXt0PUguVk0oW10sdS5rKQpzPW5ldyBXLnZEKHQpCkMuTm0uaSh0LFcuVHcobnVsbCkp
-CkMuTm0uaSh0LFcuQmwoKSkKJC5sdD1zCmQ9c31lbHNlIGQ9dH10PSQuRVUKaWYodD09bnVsbCl7dD1u
-ZXcgVy5LbyhkKQokLkVVPXQKYz10fWVsc2V7dC5hPWQKYz10fX1lbHNlIGlmKGQhPW51bGwpdGhyb3cg
-SC5iKFAueFkoInZhbGlkYXRvciBjYW4gb25seSBiZSBwYXNzZWQgaWYgdHJlZVNhbml0aXplciBpcyBu
-dWxsIikpCmlmKCQueG89PW51bGwpe3Q9ZG9jdW1lbnQKcz10LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhU
-TUxEb2N1bWVudCgiIikKJC54bz1zCiQuQk89cy5jcmVhdGVSYW5nZSgpCnM9JC54by5jcmVhdGVFbGVt
-ZW50KCJiYXNlIikKdS5jUi5hKHMpCnMuaHJlZj10LmJhc2VVUkkKJC54by5oZWFkLmFwcGVuZENoaWxk
-KHMpfXQ9JC54bwppZih0LmJvZHk9PW51bGwpe3M9dC5jcmVhdGVFbGVtZW50KCJib2R5IikKdC5ib2R5
-PXUuaS5hKHMpfXQ9JC54bwppZih1LmkuYihhKSlyPXQuYm9keQplbHNle3I9dC5jcmVhdGVFbGVtZW50
-KGEudGFnTmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0dWFsRnJh
-Z21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdOYW1lKSl7
-JC5CTy5zZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChi
-KX1lbHNle3IuaW5uZXJIVE1MPWIKcT0kLnhvLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpmb3IoO3Q9
-ci5maXJzdENoaWxkLHQhPW51bGw7KXEuYXBwZW5kQ2hpbGQodCl9dD0kLnhvLmJvZHkKaWYocj09bnVs
-bD90IT1udWxsOnIhPT10KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkKcmV0dXJu
-IHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApzaGY6ZnVu
-Y3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29udGVudD1u
-dWxsCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIpe3Jl
-dHVybiB0aGlzLnBrKGEsYixudWxsKX0sCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1lfSwK
-Z1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdS5RKX0sCiRpY3Y6MX0K
-Vy5Ddi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmIodS5BLmEoYSkpfSwKJFM6
-MjF9ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rpb24oYSxi
-LGMsZCl7dS5VLmEoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9uKGEsYixj
-KXtyZXR1cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIGEu
-YWRkRXZlbnRMaXN0ZW5lcihiLEgudFIodS5VLmEoYyksMSksZCl9LAokaUQwOjF9ClcuVDUucHJvdG90
-eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3Ro
-fX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlZiLnBy
-b3RvdHlwZT17fQpXLmZKLnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBhLm9w
-ZW4oYixjLCEwKX0sCiRpZko6MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMu
-YS5zZXRSZXF1ZXN0SGVhZGVyKEguYyhhKSxILmMoYikpfSwKJFM6OX0KVy5oSC5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwCnUucC5hKGEpCnQ9dGhpcy5hCnM9dC5zdGF0dXMKaWYo
-dHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy50QigpCnI9cz49MjAwJiZzPDMwMApxPXM+MzA3JiZz
-PDQwMApzPXJ8fHM9PT0wfHxzPT09MzA0fHxxCnA9dGhpcy5iCmlmKHMpcC5hTSgwLHQpCmVsc2UgcC5w
-bShhKX0sCiRTOjE2fQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnByb3RvdHlwZT17JGlTZzoxfQpXLnU4
-LnByb3RvdHlwZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2luIiBpbiBhKXJldHVybiBhLm9yaWdp
-bgpyZXR1cm4gSC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9zdCl9LApaOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBTdHJpbmcoYSl9LAokaXU4OjF9ClcuT0sucHJvdG90eXBlPXskaU9LOjF9ClcuZTcucHJvdG90
-eXBlPXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5ndGgKaWYo
-cz09PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIoUC5QVigi
-TW9yZSB0aGFuIG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0Q2hpbGR9LApGVjpmdW5jdGlvbihh
-LGIpe3ZhciB0LHMscixxCnUuZWguYShiKQp0PWIuYQpzPXRoaXMuYQppZih0IT09cylmb3Iocj10LmNo
-aWxkTm9kZXMubGVuZ3RoLHE9MDtxPHI7KytxKXMuYXBwZW5kQ2hpbGQodC5maXJzdENoaWxkKQpyZXR1
-cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5hKGMpCnQ9dGhpcy5hCnM9dC5jaGlsZE5v
-ZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguayhzLGIpCnQucmVwbGFjZUNoaWxkKGMsc1ti
-XSl9LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmNoaWxkTm9kZXMKcmV0dXJuIG5ldyBXLlc5
-KHQsdC5sZW5ndGgsSC5xKHQpLkMoIlc5PEdtLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYS5jaGlsZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILldZKGIpCnQ9dGhp
-cy5hLmNoaWxkTm9kZXMKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikKcmV0dXJuIHRb
-Yl19fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEpe3ZhciB0PWEucGFyZW50Tm9kZQppZih0
-IT1udWxsKXQucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlvbihhKXt2YXIgdApmb3IoO3Q9YS5maXJz
-dENoaWxkLHQhPW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LApaOmZ1bmN0aW9uKGEpe3ZhciB0PWEubm9k
-ZVZhbHVlCnJldHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwKJGl1SDoxfQpXLkJILnByb3RvdHlwZT17
-CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCmlm
-KGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAudChiLGEsbnVsbCxudWxsLG51bGwpKQpy
-ZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5u
-b3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lm
-KGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguayhhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhq
-OjEsCiRpY1g6MSwKJGl6TToxfQpXLlNOLnByb3RvdHlwZT17fQpXLmV3LnByb3RvdHlwZT17JGlldzox
-fQpXLmxwLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuVGIucHJv
-dG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZigiY3JlYXRlQ29udGV4dHVhbEZy
-YWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9
-Vy5VOSgiPHRhYmxlPiIrSC5kKGIpKyI8L3RhYmxlPiIsYyxkKQpzPWRvY3VtZW50LmNyZWF0ZURvY3Vt
-ZW50RnJhZ21lbnQoKQpzLnRvU3RyaW5nCnQudG9TdHJpbmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5l
-Nyh0KSkKcmV0dXJuIHN9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0
-LHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5
-cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFn
-bWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9TdHJpbmcK
-dD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnIudG9TdHJpbmcKdD1uZXcgVy5lNyhyKQpxPXQuZ3I4KHQp
-CnMudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBXLmU3KHEpKQpyZXR1cm4g
-c319ClcuV1AucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmlmKCJjcmVh
-dGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMu
-RFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5y
-Nih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpy
-PXQuZ3I4KHQpCnMudG9TdHJpbmcKci50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBXLmU3KHIp
-KQpyZXR1cm4gc319ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKYS50
-ZXh0Q29udGVudD1udWxsCnQ9YS5jb250ZW50CnQudG9TdHJpbmcKSi5iVCh0KQpzPXRoaXMucjYoYSxi
-LG51bGwsYykKYS5jb250ZW50LmFwcGVuZENoaWxkKHMpfSwKWUM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-dGhpcy5wayhhLGIsbnVsbCl9LAokaXlZOjF9ClcudzYucHJvdG90eXBlPXt9ClcuSzUucHJvdG90eXBl
-PXsKUG86ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVcuUDEoYS5vcGVuKGIsYykpCnJldHVybiB0fSwKZ21X
-OmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2F0aW9ufSwKJGlLNToxLAokaXY2OjF9ClcuQ20ucHJvdG90
-eXBlPXskaUNtOjF9ClcuQ1EucHJvdG90eXBlPXskaUNROjF9ClcudzQucHJvdG90eXBlPXsKWjpmdW5j
-dGlvbihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAi
-K0guZChhLndpZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1u
-dWxsKXJldHVybiExCnJldHVybiB1Lk8uYihiKSYmYS5sZWZ0PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYm
-YS53aWR0aD09Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVy
-biBXLnJFKEouaGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhmKGEud2lkdGgpLEouaGYoYS5oZWlnaHQp
-KX19ClcucmgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5j
-dGlvbihhLGIpe0guV1koYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC50KGIs
-YSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7dS5BLmEoYykK
-dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9
-LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5rKGEsYikKcmV0dXJu
-IGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuY2YucHJvdG90eXBlPXsKSzpm
-dW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5lQS5hKGIpCmZvcih0PXRoaXMuZ1YoKSxzPXQubGVu
-Z3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtw
-PXRbcV0KYi4kMihwLHIuZ2V0QXR0cmlidXRlKHApKX19LApnVjpmdW5jdGlvbigpe3ZhciB0LHMscixx
-LHA9dGhpcy5hLmF0dHJpYnV0ZXMsbz1ILlZNKFtdLHUucykKZm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9
-MDtyPHQ7KytyKXtpZihyPj1wLmxlbmd0aClyZXR1cm4gSC5rKHAscikKcT1zLmEocFtyXSkKaWYocS5u
-YW1lc3BhY2VVUkk9PW51bGwpQy5ObS5pKG8scS5uYW1lKX1yZXR1cm4gb30sCmdsMDpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aD09PTB9fQpXLmk3LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9u
-KGEpe3JldHVybiB0aGlzLmEuaGFzQXR0cmlidXRlKGEpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0
-aGlzLmEuZ2V0QXR0cmlidXRlKEguYyhiKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0
-cmlidXRlKGIsYyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3ku
-cHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hLmhhc0F0dHJpYnV0ZSgiZGF0
-YS0iK3RoaXMuTyhhKSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5hLmdldEF0dHJpYnV0
-ZSgiZGF0YS0iK3RoaXMuTyhILmMoYikpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hLnNldEF0
-dHJpYnV0ZSgiZGF0YS0iK3RoaXMuTyhiKSxjKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLG5l
-dyBXLktTKHRoaXMsdS5lQS5hKGIpKSl9LApnVjpmdW5jdGlvbigpe3ZhciB0PUguVk0oW10sdS5zKQp0
-aGlzLmEuSygwLG5ldyBXLkEzKHRoaXMsdCkpCnJldHVybiB0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuZ1YoKS5sZW5ndGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGg9
-PT0wfSwKazpmdW5jdGlvbihhKXt2YXIgdCxzLHI9SC5WTShhLnNwbGl0KCItIiksdS5zKQpmb3IodD0x
-O3Q8ci5sZW5ndGg7Kyt0KXtzPXJbdF0KaWYocy5sZW5ndGg+MClDLk5tLlkocix0LHNbMF0udG9VcHBl
-ckNhc2UoKStKLktWKHMsMSkpfXJldHVybiBDLk5tLnpWKHIsIiIpfSwKTzpmdW5jdGlvbihhKXt2YXIg
-dCxzLHIscSxwCmZvcih0PWEubGVuZ3RoLHM9MCxyPSIiO3M8dDsrK3Mpe3E9YVtzXQpwPXEudG9Mb3dl
-ckNhc2UoKQpyPShxIT09cCYmcz4wP3IrIi0iOnIpK3B9cmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9y
-OnJ9fQpXLktTLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7aWYoSi5yWShhKS5uKGEsImRhdGEt
-IikpdGhpcy5iLiQyKHRoaXMuYS5rKEMueEIuRyhhLDUpKSxiKX0sCiRTOjl9ClcuQTMucHJvdG90eXBl
-PXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRo
-aXMuYS5rKEMueEIuRyhhLDUpKSl9LAokUzo5fQpXLkk0LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oKXt2
-YXIgdCxzLHIscSxwPVAuTHModS5OKQpmb3IodD10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscz10
-Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1KLlQwKHRbcl0pCmlmKHEubGVuZ3RoIT09MClwLmkoMCxxKX1y
-ZXR1cm4gcH0sCnA6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT11LkMuYShhKS56VigwLCIgIil9
-LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGh9LApWMTpmdW5jdGlv
-bihhKXt0aGlzLmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xh
-c3NMaXN0LmNvbnRhaW5zKGIpCnJldHVybiB0fSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5j
-bGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQuYWRkKGIpCnJldHVybiFzfSwKUjpmdW5jdGlvbihhLGIp
-e3ZhciB0PXRoaXMuYS5jbGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQucmVtb3ZlKGIpCnJldHVybiBz
-fSwKRlY6ZnVuY3Rpb24oYSxiKXtXLlROKHRoaXMuYSx1LlguYShiKSl9fQpXLkZrLnByb3RvdHlwZT17
-fQpXLlJPLnByb3RvdHlwZT17fQpXLmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3RvdHlwZT17fQpXLnZO
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodS5CLmEoYSkpfSwKJFM6
-Mjh9ClcuSlEucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoJC5vci5hPT09MCl7Zm9y
-KHQ9MDt0PDI2MjsrK3QpJC5vci5ZKDAsQy5jbVt0XSxXLnBTKCkpCmZvcih0PTA7dDwxMjsrK3QpJC5v
-ci5ZKDAsQy5CSVt0XSxXLlY0KCkpfX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiAkLkFOKCkudGcoMCxX
-LnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD0kLm9yLnEoMCxILmQoVy5yUyhhKSkrIjo6
-IitiKQppZih0PT1udWxsKXQ9JC5vci5xKDAsIio6OiIrYikKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1
-cm4gSC5FOSh0LiQ0KGEsYixjLHRoaXMpKX0sCiRpa0Y6MX0KVy5HbS5wcm90b3R5cGU9ewpna3o6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIG5ldyBXLlc5KGEsdGhpcy5nQShhKSxILnEoYSkuQygiVzk8R20uRT4iKSl9
-fQpXLnZELnByb3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcg
-Vy5VdihhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLkVn
-KGEsYixjKSl9LAokaWtGOjF9ClcuVXYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUu
-ZS5hKGEpLmkwKHRoaXMuYSl9LAokUzoxN30KVy5FZy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXty
-ZXR1cm4gdS5lLmEoYSkuRWIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MTd9ClcubTYucHJvdG90
-eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCnRoaXMuYS5GVigwLGMpCnQ9Yi5ldigw
-LG5ldyBXLkVvKCkpCnM9Yi5ldigwLG5ldyBXLldrKCkpCnRoaXMuYi5GVigwLHQpCnI9dGhpcy5jCnIu
-RlYoMCxDLnhEKQpyLkZWKDAscyl9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLnRnKDAsVy5y
-UyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9dGhpcyxzPVcuclMoYSkscj10LmMKaWYoci50
-ZygwLEguZChzKSsiOjoiK2IpKXJldHVybiB0LmQuRHQoYykKZWxzZSBpZihyLnRnKDAsIio6OiIrYikp
-cmV0dXJuIHQuZC5EdChjKQplbHNle3I9dC5iCmlmKHIudGcoMCxILmQocykrIjo6IitiKSlyZXR1cm4h
-MAplbHNlIGlmKHIudGcoMCwiKjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCxILmQocykrIjo6
-KiIpKXJldHVybiEwCmVsc2UgaWYoci50ZygwLCIqOjoqIikpcmV0dXJuITB9cmV0dXJuITF9LAokaWtG
-OjF9ClcuRW8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIUMuTm0udGcoQy5CSSxILmMo
-YSkpfSwKJFM6N30KVy5Xay5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS50ZyhD
-LkJJLEguYyhhKSl9LAokUzo3fQpXLmN0LnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtpZih0
-aGlzLmpGKGEsYixjKSlyZXR1cm4hMAppZihiPT09InRlbXBsYXRlIiYmYz09PSIiKXJldHVybiEwCmlm
-KGEuZ2V0QXR0cmlidXRlKCJ0ZW1wbGF0ZSIpPT09IiIpcmV0dXJuIHRoaXMuZS50ZygwLGIpCnJldHVy
-biExfX0KVy5JQS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4iVEVNUExBVEU6OiIrSC5k
-KEguYyhhKSl9LAokUzo1fQpXLk93LnByb3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUu
-ZXcuYihhKSlyZXR1cm4hMQp0PXUuZzcuYihhKQppZih0JiZXLnJTKGEpPT09ImZvcmVpZ25PYmplY3Qi
-KXJldHVybiExCmlmKHQpcmV0dXJuITAKcmV0dXJuITF9LApFYjpmdW5jdGlvbihhLGIsYyl7aWYoYj09
-PSJpcyJ8fEMueEIubihiLCJvbiIpKXJldHVybiExCnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpX
-Llc5LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5jKzEscj10LmIKaWYoczxy
-KXt0LnNNKEoueDkodC5hLHMpKQp0LmM9cwpyZXR1cm4hMH10LnNNKG51bGwpCnQuYz1yCnJldHVybiEx
-fSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKc006ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMu
-JHRpLmMuYShhKX0sCiRpQW46MX0KVy5kVy5wcm90b3R5cGU9ewpnbVc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IFcuSEgodGhpcy5hLmxvY2F0aW9uKX0sCiRpRDA6MSwKJGl2NjoxfQpXLkZiLnByb3RvdHlwZT17fQpX
-LmtGLnByb3RvdHlwZT17fQpXLm1rLnByb3RvdHlwZT17JGl5MDoxfQpXLktvLnByb3RvdHlwZT17ClBu
-OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1uZXcgVy5mbSh0KQp0LmI9ITEKcy4kMihhLG51bGwpCmZv
-cig7dC5iOyl7dC5iPSExCnMuJDIoYSxudWxsKX19LApFUDpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMu
-Yj0hMAppZihiIT1udWxsP2IhPT1hLnBhcmVudE5vZGU6dClKLkx0KGEpCmVsc2UgYi5yZW1vdmVDaGls
-ZChhKX0sCkk0OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPSEwLG49bnVsbCxtPW51bGwKdHJ5
-e249Si5pZyhhKQptPW4uYS5nZXRBdHRyaWJ1dGUoImlzIikKdS5oLmEoYSkKdD1mdW5jdGlvbihjKXtp
-ZighKGMuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkpcmV0dXJuIHRydWUKaWYoYy5p
-ZD09J2xhc3RDaGlsZCd8fGMubmFtZT09J2xhc3RDaGlsZCd8fGMuaWQ9PSdwcmV2aW91c1NpYmxpbmcn
-fHxjLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcnfHxjLmlkPT0nY2hpbGRyZW4nfHxjLm5hbWU9PSdjaGls
-ZHJlbicpcmV0dXJuIHRydWUKdmFyIGw9Yy5jaGlsZE5vZGVzCmlmKGMubGFzdENoaWxkJiZjLmxhc3RD
-aGlsZCE9PWxbbC5sZW5ndGgtMV0pcmV0dXJuIHRydWUKaWYoYy5jaGlsZHJlbilpZighKGMuY2hpbGRy
-ZW4gaW5zdGFuY2VvZiBIVE1MQ29sbGVjdGlvbnx8Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIE5vZGVMaXN0
-KSlyZXR1cm4gdHJ1ZQp2YXIgaz0wCmlmKGMuY2hpbGRyZW4paz1jLmNoaWxkcmVuLmxlbmd0aApmb3Io
-dmFyIGo9MDtqPGs7aisrKXt2YXIgaT1jLmNoaWxkcmVuW2pdCmlmKGkuaWQ9PSdhdHRyaWJ1dGVzJ3x8
-aS5uYW1lPT0nYXR0cmlidXRlcyd8fGkuaWQ9PSdsYXN0Q2hpbGQnfHxpLm5hbWU9PSdsYXN0Q2hpbGQn
-fHxpLmlkPT0ncHJldmlvdXNTaWJsaW5nJ3x8aS5uYW1lPT0ncHJldmlvdXNTaWJsaW5nJ3x8aS5pZD09
-J2NoaWxkcmVuJ3x8aS5uYW1lPT0nY2hpbGRyZW4nKXJldHVybiB0cnVlfXJldHVybiBmYWxzZX0oYSkK
-bz1ILm9UKHQpPyEwOiEoYS5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKX1jYXRjaChx
-KXtILlJ1KHEpfXM9ImVsZW1lbnQgdW5wcmludGFibGUiCnRyeXtzPUouQWMoYSl9Y2F0Y2gocSl7SC5S
-dShxKX10cnl7cj1XLnJTKGEpCnRoaXMua1IodS5oLmEoYSksYixvLHMscix1LkcuYShuKSxILmMobSkp
-fWNhdGNoKHEpe2lmKEguUnUocSkgaW5zdGFuY2VvZiBQLkFUKXRocm93IHEKZWxzZXt0aGlzLkVQKGEs
-YikKd2luZG93CnA9IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5kKHMpCmlmKHR5cGVvZiBj
-b25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApfX19LAprUjpmdW5jdGlvbihh
-LGIsYyxkLGUsZixnKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzCmlmKGMpe24uRVAoYSxiKQp3aW5kb3cK
-dD0iUmVtb3ZpbmcgZWxlbWVudCBkdWUgdG8gY29ycnVwdGVkIGF0dHJpYnV0ZXMgb24gPCIrZCsiPiIK
-aWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJu
-fWlmKCFuLmEuaTAoYSkpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBlbGVt
-ZW50IDwiK0guZChlKSsiPiBmcm9tICIrSC5kKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVk
-Iil3aW5kb3cuY29uc29sZS53YXJuKHQpCnJldHVybn1pZihnIT1udWxsKWlmKCFuLmEuRWIoYSwiaXMi
-LGcpKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24g
-PCIrSC5kKGUpKycgaXM9IicrZysnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5k
-b3cuY29uc29sZS53YXJuKHQpCnJldHVybn10PWYuZ1YoKQpzPUguVk0odC5zbGljZSgwKSxILnQ2KHQp
-LkMoImpkPDE+IikpCmZvcihyPWYuZ1YoKS5sZW5ndGgtMSx0PWYuYTtyPj0wOy0tcil7aWYocj49cy5s
-ZW5ndGgpcmV0dXJuIEguayhzLHIpCnE9c1tyXQpwPW4uYQpvPUouY0gocSkKSC5jKHEpCmlmKCFwLkVi
-KGEsbyx0LmdldEF0dHJpYnV0ZShxKSkpe3dpbmRvdwpwPSJSZW1vdmluZyBkaXNhbGxvd2VkIGF0dHJp
-YnV0ZSA8IitILmQoZSkrIiAiK3ErJz0iJytILmQodC5nZXRBdHRyaWJ1dGUocSkpKyciPicKaWYodHlw
-ZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocCkKdC5yZW1vdmVBdHRy
-aWJ1dGUocSl9fWlmKHUuYVcuYihhKSluLlBuKGEuY29udGVudCl9LAokaW9uOjF9ClcuZm0ucHJvdG90
-eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLmEKc3dpdGNoKGEubm9k
-ZVR5cGUpe2Nhc2UgMTpuLkk0KGEsYikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6Y2FzZSAzOmNhc2UgNDpi
-cmVhawpkZWZhdWx0Om4uRVAoYSxiKX10PWEubGFzdENoaWxkCmZvcihyPXUuQTtudWxsIT10Oyl7cz1u
-dWxsCnRyeXtzPXQucHJldmlvdXNTaWJsaW5nCmlmKHMhPW51bGwpe3E9cy5uZXh0U2libGluZwpwPXQK
-cD1xPT1udWxsP3AhPW51bGw6cSE9PXAKcT1wfWVsc2UgcT0hMQppZihxKXtxPVAuUFYoIkNvcnJ1cHQg
-SFRNTCIpCnRocm93IEguYihxKX19Y2F0Y2gobyl7SC5SdShvKQpxPXIuYSh0KQpuLmI9ITAKcD1xLnBh
-cmVudE5vZGUKcD1hPT1udWxsP3AhPW51bGw6YSE9PXAKaWYocCl7cD1xLnBhcmVudE5vZGUKaWYocCE9
-bnVsbClwLnJlbW92ZUNoaWxkKHEpfWVsc2UgYS5yZW1vdmVDaGlsZChxKQp0PW51bGwKcz1hLmxhc3RD
-aGlsZH1pZih0IT1udWxsKXRoaXMuJDIodCxhKQp0PXN9fSwKJFM6MzF9ClcuTGUucHJvdG90eXBlPXt9
-ClcuSzcucHJvdG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9ClcuWFcucHJvdG90eXBlPXt9Clcub2Eu
-cHJvdG90eXBlPXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmEs
-cj1zLmxlbmd0aApmb3IodD0wO3Q8cjsrK3QpaWYoc1t0XT09PWEpcmV0dXJuIHQKQy5ObS5pKHMsYSkK
-Qy5ObS5pKHRoaXMuYixudWxsKQpyZXR1cm4gcn0sClB2OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRo
-aXMscD17fQppZihhPT1udWxsKXJldHVybiBhCmlmKEguclEoYSkpcmV0dXJuIGEKaWYodHlwZW9mIGE9
-PSJudW1iZXIiKXJldHVybiBhCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhIGluc3Rh
-bmNlb2YgUC5pUClyZXR1cm4gbmV3IERhdGUoYS5hKQppZih1LmZ2LmIoYSkpdGhyb3cgSC5iKFAubigi
-c3RydWN0dXJlZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodS5jOC5iKGEpKXJldHVybiBhCmlmKHUuZC5i
-KGEpKXJldHVybiBhCmlmKHUuSS5iKGEpKXJldHVybiBhCnQ9dS5kRS5iKGEpfHwhMQppZih0KXJldHVy
-biBhCmlmKHUuRy5iKGEpKXtzPXEuVkgoYSkKdD1xLmIKaWYocz49dC5sZW5ndGgpcmV0dXJuIEguayh0
-LHMpCnI9cC5hPXRbc10KaWYociE9bnVsbClyZXR1cm4gcgpyPXt9CnAuYT1yCkMuTm0uWSh0LHMscikK
-YS5LKDAsbmV3IFAuamcocCxxKSkKcmV0dXJuIHAuYX1pZih1LmouYihhKSl7cz1xLlZIKGEpCnA9cS5i
-CmlmKHM+PXAubGVuZ3RoKXJldHVybiBILmsocCxzKQpyPXBbc10KaWYociE9bnVsbClyZXR1cm4gcgpy
-ZXR1cm4gcS5layhhLHMpfWlmKHUuZUguYihhKSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3Ro
-KXJldHVybiBILmsodCxzKQpyPXAuYj10W3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17fQpwLmI9cgpD
-Lk5tLlkodCxzLHIpCnEuaW0oYSxuZXcgUC5UYShwLHEpKQpyZXR1cm4gcC5ifXRocm93IEguYihQLm4o
-InN0cnVjdHVyZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVrOmZ1bmN0aW9uKGEsYil7dmFyIHQs
-cz1KLlU2KGEpLHI9cy5nQShhKSxxPW5ldyBBcnJheShyKQpDLk5tLlkodGhpcy5iLGIscSkKZm9yKHQ9
-MDt0PHI7Kyt0KUMuTm0uWShxLHQsdGhpcy5QdihzLnEoYSx0KSkpCnJldHVybiBxfX0KUC5qZy5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5hW2FdPXRoaXMuYi5QdihiKX0sCiRTOjF9ClAu
-VGEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYlthXT10aGlzLmIuUHYoYil9LAok
-UzoxfQpQLkJmLnByb3RvdHlwZT17CmltOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5iOC5hKGIp
-CmZvcih0PU9iamVjdC5rZXlzKGEpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9dFtyXQpiLiQyKHEs
-YVtxXSl9fX0KUC5Bcy5wcm90b3R5cGU9ewpUOmZ1bmN0aW9uKGEpe3ZhciB0CkguYyhhKQp0PSQuaEco
-KS5iCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILnZoKEguSShhKSkKaWYodC50ZXN0KGEpKXJldHVybiBh
-CnRocm93IEguYihQLkwzKGEsInZhbHVlIiwiTm90IGEgdmFsaWQgY2xhc3MgdG9rZW4iKSl9LApaOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLncoKS56VigwLCIgIil9LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcy53KCkKcmV0dXJuIFAucmoodCx0LnIsSC5MaCh0KS5jKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLncoKS5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt0aGlzLlQoYikKcmV0dXJuIHRoaXMudygpLnRn
-KDAsYil9LAppOmZ1bmN0aW9uKGEsYil7dGhpcy5UKGIpCnJldHVybiBILkU5KHRoaXMuT1MobmV3IFAu
-R0UoYikpKX0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCnRoaXMuVChiKQp0PXRoaXMudygpCnM9dC5S
-KDAsYikKdGhpcy5wKHQpCnJldHVybiBzfSwKRlY6ZnVuY3Rpb24oYSxiKXt0aGlzLk9TKG5ldyBQLk43
-KHRoaXMsdS5YLmEoYikpKX0sClYxOmZ1bmN0aW9uKGEpe3RoaXMuT1MobmV3IFAudVEoKSl9LApPUzpm
-dW5jdGlvbihhKXt2YXIgdCxzCnUuYlUuYShhKQp0PXRoaXMudygpCnM9YS4kMSh0KQp0aGlzLnAodCkK
-cmV0dXJuIHN9fQpQLkdFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LkMuYShhKS5p
-KDAsdGhpcy5hKX0sCiRTOjMyfQpQLk43LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuYixzPUgudDYodCkKcmV0dXJuIHUuQy5hKGEpLkZWKDAsbmV3IEgubEoodCxzLkMoInFVKDEpIiku
-YSh0aGlzLmEuZ3VNKCkpLHMuQygibEo8MSxxVT4iKSkpfSwKJFM6MjB9ClAudVEucHJvdG90eXBlPXsK
-JDE6ZnVuY3Rpb24oYSl7dS5DLmEoYSkKaWYoYS5hPjApe2EuYj1hLmM9YS5kPWEuZT1hLmY9bnVsbAph
-LmE9MAphLlgoKX1yZXR1cm4gbnVsbH0sCiRTOjIwfQpQLmhGLnByb3RvdHlwZT17JGloRjoxfQpQLlBD
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuWi5hKGEpCnQ9ZnVuY3Rpb24oYixjLGQp
-e3JldHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMsZCx0aGlzLEFycmF5LnByb3RvdHlwZS5zbGljZS5h
-cHBseShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkKUC5EbSh0LCQud1EoKSxhKQpyZXR1cm4gdH0sCiRT
-OjJ9ClAubXQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyB0aGlzLmEoYSl9LAok
-UzoyfQpQLk56LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5yNyhhKX0sCiRT
-OjM0fQpQLlFTLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5UeihhLHUuYW0p
-fSwKJFM6MzV9ClAubnAucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkU0KGEp
-fSwKJFM6MzZ9ClAuRTQucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiIT0ic3Ry
-aW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBT
-dHJpbmcgb3IgbnVtIikpCnJldHVybiBQLkw3KHRoaXMuYVtiXSl9LApZOmZ1bmN0aW9uKGEsYixjKXtp
-Zih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBILmIoUC54WSgicHJv
-cGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51bSIpKQp0aGlzLmFbYl09UC53WShjKX0sCkROOmZ1bmN0
-aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAuRTQmJnRoaXMu
-YT09PWIuYX0sClo6ZnVuY3Rpb24oYSl7dmFyIHQscwp0cnl7dD1TdHJpbmcodGhpcy5hKQpyZXR1cm4g
-dH1jYXRjaChzKXtILlJ1KHMpCnQ9dGhpcy54YigwKQpyZXR1cm4gdH19LApWNzpmdW5jdGlvbihhLGIp
-e3ZhciB0LHM9dGhpcy5hCmlmKGI9PW51bGwpdD1udWxsCmVsc2V7dD1ILnQ2KGIpCnQ9UC5DSChuZXcg
-SC5sSihiLHQuQygiQCgxKSIpLmEoUC5pRygpKSx0LkMoImxKPDEsQD4iKSksITAsdS56KX1yZXR1cm4g
-UC5MNyhzW2FdLmFwcGx5KHMsdCkpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfX0KUC5yNy5wcm90
-b3R5cGU9e30KUC5Uei5wcm90b3R5cGU9ewpjUDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9YTwwfHxh
-Pj10LmdBKHQpCmlmKHMpdGhyb3cgSC5iKFAuVEUoYSwwLHQuZ0EodCksbnVsbCxudWxsKSl9LApxOmZ1
-bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PSJudW1iZXIiJiZiPT09Qy5qbi55dShiKSl0aGlzLmNQKEgu
-V1koYikpCnJldHVybiB0aGlzLiR0aS5jLmEodGhpcy5VcigwLGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0CnRoaXMuJHRpLmMuYShjKQp0PUMuam4ueXUoYikKaWYoYj09PXQpdGhpcy5jUChiKQp0aGlz
-LmU0KDAsYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5sZW5ndGgKaWYodHlwZW9mIHQ9
-PT0ibnVtYmVyIiYmdD4+PjA9PT10KXJldHVybiB0CnRocm93IEguYihQLlBWKCJCYWQgSnNBcnJheSBs
-ZW5ndGgiKSl9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpQLmNvLnByb3RvdHlwZT17fQpQLm5kLnBy
-b3RvdHlwZT17JGluZDoxfQpQLktlLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxw
-PXRoaXMuYS5nZXRBdHRyaWJ1dGUoImNsYXNzIiksbz1QLkxzKHUuTikKaWYocD09bnVsbClyZXR1cm4g
-bwpmb3IodD1wLnNwbGl0KCIgIikscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1KLlQwKHRbcl0pCmlm
-KHEubGVuZ3RoIT09MClvLmkoMCxxKX1yZXR1cm4gb30sCnA6ZnVuY3Rpb24oYSl7dGhpcy5hLnNldEF0
-dHJpYnV0ZSgiY2xhc3MiLGEuelYoMCwiICIpKX19ClAuZDUucHJvdG90eXBlPXsKZ1A6ZnVuY3Rpb24o
-YSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5ZQyhhLGIpfSwKcjY6
-ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGQ9PW51bGwpe3Q9SC5WTShbXSx1Lmsp
-CmQ9bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQsVy5CbCgpKQpDLk5tLmko
-dCxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnM9JzxzdmcgdmVyc2lvbj0iMS4xIj4nK0guZChiKSsi
-PC9zdmc+Igp0PWRvY3VtZW50CnI9dC5ib2R5CnE9KHImJkMuUlkpLkFIKHIscyxjKQpwPXQuY3JlYXRl
-RG9jdW1lbnRGcmFnbWVudCgpCnEudG9TdHJpbmcKdD1uZXcgVy5lNyhxKQpvPXQuZ3I4KHQpCmZvcig7
-dD1vLmZpcnN0Q2hpbGQsdCE9bnVsbDspcC5hcHBlbmRDaGlsZCh0KQpyZXR1cm4gcH0sCm56OmZ1bmN0
-aW9uKGEsYixjLGQsZSl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBpbnZva2UgaW5zZXJ0QWRqYWNlbnRI
-dG1sIG9uIFNWRy4iKSl9LApnVmw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmV1KGEsImNsaWNrIiwh
-MSx1LlEpfSwKJGlkNToxfQpQLm42LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXpNOjEsJGllcTox
-fQpNLkg3LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYn19ClUuTEwucHJvdG90
-eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC5FRihbIm5vZGVJZCIsdGhpcy5iLCJraW5kIix0aGlz
-LmEuYV0sdS5OLHUuSyl9fQpVLk1ELnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1Lmdw
-LmEoYSkuYT09PXRoaXMuYS5xKDAsImtpbmQiKX0sCiRTOjUwfQpVLmQyLnByb3RvdHlwZT17Ckx0OmZ1
-bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89dS5OLG49dS5LLG09UC5GbChvLG4pLGw9cC5hCmlm
-KGwhPW51bGwpe3Q9SC5WTShbXSx1LkopCmZvcihzPWwubGVuZ3RoLHI9MDtyPGwubGVuZ3RoO2wubGVu
-Z3RoPT09c3x8KDAsSC5saykobCksKytyKXtxPWxbcl0KQy5ObS5pKHQsUC5FRihbImRlc2NyaXB0aW9u
-IixxLmEsImhyZWYiLHEuYl0sbyxuKSl9bS5ZKDAsImVkaXRzIix0KX1tLlkoMCwiZXhwbGFuYXRpb24i
-LHAuYikKbS5ZKDAsImxpbmUiLHAuYykKbS5ZKDAsInBhdGgiLHAuZCkKbz1wLmUKaWYobyE9bnVsbCl7
-bj1ILlZNKFtdLHUuSikKZm9yKGw9by5sZW5ndGgscj0wO3I8by5sZW5ndGg7by5sZW5ndGg9PT1sfHwo
-MCxILmxrKShvKSwrK3IpQy5ObS5pKG4sb1tyXS5MdCgpKQptLlkoMCwidHJhY2VzIixuKX1yZXR1cm4g
-bX19ClUuU2UucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC5FRihbImRlc2NyaXB0aW9u
-Iix0aGlzLmEsImhyZWYiLHRoaXMuYl0sdS5OLHUuSyl9fQpVLk1sLnByb3RvdHlwZT17Ckx0OmZ1bmN0
-aW9uKCl7cmV0dXJuIFAuRUYoWyJocmVmIix0aGlzLmEsImxpbmUiLHRoaXMuYiwicGF0aCIsdGhpcy5j
-XSx1Lk4sdS5LKX19ClUueUQucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscT1ILlZN
-KFtdLHUuSikKZm9yKHQ9dGhpcy5iLHM9dC5sZW5ndGgscj0wO3I8dC5sZW5ndGg7dC5sZW5ndGg9PT1z
-fHwoMCxILmxrKSh0KSwrK3IpQy5ObS5pKHEsdFtyXS5MdCgpKQpyZXR1cm4gUC5FRihbImRlc2NyaXB0
-aW9uIix0aGlzLmEsImVudHJpZXMiLHFdLHUuTix1LkspfX0KVS53Yi5wcm90b3R5cGU9ewpMdDpmdW5j
-dGlvbigpe3ZhciB0LHMscj10aGlzLHE9UC5GbCh1Lk4sdS5LKQpxLlkoMCwiZGVzY3JpcHRpb24iLHIu
-YSkKdD1yLmIKaWYodCE9bnVsbClxLlkoMCwiZnVuY3Rpb24iLHQpCnQ9ci5jCmlmKHQhPW51bGwpcS5Z
-KDAsImxpbmsiLHQuTHQoKSkKdD1yLmQKaWYodC5sZW5ndGghPT0wKXtzPUgudDYodCkKcS5ZKDAsImhp
-bnRBY3Rpb25zIixuZXcgSC5sSih0LHMuQygiWjA8cVUsTWg+KDEpIikuYShuZXcgVS5iMCgpKSxzLkMo
-ImxKPDEsWjA8cVUsTWg+PiIpKS5icigwKSl9cmV0dXJuIHF9fQpVLmFOLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiBVLm56KHUuUy5hKGEpKX0sCiRTOjM4fQpVLmIwLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3JldHVybiB1LkYuYShhKS5MdCgpfSwKJFM6Mzl9CkIuajgucHJvdG90eXBlPXsK
-THQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC5FRihbImxpbmUiLHRoaXMuYSwiZXhwbGFuYXRpb24iLHRoaXMu
-Yiwib2Zmc2V0Iix0aGlzLmNdLHUuTix1LkspfX0KQi5xcC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigp
-e3ZhciB0LHMscixxLHAsbyxuLG09dGhpcyxsPXUuTixrPVAuRmwobCx1LmQzKQpmb3IodD1tLmQsdD10
-LmdQdSh0KSx0PXQuZ2t6KHQpLHM9dS5LLHI9dS5KO3QuRigpOyl7cT10LmdsKCkKcD1xLmEKbz1ILlZN
-KFtdLHIpCmZvcihxPUouSVQocS5iKTtxLkYoKTspe249cS5nbCgpCkMuTm0uaShvLFAuRUYoWyJsaW5l
-IixuLmEsImV4cGxhbmF0aW9uIixuLmIsIm9mZnNldCIsbi5jXSxsLHMpKX1rLlkoMCxwLG8pfXJldHVy
-biBQLkVGKFsicmVnaW9ucyIsbS5hLCJuYXZpZ2F0aW9uQ29udGVudCIsbS5iLCJzb3VyY2VDb2RlIixt
-LmMsImVkaXRzIixrXSxsLHMpfX0KVC5tUS5wcm90b3R5cGU9e30KTC5lLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuCnUuQi5hKGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhu
-YW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikKcj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVm
-KQpMLkdlKCkKaWYodCE9PSIvIiYmdCE9PUouVDAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3Qi
-KS50ZXh0Q29udGVudCkpTC5HNyh0LHMsciwhMCxuZXcgTC5WVyh0LHMscikpCnE9ZG9jdW1lbnQKcD1K
-LnFGKHEucXVlcnlTZWxlY3RvcigiLmFwcGx5LW1pZ3JhdGlvbiIpKQpvPXAuJHRpCm49by5DKCJ+KDEp
-IikuYShuZXcgTC5vWigpKQp1Lk0uYShudWxsKQpXLkpFKHAuYSxwLmIsbiwhMSxvLmMpCm89Si5xRihx
-LnF1ZXJ5U2VsZWN0b3IoIi5yZXJ1bi1taWdyYXRpb24iKSkKbj1vLiR0aQpXLkpFKG8uYSxvLmIsbi5D
-KCJ+KDEpIikuYShuZXcgTC55OCgpKSwhMSxuLmMpCm49Si5xRihxLnF1ZXJ5U2VsZWN0b3IoIi5yZXBv
-cnQtcHJvYmxlbSIpKQpvPW4uJHRpClcuSkUobi5hLG4uYixvLkMoIn4oMSkiKS5hKG5ldyBMLkhpKCkp
-LCExLG8uYykKcT1KLnFGKHEucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUgLmNsb3NlIikpCm89cS4k
-dGkKVy5KRShxLmEscS5iLG8uQygifigxKSIpLmEobmV3IEwuQlQoKSksITEsby5jKX0sCiRTOjE5fQpM
-LlZXLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAok
-UzowfQpMLm9aLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3UuVi5hKGEpCmlmKEgub1Qod2luZG93
-LmNvbmZpcm0oIlRoaXMgd2lsbCBhcHBseSB0aGUgY2hhbmdlcyB5b3UndmUgcHJldmlld2VkIHRvIHlv
-dXIgd29ya2luZyBkaXJlY3RvcnkuIEl0IGlzIHJlY29tbWVuZGVkIHlvdSBjb21taXQgYW55IGNoYW5n
-ZXMgeW91IG1hZGUgYmVmb3JlIGRvaW5nIHRoaXMuIikpKUwudHkoIi9hcHBseS1taWdyYXRpb24iLG51
-bGwpLlc3KG5ldyBMLmpyKCksdS5QKS5PQShuZXcgTC5xbCgpKX0sCiRTOjR9CkwuanIucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5TLmEoYSkKdD1kb2N1bWVudC5ib2R5CnQuY2xhc3NMaXN0
-LnJlbW92ZSgicHJvcG9zZWQiKQp0LmNsYXNzTGlzdC5hZGQoImFwcGxpZWQiKX0sCiRTOjQyfQpMLnFs
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5DMigiQ291bGQgbm90IGFwcGx5IG1pZ3JhdGlv
-biIsYSxiKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9CkwueTgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMueG4odS5WLmEoYSkpfSwKeG46ZnVuY3Rpb24oYSl7dmFyIHQ9MCxzPVAuRlgo
-dS5QKSxyPTEscSxwPVtdLG8sbixtLGwKdmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYo
-Yj09PTEpe3E9Ywp0PXJ9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOnI9Mwpkb2N1bWVudC5ib2R5
-LmNsYXNzTGlzdC5hZGQoInJlcnVubmluZyIpCnQ9NgpyZXR1cm4gUC5qUShMLnR5KCIvcmVydW4tbWln
-cmF0aW9uIixudWxsKSwkYXN5bmMkJDEpCmNhc2UgNjp3aW5kb3cubG9jYXRpb24ucmVsb2FkKCkKcC5w
-dXNoKDUpCnQ9NApicmVhawpjYXNlIDM6cj0yCmw9cQpvPUguUnUobCkKbj1ILnRzKGwpCkwuQzIoIkZh
-aWxlZCB0byByZXJ1biBtaWdyYXRpb24iLG8sbikKcC5wdXNoKDUpCnQ9NApicmVhawpjYXNlIDI6cD1b
-MV0KY2FzZSA0OnI9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoInJlcnVubmluZyIpCnQ9
-cC5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNlIDE6cmV0dXJuIFAuZjMo
-cSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscyl9LAokUzoxMX0KTC5IaS5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXt2YXIgdAp1LlYuYShhKQp0PXUuTgpDLm9sLlBvKHdpbmRvdyxQLlhkKCJodHRw
-cyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9uZXciLFAuRUYoWyJ0aXRsZSIsIkN1
-c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRpb24gdG9vbCIsImxhYmVscyIsImFy
-ZWEtYW5hbHl6ZXIsYW5hbHl6ZXItbm5iZC1taWdyYXRpb24sdHlwZS1idWciLCJib2R5IiwiIyMjIyBT
-dGVwcyB0byByZXByb2R1Y2VcblxuIyMjIyBXaGF0IGRpZCB5b3UgZXhwZWN0IHRvIGhhcHBlbj9cblxu
-IyMjIyBXaGF0IGFjdHVhbGx5IGhhcHBlbmVkP1xuXG5fU2NyZWVuc2hvdHMgYXJlIGFwcHJlY2lhdGVk
-X1xuXG4qKkRhcnQgU0RLIHZlcnNpb24qKjogIitILmQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNk
-ay12ZXJzaW9uIikudGV4dENvbnRlbnQpKyJcblxuVGhhbmtzIGZvciBmaWxpbmchXG4iXSx0LHQpKS5a
-KDApLCJyZXBvcnQtcHJvYmxlbSIpfSwKJFM6NH0KTC5CVC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgdAp1LlYuYShhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikuc3R5
-bGUKdC5kaXNwbGF5PSJub25lIgpyZXR1cm4ibm9uZSJ9LAokUzo0NH0KTC5MLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LkIuYShhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpz
-PUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYo
-dC5sZW5ndGg+MSlMLkc3KHQscyxyLCExLG51bGwpCmVsc2V7TC5CRSh0LG5ldyBCLnFwKCIiLCIiLCIi
-LEMuQ00pLCEwKQpMLkJYKCImbmJzcDsiLG51bGwpfX0sCiRTOjE5fQpMLld4LnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPSJjb2xsYXBzZWQiCnUuVi5hKGEpCnQ9dGhpcy5hCnM9Si5S
-RSh0KQpyPXRoaXMuYgppZighcy5nUCh0KS50ZygwLHEpKXtzLmdQKHQpLmkoMCxxKQpKLmRSKHIpLmko
-MCxxKX1lbHNle3MuZ1AodCkuUigwLHEpCkouZFIocikuUigwLHEpfX0sCiRTOjR9CkwuQU8ucHJvdG90
-eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1LmguYShhKSkscz10LiR0aSxyPXMuQygifigx
-KSIpLmEobmV3IEwuZE4odGhpcy5hKSkKdS5NLmEobnVsbCkKVy5KRSh0LmEsdC5iLHIsITEscy5jKX0s
-CiRTOjZ9CkwuZE4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5WLmEoYSkKdD1kb2N1
-bWVudC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKdC50b1N0cmluZwpMLnQyKGEsdGhp
-cy5hLHQuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcodCkpLk8oInBhdGgiKSkp
-fSwKJFM6NH0KTC5Iby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKdS5oLmEoYSkK
-dD1KLnFGKGEpCnM9dC4kdGkKcj1zLkMoIn4oMSkiKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdS5NLmEo
-bnVsbCkKVy5KRSh0LmEsdC5iLHIsITEscy5jKX0sCiRTOjZ9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHQscz1udWxsCnUuVi5hKGEpCnQ9dGhpcy5hCkwuaFgodGhpcy5iLFAuUUEodC5n
-ZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygib2Zmc2V0IikpLHMscyks
-UC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJsaW5lIikp
-LHMscykpfSwKJFM6NH0KTC5JQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD1KLnFGKHUu
-aC5hKGEpKSxzPXQuJHRpCnMuQygifigxKSIpLmEoTC5pUygpKQp1Lk0uYShudWxsKQpXLkpFKHQuYSx0
-LmIsTC5pUygpLCExLHMuYyl9LAokUzo2fQpMLkwxLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Uu
-cC5hKGEpCnRoaXMuYS5hTSgwLHRoaXMuYil9LAokUzoxNn0KTC5uVC5wcm90b3R5cGU9ewokMDpmdW5j
-dGlvbigpe0wuRnIodGhpcy5hLmEsdGhpcy5iLHRoaXMuYyl9LAokUzowfQpMLkJaLnByb3RvdHlwZT17
-CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEuYSxudWxsLG51bGwpfSwKJFM6MH0KTC5HSC5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXt1LmguYShhKQokLnpCKCkudG9TdHJpbmcKdS52LmEoJC5vdygpLnEo
-MCwiaGxqcyIpKS5WNygiaGlnaGxpZ2h0QmxvY2siLFthXSl9LAokUzo2fQpMLkRULnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdS5yLmEoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXt0PUMu
-Q3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQpzPUouVTYodCkKTC5UMShuZXcgVS5kMihVLmpmKHMu
-cSh0LCJlZGl0cyIpKSxILmMocy5xKHQsImV4cGxhbmF0aW9uIikpLEguV1kocy5xKHQsImxpbmUiKSks
-SC5jKHMucSh0LCJwYXRoIikpLFUuTmQocy5xKHQsInRyYWNlcyIpKSkpCkwuRnIodGhpcy5hLHRoaXMu
-Yix0aGlzLmMpCkwueVgoIi5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50IiwhMSl9ZWxzZSB3aW5kb3cu
-YWxlcnQoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2YgIitILmQodCkpfSwKJFM6MTB9CkwuZUgucHJv
-dG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2FkUmVnaW9uRXhwbGFuYXRpb246ICIrSC5k
-KGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIitILmQodGhpcy5hKSsiICgiK0guZChh
-KSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9CkwueXUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyPXRoaXMKdS5yLmEoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPXIuYQpMLkJF
-KHMsQi5ZZih1LmIuYShDLkN0LnBXKDAsYS5yZXNwb25zZVRleHQsbnVsbCkpKSxyLmIpCnQ9ci5jCkwu
-ZkcodCxyLmQpCkwuQlgoQy54Qi50ZyhzLCI/Iik/Qy54Qi5OaihzLDAsQy54Qi5PWShzLCI/IikpOnMs
-dCkKdD1yLmUKaWYodCE9bnVsbCl0LiQwKCl9ZWxzZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3QgZmFpbGVk
-OyBzdGF0dXMgb2YgIitILmQodCkpfSwKJFM6MTB9CkwuekQucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
-YSxiKXtMLnFKKCJsb2FkRmlsZTogIitILmQoYSksYikKd2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9h
-ZCAiK3RoaXMuYSsiICgiK0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9CkwuVFcucHJv
-dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUuci5hKGEpCnQ9YS5zdGF0dXMKaWYodD09
-PTIwMCl7cz1DLkN0LnBXKDAsYS5yZXNwb25zZVRleHQsbnVsbCkKcj1kb2N1bWVudC5xdWVyeVNlbGVj
-dG9yKCIubmF2LXRyZWUiKQpKLmw1KHIsIiIpCkwudFgocixMLm1LKHMpKX1lbHNlIHdpbmRvdy5hbGVy
-dCgiUmVxdWVzdCBmYWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzoxMH0KTC54ci5wcm90b3R5
-cGU9ewokMjpmdW5jdGlvbihhLGIpe0wucUooImxvYWROYXZpZ2F0aW9uVHJlZTogIitILmQoYSksYikK
-d2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9hZCAiK3RoaXMuYSsiICgiK0guZChhKSsiKS4iKX0sCiRD
-OiIkMiIsCiRSOjIsCiRTOjF9CkwuRUUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp1
+bnVtYmVyIilyZXR1cm4gYStiCnJldHVybiBKLlRKKGEpLmgoYSxiKX0sCnEwOmZ1bmN0aW9uKGEsYixj
+KXtyZXR1cm4gSi5yWShhKS5RaShhLGIsYyl9LApxRjpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5n
+VmwoYSl9LAp0SDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouUkUoYSkucGsoYSxiLGMpfSwKeDk6ZnVu
+Y3Rpb24oYSxiKXtpZih0eXBlb2YgYj09PSJudW1iZXIiKWlmKGEuY29uc3RydWN0b3I9PUFycmF5fHx0
+eXBlb2YgYT09InN0cmluZyJ8fEgud1YoYSxhW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdKSlpZihiPj4+
+MD09PWImJmI8YS5sZW5ndGgpcmV0dXJuIGFbYl0KcmV0dXJuIEouVTYoYSkucShhLGIpfSwKemw6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gSi5VNihhKS50ZyhhLGIpfSwKdkI6ZnVuY3Rpb24gdkIoKXt9LAp5RTpm
+dW5jdGlvbiB5RSgpe30sCllFOmZ1bmN0aW9uIFlFKCl7fSwKTUY6ZnVuY3Rpb24gTUYoKXt9LAppQzpm
+dW5jdGlvbiBpQygpe30sCmtkOmZ1bmN0aW9uIGtkKCl7fSwKYzU6ZnVuY3Rpb24gYzUoKXt9LApqZDpm
+dW5jdGlvbiBqZChhKXt0aGlzLiR0aT1hfSwKUG86ZnVuY3Rpb24gUG8oYSl7dGhpcy4kdGk9YX0sCm0x
+OmZ1bmN0aW9uIG0xKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8u
+JHRpPWN9LApxSTpmdW5jdGlvbiBxSSgpe30sCmJVOmZ1bmN0aW9uIGJVKCl7fSwKVkE6ZnVuY3Rpb24g
+VkEoKXt9LApEcjpmdW5jdGlvbiBEcigpe319LFA9ewpPajpmdW5jdGlvbigpe3ZhciB0LHMscj17fQpp
+ZihzZWxmLnNjaGVkdWxlSW1tZWRpYXRlIT1udWxsKXJldHVybiBQLkVYKCkKaWYoc2VsZi5NdXRhdGlv
+bk9ic2VydmVyIT1udWxsJiZzZWxmLmRvY3VtZW50IT1udWxsKXt0PXNlbGYuZG9jdW1lbnQuY3JlYXRl
+RWxlbWVudCgiZGl2IikKcz1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpyLmE9bnVs
+bApuZXcgc2VsZi5NdXRhdGlvbk9ic2VydmVyKEgudFIobmV3IFAudGgociksMSkpLm9ic2VydmUodCx7
+Y2hpbGRMaXN0OnRydWV9KQpyZXR1cm4gbmV3IFAuaGEocix0LHMpfWVsc2UgaWYoc2VsZi5zZXRJbW1l
+ZGlhdGUhPW51bGwpcmV0dXJuIFAueXQoKQpyZXR1cm4gUC5xVygpfSwKWlY6ZnVuY3Rpb24oYSl7c2Vs
+Zi5zY2hlZHVsZUltbWVkaWF0ZShILnRSKG5ldyBQLlZzKHUuTS5hKGEpKSwwKSl9LApvQTpmdW5jdGlv
+bihhKXtzZWxmLnNldEltbWVkaWF0ZShILnRSKG5ldyBQLkZ0KHUuTS5hKGEpKSwwKSl9LApCejpmdW5j
+dGlvbihhKXt1Lk0uYShhKQpQLlFOKDAsYSl9LApRTjpmdW5jdGlvbihhLGIpe3ZhciB0PW5ldyBQLlcz
+KCkKdC5DWShhLGIpCnJldHVybiB0fSwKRlg6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmloKG5ldyBQ
+LnZzKCQuWDMsYS5DKCJ2czwwPiIpKSxhLkMoImloPDA+IikpfSwKREk6ZnVuY3Rpb24oYSxiKXthLiQy
+KDAsbnVsbCkKYi5iPSEwCnJldHVybiBiLmF9LApqUTpmdW5jdGlvbihhLGIpe1AuSmUoYSxiKX0sCnlD
+OmZ1bmN0aW9uKGEsYil7Yi5hTSgwLGEpfSwKZjM6ZnVuY3Rpb24oYSxiKXtiLncwKEguUnUoYSksSC50
+cyhhKSl9LApKZTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1uZXcgUC5XTShiKSxxPW5ldyBQLlNYKGIp
+CmlmKGEgaW5zdGFuY2VvZiBQLnZzKWEuUWQocixxLHUueikKZWxzZXt0PXUuegppZih1LmMuYihhKSlh
+LlNxKHIscSx0KQplbHNle3M9bmV3IFAudnMoJC5YMyx1Ll8pCnMuYT00CnMuYz1hCnMuUWQocixxLHQp
+fX19LApsejpmdW5jdGlvbihhKXt2YXIgdD1mdW5jdGlvbihiLGMpe3JldHVybiBmdW5jdGlvbihkLGUp
+e3doaWxlKHRydWUpdHJ5e2IoZCxlKQpicmVha31jYXRjaChzKXtlPXMKZD1jfX19KGEsMSkKcmV0dXJu
+ICQuWDMuTGoobmV3IFAuR3ModCksdS5QLHUucCx1LnopfSwKR1E6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
+dyBQLkZ5KGEsMSl9LApUaDpmdW5jdGlvbigpe3JldHVybiBDLndRfSwKWW06ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBQLkZ5KGEsMyl9LApsMDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5xNChhLGIuQygi
+cTQ8MD4iKSl9LAprMzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpiLmE9MQp0cnl7YS5TcShuZXcgUC5w
+VihiKSxuZXcgUC5VNyhiKSx1LlApfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5yYihuZXcg
+UC52cihiLHQscykpfX0sCkE5OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PXUuXztzPWEuYSxz
+PT09MjspYT10LmEoYS5jKQppZihzPj00KXtyPWIuYWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5IWihiLHIp
+fWVsc2V7cj11LnguYShiLmMpCmIuYT0yCmIuYz1hCmEualEocil9fSwKSFo6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1udWxsLGQ9e30sYz1kLmE9YQpmb3IodD11
+Lm4scz11Lngscj11LmM7ITA7KXtxPXt9CnA9Yy5hPT09OAppZihiPT1udWxsKXtpZihwKXtvPXQuYShj
+LmMpClAuTDIoZSxlLGMuYixvLmEsby5iKX1yZXR1cm59Zm9yKDtuPWIuYSxuIT1udWxsO2I9bil7Yi5h
+PW51bGwKUC5IWihkLmEsYil9Yz1kLmEKbT1jLmMKcS5hPXAKcS5iPW0KbD0hcAppZihsKXtrPWIuYwpr
+PShrJjEpIT09MHx8KGsmMTUpPT09OH1lbHNlIGs9ITAKaWYoayl7az1iLmIKaj1rLmIKaWYocCl7aT1j
+LmI9PT1qCmk9IShpfHxpKX1lbHNlIGk9ITEKaWYoaSl7dC5hKG0pClAuTDIoZSxlLGMuYixtLmEsbS5i
+KQpyZXR1cm59aD0kLlgzCmlmKGghPT1qKSQuWDM9agplbHNlIGg9ZQpjPWIuYwppZigoYyYxNSk9PT04
+KW5ldyBQLlJUKGQscSxiLHApLiQwKCkKZWxzZSBpZihsKXtpZigoYyYxKSE9PTApbmV3IFAucnEocSxi
+LG0pLiQwKCl9ZWxzZSBpZigoYyYyKSE9PTApbmV3IFAuUlcoZCxxLGIpLiQwKCkKaWYoaCE9bnVsbCkk
+LlgzPWgKYz1xLmIKaWYoci5iKGMpKXtpZihjLmE+PTQpe2c9cy5hKGsuYykKay5jPW51bGwKYj1rLk44
+KGcpCmsuYT1jLmEKay5jPWMuYwpkLmE9Ywpjb250aW51ZX1lbHNlIFAuQTkoYyxrKQpyZXR1cm59fWY9
+Yi5iCmc9cy5hKGYuYykKZi5jPW51bGwKYj1mLk44KGcpCmM9cS5hCmw9cS5iCmlmKCFjKXtmLiR0aS5j
+LmEobCkKZi5hPTQKZi5jPWx9ZWxzZXt0LmEobCkKZi5hPTgKZi5jPWx9ZC5hPWYKYz1mfX0sClZIOmZ1
+bmN0aW9uKGEsYil7dmFyIHQKaWYodS5hZy5iKGEpKXJldHVybiBiLkxqKGEsdS56LHUuSyx1LmwpCnQ9
+dS5iSQppZih0LmIoYSkpcmV0dXJuIHQuYShhKQp0aHJvdyBILmIoUC5MMyhhLCJvbkVycm9yIiwiRXJy
+b3IgaGFuZGxlciBtdXN0IGFjY2VwdCBvbmUgT2JqZWN0IG9yIG9uZSBPYmplY3QgYW5kIGEgU3RhY2tU
+cmFjZSBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm4gYSBhIHZhbGlkIHJlc3VsdCIpKX0sCnB1OmZ1bmN0
+aW9uKCl7dmFyIHQscwpmb3IoO3Q9JC5TNix0IT1udWxsOyl7JC5tZz1udWxsCnM9dC5iCiQuUzY9cwpp
+ZihzPT1udWxsKSQuazg9bnVsbAp0LmEuJDAoKX19LAplTjpmdW5jdGlvbigpeyQuVUQ9ITAKdHJ5e1Au
+cHUoKX1maW5hbGx5eyQubWc9bnVsbAokLlVEPSExCmlmKCQuUzYhPW51bGwpJC51dCgpLiQxKFAuVjko
+KSl9fSwKZVc6ZnVuY3Rpb24oYSl7dmFyIHQ9bmV3IFAuT00oYSkKaWYoJC5TNj09bnVsbCl7JC5TNj0k
+Lms4PXQKaWYoISQuVUQpJC51dCgpLiQxKFAuVjkoKSl9ZWxzZSAkLms4PSQuazguYj10fSwKclI6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyPSQuUzYKaWYocj09bnVsbCl7UC5lVyhhKQokLm1nPSQuazgKcmV0dXJu
+fXQ9bmV3IFAuT00oYSkKcz0kLm1nCmlmKHM9PW51bGwpe3QuYj1yCiQuUzY9JC5tZz10fWVsc2V7dC5i
+PXMuYgokLm1nPXMuYj10CmlmKHQuYj09bnVsbCkkLms4PXR9fSwKcmI6ZnVuY3Rpb24oYSl7dmFyIHQ9
+bnVsbCxzPSQuWDMKaWYoQy5OVT09PXMpe1AuVGsodCx0LEMuTlUsYSkKcmV0dXJufVAuVGsodCx0LHMs
+dS5NLmEocy5HWShhKSkpfSwKUXc6ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKUgudmgoUC5FZSgic3Ry
+ZWFtIikpCnJldHVybiBuZXcgUC54SShiLkMoInhJPDA+IikpfSwKVGw6ZnVuY3Rpb24oYSxiKXt2YXIg
+dD1iPT1udWxsP1AudjAoYSk6YgpQLlVJKGEsImVycm9yIix1LkspCnJldHVybiBuZXcgUC5PSChhLHQp
+fSwKdjA6ZnVuY3Rpb24oYSl7dmFyIHQKaWYodS5XLmIoYSkpe3Q9YS5nSUkoKQppZih0IT1udWxsKXJl
+dHVybiB0fXJldHVybiBDLnBkfSwKTDI6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD17fQp0LmE9ZAp0
+LmI9ZQppZihkPT1udWxsKXt0LmE9bmV3IFAuQVQoITEsbnVsbCwiZXJyb3IiLCJNdXN0IG5vdCBiZSBu
+dWxsIikKdC5iPVAuWmIoKX1QLnJSKG5ldyBQLnBLKHQpKX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7
+dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1kLiQwKCkK
+cmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKeXY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQs
+cz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQxKGUpCiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShlKQpyZXR1
+cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQs
+cz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQyKGUsZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQyKGUsZikK
+cmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKVGs6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKdS5NLmEo
+ZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8ITEpP2MuR1koZCk6Yy5SVChkLHUuSCkKUC5lVyhkKX0s
+CnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1hfSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1h
+CnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVuY3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlv
+biBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0
+aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRo
+aXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShhKXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3Ro
+aXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3Ro
+aXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rpb24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1f
+LmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9
+Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6ZnVuY3Rpb24gUGYoKXt9LApaZjpmdW5jdGlvbiBaZihh
+LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpmdW5jdGlvbiBGZShhLGIsYyxkLGUpe3ZhciBfPXRo
+aXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0aW9uIHZz
+KGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpfLmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVuY3Rpb24g
+ZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9ROmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5hPWEKdGhp
+cy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlzLmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEpe3RoaXMu
+YT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKckg6
+ZnVuY3Rpb24gckgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEsYil7dGhp
+cy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBaTChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
+cy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
+Cl8uZD1kfSwKalo6ZnVuY3Rpb24galooYSl7dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVzpmdW5jdGlvbiBSVyhhLGIsYyl7dGhpcy5hPWEK
+dGhpcy5iPWIKdGhpcy5jPWN9LApPTTpmdW5jdGlvbiBPTShhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0s
+CnFoOmZ1bmN0aW9uIHFoKCl7fSwKQjU6ZnVuY3Rpb24gQjUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
+CnVPOmZ1bmN0aW9uIHVPKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNTzpmdW5jdGlvbiBNTygpe30s
+CmtUOmZ1bmN0aW9uIGtUKCl7fSwKeEk6ZnVuY3Rpb24geEkoYSl7dGhpcy4kdGk9YX0sCk9IOmZ1bmN0
+aW9uIE9IKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAptMDpmdW5jdGlvbiBtMCgpe30sCnBLOmZ1bmN0
+aW9uIHBLKGEpe3RoaXMuYT1hfSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlvbiBoaihhLGIs
+Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1j
+fSwKRUY6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJGbzwxLDI+Iiku
+YShILkI3KGEsbmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkpfSwKRmw6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8MSwyPiIpKX0s
+CkxzOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6ZnVuY3Rpb24o
+KXt2YXIgdD1PYmplY3QuY3JlYXRlKG51bGwpCnRbIjxub24taWRlbnRpZmllci1rZXk+Il09dApkZWxl
+dGUgdFsiPG5vbi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gdH0sCnJqOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgdD1uZXcgUC5sbShhLGIsYy5DKCJsbTwwPiIpKQp0LmM9YS5lCnJldHVybiB0fSwKRVA6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIilyZXR1cm4iKC4u
+LikiCnJldHVybiBiKyIuLi4iK2N9dD1ILlZNKFtdLHUucykKQy5ObS5pKCQueGcsYSkKdHJ5e1AuVnIo
+YSx0KX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3Ao
+KX1zPVAudmcoYix1LlIuYSh0KSwiLCAiKStjCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwK
+V0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSlyZXR1cm4gYisiLi4uIitjCnQ9bmV3
+IFAuUm4oYikKQy5ObS5pKCQueGcsYSkKdHJ5e3M9dApzLmE9UC52ZyhzLmEsYSwiLCAiKX1maW5hbGx5
+e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3AoKX10LmErPWMKcz10
+LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApoQjpmdW5jdGlvbihhKXt2YXIgdCxzCmZv
+cih0PSQueGcubGVuZ3RoLHM9MDtzPHQ7KytzKWlmKGE9PT0kLnhnW3NdKXJldHVybiEwCnJldHVybiEx
+fSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPWEuZ2t6KGEpLGw9MCxrPTAKd2hp
+bGUoITApe2lmKCEobDw4MHx8azwzKSlicmVhawppZighbS5GKCkpcmV0dXJuCnQ9SC5kKG0uZ2woKSkK
+Qy5ObS5pKGIsdCkKbCs9dC5sZW5ndGgrMjsrK2t9aWYoIW0uRigpKXtpZihrPD01KXJldHVybgppZigw
+Pj1iLmxlbmd0aClyZXR1cm4gSC5rKGIsLTEpCnM9Yi5wb3AoKQppZigwPj1iLmxlbmd0aClyZXR1cm4g
+SC5rKGIsLTEpCnI9Yi5wb3AoKX1lbHNle3E9bS5nbCgpOysrawppZighbS5GKCkpe2lmKGs8PTQpe0Mu
+Tm0uaShiLEguZChxKSkKcmV0dXJufXM9SC5kKHEpCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILmsoYiwt
+MSkKcj1iLnBvcCgpCmwrPXMubGVuZ3RoKzJ9ZWxzZXtwPW0uZ2woKTsrK2sKZm9yKDttLkYoKTtxPXAs
+cD1vKXtvPW0uZ2woKTsrK2sKaWYoaz4xMDApe3doaWxlKCEwKXtpZighKGw+NzUmJms+MykpYnJlYWsK
+aWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguayhiLC0xKQpsLT1iLnBvcCgpLmxlbmd0aCsyOy0ta31DLk5t
+LmkoYiwiLi4uIikKcmV0dXJufX1yPUguZChxKQpzPUguZChwKQpsKz1zLmxlbmd0aCtyLmxlbmd0aCs0
+fX1pZihrPmIubGVuZ3RoKzIpe2wrPTUKbj0iLi4uIn1lbHNlIG49bnVsbAp3aGlsZSghMCl7aWYoIShs
+PjgwJiZiLmxlbmd0aD4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5rKGIsLTEpCmwtPWIu
+cG9wKCkubGVuZ3RoKzIKaWYobj09bnVsbCl7bCs9NQpuPSIuLi4ifX1pZihuIT1udWxsKUMuTm0uaShi
+LG4pCkMuTm0uaShiLHIpCkMuTm0uaShiLHMpfSwKdE06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9UC5M
+cyhiKQpmb3IodD1hLmxlbmd0aCxzPTA7czxhLmxlbmd0aDthLmxlbmd0aD09PXR8fCgwLEgubGspKGEp
+LCsrcylyLmkoMCxiLmEoYVtzXSkpCnJldHVybiByfSwKbk86ZnVuY3Rpb24oYSl7dmFyIHQscz17fQpp
+ZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKdD1uZXcgUC5SbigiIikKdHJ5e0MuTm0uaSgkLnhnLGEpCnQu
+YSs9InsiCnMuYT0hMAphLksoMCxuZXcgUC5yYShzLHQpKQp0LmErPSJ9In1maW5hbGx5e2lmKDA+PSQu
+eGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3AoKX1zPXQuYQpyZXR1cm4gcy5jaGFy
+Q29kZUF0KDApPT0wP3M6c30sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5mPV8u
+ZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBibihhKXt0aGlzLmE9
+YQp0aGlzLmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFyIF89dGhpcwpfLmE9
+YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7fSwKdXk6ZnVuY3Rp
+b24gdXkoKXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7fSwKcmE6ZnVuY3Rp
+b24gcmEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7fSwKeVE6ZnVuY3Rp
+b24geVEoYSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0aW9uIFBuKCl7fSwK
+R2o6ZnVuY3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTWE6ZnVuY3Rpb24gTWEoKXt9
+LApWajpmdW5jdGlvbiBWaigpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVuY3Rpb24gblkoKXt9
+LApUQzpmdW5jdGlvbiBUQygpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKQlM6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscQppZih0eXBlb2YgYSE9InN0cmluZyIpdGhyb3cgSC5iKEguSShhKSkKdD1udWxsCnRy
+eXt0PUpTT04ucGFyc2UoYSl9Y2F0Y2gocil7cz1ILlJ1KHIpCnE9UC5ycihTdHJpbmcocyksbnVsbCxu
+dWxsKQp0aHJvdyBILmIocSl9cT1QLlFlKHQpCnJldHVybiBxfSwKUWU6ZnVuY3Rpb24oYSl7dmFyIHQK
+aWYoYT09bnVsbClyZXR1cm4gbnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGEKaWYoT2Jq
+ZWN0LmdldFByb3RvdHlwZU9mKGEpIT09QXJyYXkucHJvdG90eXBlKXJldHVybiBuZXcgUC51dyhhLE9i
+amVjdC5jcmVhdGUobnVsbCkpCmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpYVt0XT1QLlFlKGFbdF0pCnJl
+dHVybiBhfSwKa3k6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0
+dXJuIFAuUlAoITEsYixjLGQpCnJldHVybiBudWxsfSwKUlA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
+cyxyPSQudEwoKQppZihyPT1udWxsKXJldHVybiBudWxsCnQ9MD09PWMKaWYodCYmITApcmV0dXJuIFAu
+T1EocixiKQpzPWIubGVuZ3RoCmQ9UC5qQihjLGQscykKaWYodCYmZD09PXMpcmV0dXJuIFAuT1Eocixi
+KQpyZXR1cm4gUC5PUShyLGIuc3ViYXJyYXkoYyxkKSl9LApPUTpmdW5jdGlvbihhLGIpe2lmKFAuQWoo
+YikpcmV0dXJuIG51bGwKcmV0dXJuIFAuSmgoYSxiKX0sCkpoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0
+cnl7dD1hLmRlY29kZShiKQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpfXJldHVybiBudWxsfSwKQWo6
+ZnVuY3Rpb24oYSl7dmFyIHQscz1hLmxlbmd0aC0yCmZvcih0PTA7dDxzOysrdClpZihhW3RdPT09MjM3
+KWlmKChhW3QrMV0mMjI0KT09PTE2MClyZXR1cm4hMApyZXR1cm4hMX0sCldJOmZ1bmN0aW9uKCl7dmFy
+IHQscwp0cnl7dD1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVybiB0fWNh
+dGNoKHMpe0guUnUocyl9cmV0dXJuIG51bGx9LApjUDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyCmZv
+cih0PUouVTYoYSkscz1iO3M8YzsrK3Mpe3I9dC5xKGEscykKaWYodHlwZW9mIHIhPT0ibnVtYmVyIily
+ZXR1cm4gci56TSgpCmlmKChyJjEyNykhPT1yKXJldHVybiBzLWJ9cmV0dXJuIGMtYn0sCnhNOmZ1bmN0
+aW9uKGEsYixjLGQsZSxmKXtpZihDLmpuLnpZKGYsNCkhPT0wKXRocm93IEguYihQLnJyKCJJbnZhbGlk
+IGJhc2U2NCBwYWRkaW5nLCBwYWRkZWQgbGVuZ3RoIG11c3QgYmUgbXVsdGlwbGUgb2YgZm91ciwgaXMg
+IitmLGEsYykpCmlmKGQrZSE9PWYpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcs
+ICc9JyBub3QgYXQgdGhlIGVuZCIsYSxiKSkKaWYoZT4yKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJh
+c2U2NCBwYWRkaW5nLCBtb3JlIHRoYW4gdHdvICc9JyBjaGFyYWN0ZXJzIixhLGIpKX0sCkd5OmZ1bmN0
+aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuVWQoYSxiKX0sCk5DOmZ1bmN0aW9uKGEpe3JldHVybiBhLkx0
+KCl9LAp1WDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1uZXcgUC5SbigiIikscj1uZXcgUC50dShzLFtd
+LFAuQ3koKSkKci5pVShhKQp0PXMuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCnV3OmZ1
+bmN0aW9uIHV3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPW51bGx9LAppODpmdW5jdGlvbiBp
+OChhKXt0aGlzLmE9YX0sCkNWOmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpm
+dW5jdGlvbiBVaygpe30sCndJOmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApVZDpm
+dW5jdGlvbiBVZChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSzg6ZnVuY3Rpb24gSzgoYSxiKXt0aGlz
+LmE9YQp0aGlzLmI9Yn0sCmJ5OmZ1bmN0aW9uIGJ5KCl7fSwKb2o6ZnVuY3Rpb24gb2ooYSl7dGhpcy5i
+PWF9LApNeDpmdW5jdGlvbiBNeChhKXt0aGlzLmE9YX0sClNoOmZ1bmN0aW9uIFNoKCl7fSwKdGk6ZnVu
+Y3Rpb24gdGkoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnR1OmZ1bmN0aW9uIHR1KGEsYixjKXt0aGlz
+LmM9YQp0aGlzLmE9Ygp0aGlzLmI9Y30sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMo
+KXt9LApSdzpmdW5jdGlvbiBSdyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEp
+e3RoaXMuYT1hfSwKYno6ZnVuY3Rpb24gYnooYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0h
+MApfLmY9Xy5lPV8uZD0wfSwKUUE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguSHAoYSxjKQppZih0IT1u
+dWxsKXJldHVybiB0CmlmKGIhPW51bGwpcmV0dXJuIGIuJDEoYSkKdGhyb3cgSC5iKFAucnIoYSxudWxs
+LG51bGwpKX0sCm9zOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILlRwKXJldHVybiBhLlooMCkK
+cmV0dXJuIkluc3RhbmNlIG9mICciK0guZChILmxoKGEpKSsiJyJ9LApPODpmdW5jdGlvbihhLGIsYyl7
+dmFyIHQscz1KLlFpKGEsYykKaWYoYSE9PTAmJiEwKWZvcih0PTA7dDxzLmxlbmd0aDsrK3QpQy5ObS5Z
+KHMsdCxiKQpyZXR1cm4gc30sCkNIOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPUguVk0oW10sYy5DKCJq
+ZDwwPiIpKQpmb3IodD1KLklUKGEpO3QuRigpOylDLk5tLmkocyxjLmEodC5nbCgpKSkKaWYoYilyZXR1
+cm4gcwpyZXR1cm4gYy5DKCJ6TTwwPiIpLmEoSi5FcChzKSl9LApBRjpmdW5jdGlvbihhLGIpe3JldHVy
+biBiLkMoInpNPDA+IikuYShKLnVuKFAuQ0goYSwhMSxiKSkpfSwKSE06ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0CmlmKEFycmF5LmlzQXJyYXkoYSkpe3UudC5hKGEpCnQ9YS5sZW5ndGgKYz1QLmpCKGIsYyx0KQpy
+ZXR1cm4gSC5lVChiPjB8fGM8dD9DLk5tLkQ2KGEsYixjKTphKX1pZih1LmJtLmIoYSkpcmV0dXJuIEgu
+ZncoYSxiLFAuakIoYixjLGEubGVuZ3RoKSkKcmV0dXJuIFAuYncoYSxiLGMpfSwKT286ZnVuY3Rpb24o
+YSl7cmV0dXJuIEguTHcoYSl9LApidzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD1udWxsCmlm
+KGI8MCl0aHJvdyBILmIoUC5URShiLDAsSi5IKGEpLHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRo
+cm93IEguYihQLlRFKGMsYixKLkgoYSkscCxwKSkKcz1KLklUKGEpCmZvcihyPTA7cjxiOysrcilpZigh
+cy5GKCkpdGhyb3cgSC5iKFAuVEUoYiwwLHIscCxwKSkKcT1bXQppZih0KWZvcig7cy5GKCk7KXEucHVz
+aChzLmdsKCkpCmVsc2UgZm9yKHI9YjtyPGM7KytyKXtpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYyxi
+LHIscCxwKSkKcS5wdXNoKHMuZ2woKSl9cmV0dXJuIEguZVQocSl9LApudTpmdW5jdGlvbihhKXtyZXR1
+cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAsITEsITEsITEpKX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgdD1KLklUKGIpCmlmKCF0LkYoKSlyZXR1cm4gYQppZihjLmxlbmd0aD09PTApe2RvIGErPUguZCh0
+LmdsKCkpCndoaWxlKHQuRigpKX1lbHNle2ErPUguZCh0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0gu
+ZCh0LmdsKCkpfXJldHVybiBhfSwKbHI6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEs
+YixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIgdD1ILk0wKCkKaWYodCE9bnVsbClyZXR1cm4gUC5oSyh0
+KQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNlJyBpcyBub3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rp
+b24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG49IjAxMjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhN
+KXt0PSQuejQoKS5iCmlmKHR5cGVvZiBiIT0ic3RyaW5nIilILnZoKEguSShiKSkKdD10LnRlc3QoYil9
+ZWxzZSB0PSExCmlmKHQpcmV0dXJuIGIKSC5MaChjKS5DKCJVay5TIikuYShiKQpzPWMuZ1pFKCkuV0oo
+YikKZm9yKHQ9cy5sZW5ndGgscj0wLHE9IiI7cjx0Oysrcil7cD1zW3JdCmlmKHA8MTI4KXtvPXA+Pj40
+CmlmKG8+PTgpcmV0dXJuIEguayhhLG8pCm89KGFbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlm
+KG8pcSs9SC5MdyhwKQplbHNlIHE9ZCYmcD09PTMyP3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYx
+NV19cmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9xOnF9LApaYjpmdW5jdGlvbigpe3ZhciB0LHMKaWYo
+SC5vVCgkLnA2KCkpKXJldHVybiBILnRzKG5ldyBFcnJvcigpKQp0cnl7dGhyb3cgSC5iKCIiKX1jYXRj
+aChzKXtILlJ1KHMpCnQ9SC50cyhzKQpyZXR1cm4gdH19LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRo
+LmFicyhhKSxzPWE8MD8iLSI6IiIKaWYodD49MTAwMClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4g
+cysiMCIrdAppZih0Pj0xMClyZXR1cm4gcysiMDAiK3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0
+aW9uKGEpe2lmKGE+PTEwMClyZXR1cm4iIithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIr
+YX0sCmgwOmZ1bmN0aW9uKGEpe2lmKGE+PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApoOmZ1bmN0
+aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyInx8SC5yUShhKXx8bnVsbD09YSlyZXR1cm4gSi5BYyhh
+KQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEpTT04uc3RyaW5naWZ5KGEpCnJldHVybiBQLm9z
+KGEpfSwKaFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBQLkFUKCExLG51bGwsbnVsbCxhKX0sCkwzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3
+IFAuQVQoITAsYSxiLGMpfSwKRWU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkFUKCExLG51bGwsYSwi
+TXVzdCBub3QgYmUgbnVsbCIpfSwKVUk6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpdGhyb3cgSC5i
+KFAuRWUoYikpCnJldHVybiBhfSwKTzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuYkoobnVsbCxu
+dWxsLCEwLGEsYiwiVmFsdWUgbm90IGluIHJhbmdlIil9LApURTpmdW5jdGlvbihhLGIsYyxkLGUpe3Jl
+dHVybiBuZXcgUC5iSihiLGMsITAsYSxkLCJJbnZhbGlkIHZhbHVlIil9LAp3QTpmdW5jdGlvbihhLGIs
+YyxkKXtpZihhPGJ8fGE+Yyl0aHJvdyBILmIoUC5URShhLGIsYyxkLG51bGwpKQpyZXR1cm4gYX0sCmpC
+OmZ1bmN0aW9uKGEsYixjKXtpZigwPmF8fGE+Yyl0aHJvdyBILmIoUC5URShhLDAsYywic3RhcnQiLG51
+bGwpKQppZihiIT1udWxsKXtpZihhPmJ8fGI+Yyl0aHJvdyBILmIoUC5URShiLGEsYywiZW5kIixudWxs
+KSkKcmV0dXJuIGJ9cmV0dXJuIGN9LAprMTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhIT09Im51bWJl
+ciIpcmV0dXJuIGEuSigpCmlmKGE8MCl0aHJvdyBILmIoUC5URShhLDAsbnVsbCxiLG51bGwpKQpyZXR1
+cm4gYX0sCnQ6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1ILldZKGU9PW51bGw/Si5IKGIpOmUpCnJl
+dHVybiBuZXcgUC5lWSh0LCEwLGEsYywiSW5kZXggb3V0IG9mIHJhbmdlIil9LApMNDpmdW5jdGlvbihh
+KXtyZXR1cm4gbmV3IFAudWIoYSl9LApuOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5kcyhhKX0sClBW
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5saihhKX0sCmE0OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcg
+UC5VVihhKX0sCnJyOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuYUUoYSxiLGMpfSwKZEg6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHQscz1ILlZNKFtdLGQuQygiamQ8MD4iKSkKQy5ObS5zQShzLGEpCmZv
+cih0PTA7dDxhOysrdClDLk5tLlkocyx0LGIuJDEodCkpCnJldHVybiBzfSwKaEs6ZnVuY3Rpb24oYSl7
+dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGU9bnVsbCxkPWEubGVuZ3RoCmlmKGQ+PTUp
+e3Q9KChKLlF6KGEsNCleNTgpKjN8Qy54Qi5XKGEsMCleMTAwfEMueEIuVyhhLDEpXjk3fEMueEIuVyhh
+LDIpXjExNnxDLnhCLlcoYSwzKV45Nyk+Pj4wCmlmKHQ9PT0wKXJldHVybiBQLktEKGQ8ZD9DLnhCLk5q
+KGEsMCxkKTphLDUsZSkuZ2xSKCkKZWxzZSBpZih0PT09MzIpcmV0dXJuIFAuS0QoQy54Qi5OaihhLDUs
+ZCksMCxlKS5nbFIoKX1zPW5ldyBBcnJheSg4KQpzLmZpeGVkJGxlbmd0aD1BcnJheQpyPUguVk0ocyx1
+LnQpCkMuTm0uWShyLDAsMCkKQy5ObS5ZKHIsMSwtMSkKQy5ObS5ZKHIsMiwtMSkKQy5ObS5ZKHIsNywt
+MSkKQy5ObS5ZKHIsMywwKQpDLk5tLlkociw0LDApCkMuTm0uWShyLDUsZCkKQy5ObS5ZKHIsNixkKQpp
+ZihQLlVCKGEsMCxkLDAscik+PTE0KUMuTm0uWShyLDcsZCkKcT1yWzFdCmlmKHR5cGVvZiBxIT09Im51
+bWJlciIpcmV0dXJuIHEudEIoKQppZihxPj0wKWlmKFAuVUIoYSwwLHEsMjAscik9PT0yMClyWzddPXEK
+cz1yWzJdCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuaCgpCnA9cysxCm89clszXQpuPXJb
+NF0KbT1yWzVdCmw9cls2XQppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkooKQppZih0eXBl
+b2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCmlmKGw8bSltPWwKaWYodHlwZW9mIG4hPT0ibnVt
+YmVyIilyZXR1cm4gbi5KKCkKaWYobjxwKW49bQplbHNlIGlmKG48PXEpbj1xKzEKaWYodHlwZW9mIG8h
+PT0ibnVtYmVyIilyZXR1cm4gby5KKCkKaWYobzxwKW89bgpzPXJbN10KaWYodHlwZW9mIHMhPT0ibnVt
+YmVyIilyZXR1cm4gcy5KKCkKaz1zPDAKaWYoaylpZihwPnErMyl7aj1lCms9ITF9ZWxzZXtzPW8+MApp
+ZihzJiZvKzE9PT1uKXtqPWUKaz0hMX1lbHNle2lmKCEobTxkJiZtPT09bisyJiZKLnEwKGEsIi4uIixu
+KSkpaT1tPm4rMiYmSi5xMChhLCIvLi4iLG0tMykKZWxzZSBpPSEwCmlmKGkpe2o9ZQprPSExfWVsc2V7
+aWYocT09PTQpaWYoSi5xMChhLCJmaWxlIiwwKSl7aWYocDw9MCl7aWYoIUMueEIuUWkoYSwiLyIsbikp
+e2g9ImZpbGU6Ly8vIgp0PTN9ZWxzZXtoPSJmaWxlOi8vIgp0PTJ9YT1oK0MueEIuTmooYSxuLGQpCnEt
+PTAKcz10LTAKbSs9cwpsKz1zCmQ9YS5sZW5ndGgKcD03Cm89NwpuPTd9ZWxzZSBpZihuPT09bSl7Zz1t
+KzE7KytsCmE9Qy54Qi5pNyhhLG4sbSwiLyIpOysrZAptPWd9aj0iZmlsZSJ9ZWxzZSBpZihDLnhCLlFp
+KGEsImh0dHAiLDApKXtpZihzJiZvKzM9PT1uJiZDLnhCLlFpKGEsIjgwIixvKzEpKXtmPW4tMwptLT0z
+CmwtPTMKYT1DLnhCLmk3KGEsbyxuLCIiKQpkLT0zCm49Zn1qPSJodHRwIn1lbHNlIGo9ZQplbHNlIGlm
+KHE9PT01JiZKLnEwKGEsImh0dHBzIiwwKSl7aWYocyYmbys0PT09biYmSi5xMChhLCI0NDMiLG8rMSkp
+e2Y9bi00Cm0tPTQKbC09NAphPUouZGcoYSxvLG4sIiIpCmQtPTMKbj1mfWo9Imh0dHBzIn1lbHNlIGo9
+ZQprPSEwfX19ZWxzZSBqPWUKaWYoayl7cz1hLmxlbmd0aAppZihkPHMpe2E9Si5sZChhLDAsZCkKcS09
+MApwLT0wCm8tPTAKbi09MAptLT0wCmwtPTB9cmV0dXJuIG5ldyBQLlVmKGEscSxwLG8sbixtLGwsail9
+cmV0dXJuIFAuanYoYSwwLGQscSxwLG8sbixtLGwsail9LApNdDpmdW5jdGlvbihhKXtILmMoYSkKcmV0
+dXJuIFAua3UoYSwwLGEubGVuZ3RoLEMueE0sITEpfSwKV1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dS5OCnJl
+dHVybiBDLk5tLk4wKEguVk0oYS5zcGxpdCgiJiIpLHUucyksUC5GbCh0LHQpLG5ldyBQLm4xKEMueE0p
+LHUuZil9LApIaDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbT1udWxsLGw9IklQdjQg
+YWRkcmVzcyBzaG91bGQgY29udGFpbiBleGFjdGx5IDQgcGFydHMiLGs9ImVhY2ggcGFydCBtdXN0IGJl
+IGluIHRoZSByYW5nZSAwLi4yNTUiLGo9bmV3IFAuY1MoYSksaT1uZXcgVWludDhBcnJheSg0KQpmb3Io
+dD1pLmxlbmd0aCxzPWIscj1zLHE9MDtzPGM7KytzKXtwPUMueEIubShhLHMpCmlmKHAhPT00Nil7aWYo
+KHBeNDgpPjkpai4kMigiaW52YWxpZCBjaGFyYWN0ZXIiLHMpfWVsc2V7aWYocT09PTMpai4kMihsLHMp
+Cm89UC5RQShDLnhCLk5qKGEscixzKSxtLG0pCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8u
+b3MoKQppZihvPjI1NSlqLiQyKGsscikKbj1xKzEKaWYocT49dClyZXR1cm4gSC5rKGkscSkKaVtxXT1v
+CnI9cysxCnE9bn19aWYocSE9PTMpai4kMihsLGMpCm89UC5RQShDLnhCLk5qKGEscixjKSxtLG0pCmlm
+KHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQppZihvPjI1NSlqLiQyKGsscikKaWYocT49
+dClyZXR1cm4gSC5rKGkscSkKaVtxXT1vCnJldHVybiBpfSwKZWc6ZnVuY3Rpb24oYSxiLGEwKXt2YXIg
+dCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPW5ldyBQLlZDKGEpLGM9bmV3IFAuSlQoZCxh
+KQppZihhLmxlbmd0aDwyKWQuJDEoImFkZHJlc3MgaXMgdG9vIHNob3J0IikKdD1ILlZNKFtdLHUudCkK
+Zm9yKHM9YixyPXMscT0hMSxwPSExO3M8YTA7KytzKXtvPUMueEIubShhLHMpCmlmKG89PT01OCl7aWYo
+cz09PWIpeysrcwppZihDLnhCLm0oYSxzKSE9PTU4KWQuJDIoImludmFsaWQgc3RhcnQgY29sb24uIixz
+KQpyPXN9aWYocz09PXIpe2lmKHEpZC4kMigib25seSBvbmUgd2lsZGNhcmQgYDo6YCBpcyBhbGxvd2Vk
+IixzKQpDLk5tLmkodCwtMSkKcT0hMH1lbHNlIEMuTm0uaSh0LGMuJDIocixzKSkKcj1zKzF9ZWxzZSBp
+ZihvPT09NDYpcD0hMH1pZih0Lmxlbmd0aD09PTApZC4kMSgidG9vIGZldyBwYXJ0cyIpCm49cj09PWEw
+Cm09Qy5ObS5ncloodCkKaWYobiYmbSE9PS0xKWQuJDIoImV4cGVjdGVkIGEgcGFydCBhZnRlciBsYXN0
+IGA6YCIsYTApCmlmKCFuKWlmKCFwKUMuTm0uaSh0LGMuJDIocixhMCkpCmVsc2V7bD1QLkhoKGEscixh
+MCkKQy5ObS5pKHQsKGxbMF08PDh8bFsxXSk+Pj4wKQpDLk5tLmkodCwobFsyXTw8OHxsWzNdKT4+PjAp
+fWlmKHEpe2lmKHQubGVuZ3RoPjcpZC4kMSgiYW4gYWRkcmVzcyB3aXRoIGEgd2lsZGNhcmQgbXVzdCBo
+YXZlIGxlc3MgdGhhbiA3IHBhcnRzIil9ZWxzZSBpZih0Lmxlbmd0aCE9PTgpZC4kMSgiYW4gYWRkcmVz
+cyB3aXRob3V0IGEgd2lsZGNhcmQgbXVzdCBjb250YWluIGV4YWN0bHkgOCBwYXJ0cyIpCms9bmV3IFVp
+bnQ4QXJyYXkoMTYpCmZvcihtPXQubGVuZ3RoLGo9ay5sZW5ndGgsaT05LW0scz0wLGg9MDtzPG07Kytz
+KXtnPXRbc10KaWYoZz09PS0xKWZvcihmPTA7ZjxpOysrZil7aWYoaDwwfHxoPj1qKXJldHVybiBILmso
+ayxoKQprW2hdPTAKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5rKGssZSkKa1tlXT0wCmgrPTJ9ZWxzZXtl
+PUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJuIEguayhrLGgpCmtbaF09ZQplPWgrMQppZihl
+Pj1qKXJldHVybiBILmsoayxlKQprW2VdPWcmMjU1CmgrPTJ9fXJldHVybiBrfSwKanY6ZnVuY3Rpb24o
+YSxiLGMsZCxlLGYsZyxoLGksail7dmFyIHQscyxyLHEscCxvLG4sbT1udWxsCmlmKGo9PW51bGwpaWYo
+ZD5iKWo9UC5QaShhLGIsZCkKZWxzZXtpZihkPT09YilQLlIzKGEsYiwiSW52YWxpZCBlbXB0eSBzY2hl
+bWUiKQpqPSIifWlmKGU+Yil7dD1kKzMKcz10PGU/UC56UihhLHQsZS0xKToiIgpyPVAuT2UoYSxlLGYs
+ITEpCmlmKHR5cGVvZiBmIT09Im51bWJlciIpcmV0dXJuIGYuaCgpCnE9ZisxCmlmKHR5cGVvZiBnIT09
+Im51bWJlciIpcmV0dXJuIEgucFkoZykKcD1xPGc/UC53QihQLlFBKEoubGQoYSxxLGcpLG5ldyBQLmUx
+KGEsZiksbSksaik6bX1lbHNle3A9bQpyPXAKcz0iIn1vPVAua2EoYSxnLGgsbSxqLHIhPW51bGwpCmlm
+KHR5cGVvZiBoIT09Im51bWJlciIpcmV0dXJuIGguSigpCm49aDxpP1AubGUoYSxoKzEsaSxtKTptCnJl
+dHVybiBuZXcgUC5EbihqLHMscixwLG8sbixpPGM/UC50RyhhLGkrMSxjKTptKX0sCktMOmZ1bmN0aW9u
+KGEsYixjLGQsZSxmLGcpe3ZhciB0LHMscixxLHAsbwpmPVAuUGkoZiwwLGY9PW51bGw/MDpmLmxlbmd0
+aCkKZz1QLnpSKGcsMCxnPT1udWxsPzA6Zy5sZW5ndGgpCmE9UC5PZShhLDAsYT09bnVsbD8wOmEubGVu
+Z3RoLCExKQp0PVAubGUobnVsbCwwLDAsZSkKcz1QLnRHKG51bGwsMCwwKQpkPVAud0IoZCxmKQpyPWY9
+PT0iZmlsZSIKaWYoYT09bnVsbClxPWcubGVuZ3RoIT09MHx8ZCE9bnVsbHx8cgplbHNlIHE9ITEKaWYo
+cSlhPSIiCnE9YT09bnVsbApwPSFxCmI9UC5rYShiLDAsYj09bnVsbD8wOmIubGVuZ3RoLGMsZixwKQpv
+PWYubGVuZ3RoPT09MAppZihvJiZxJiYhQy54Qi5uKGIsIi8iKSliPVAud0YoYiwhb3x8cCkKZWxzZSBi
+PVAueGUoYikKcmV0dXJuIG5ldyBQLkRuKGYsZyxxJiZDLnhCLm4oYiwiLy8iKT8iIjphLGQsYix0LHMp
+fSwKd0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1cm4gODAKaWYoYT09PSJodHRwcyIpcmV0
+dXJuIDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixjKXt0aHJvdyBILmIoUC5ycihjLGEsYikp
+fSwKWGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPW51bGwsaD1i
+Lmxlbmd0aAppZihoIT09MCl7cj0wCndoaWxlKCEwKXtpZighKHI8aCkpe3Q9IiIKcz0wCmJyZWFrfWlm
+KEMueEIuVyhiLHIpPT09NjQpe3Q9Qy54Qi5OaihiLDAscikKcz1yKzEKYnJlYWt9KytyfWlmKHM8aCYm
+Qy54Qi5XKGIscyk9PT05MSl7Zm9yKHE9cyxwPS0xO3E8aDsrK3Epe289Qy54Qi5XKGIscSkKaWYobz09
+PTM3JiZwPDApe249Qy54Qi5RaShiLCIyNSIscSsxKT9xKzI6cQpwPXEKcT1ufWVsc2UgaWYobz09PTkz
+KWJyZWFrfWlmKHE9PT1oKXRocm93IEguYihQLnJyKCJJbnZhbGlkIElQdjYgaG9zdCBlbnRyeS4iLGIs
+cykpCm09cDwwP3E6cApQLmVnKGIscysxLG0pOysrcQppZihxIT09aCYmQy54Qi5XKGIscSkhPT01OCl0
+aHJvdyBILmIoUC5ycigiSW52YWxpZCBlbmQgb2YgYXV0aG9yaXR5IixiLHEpKX1lbHNlIHE9cwp3aGls
+ZSghMCl7aWYoIShxPGgpKXtsPWkKYnJlYWt9aWYoQy54Qi5XKGIscSk9PT01OCl7az1DLnhCLkcoYixx
+KzEpCmw9ay5sZW5ndGghPT0wP1AuUUEoayxpLGkpOmkKYnJlYWt9KytxfWo9Qy54Qi5OaihiLHMscSl9
+ZWxzZXtsPWkKaj1sCnQ9IiJ9cmV0dXJuIFAuS0woaixpLEguVk0oYy5zcGxpdCgiLyIpLHUucyksbCxk
+LGEsdCl9LAprRTpmdW5jdGlvbihhLGIpe0MuTm0uSyhhLG5ldyBQLk5ZKCExKSl9LApITjpmdW5jdGlv
+bihhLGIsYyl7dmFyIHQscyxyCmZvcih0PUgucUMoYSxjLG51bGwsSC50NihhKS5jKSx0PW5ldyBILmE3
+KHQsdC5nQSh0KSx0LiR0aS5DKCJhNzxhTC5FPiIpKTt0LkYoKTspe3M9dC5kCnI9UC5udSgnWyIqLzo8
+Pj9cXFxcfF0nKQpzLnRvU3RyaW5nCmlmKEgubTIocyxyLDApKXt0PVAuTDQoIklsbGVnYWwgY2hhcmFj
+dGVyIGluIHBhdGg6ICIrcykKdGhyb3cgSC5iKHQpfX19LApyZzpmdW5jdGlvbihhLGIpe3ZhciB0Cmlm
+KCEoNjU8PWEmJmE8PTkwKSl0PTk3PD1hJiZhPD0xMjIKZWxzZSB0PSEwCmlmKHQpcmV0dXJuCnQ9UC5M
+NCgiSWxsZWdhbCBkcml2ZSBsZXR0ZXIgIitQLk9vKGEpKQp0aHJvdyBILmIodCl9LAp3QjpmdW5jdGlv
+bihhLGIpe2lmKGEhPW51bGwmJmE9PT1QLndLKGIpKXJldHVybiBudWxsCnJldHVybiBhfSwKT2U6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoYj09
+PWMpcmV0dXJuIiIKaWYoQy54Qi5tKGEsYik9PT05MSl7aWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1
+cm4gYy5ITigpCnQ9Yy0xCmlmKEMueEIubShhLHQpIT09OTMpUC5SMyhhLGIsIk1pc3NpbmcgZW5kIGBd
+YCB0byBtYXRjaCBgW2AgaW4gaG9zdCIpCnM9YisxCnI9UC50byhhLHMsdCkKaWYodHlwZW9mIHIhPT0i
+bnVtYmVyIilyZXR1cm4gci5KKCkKaWYocjx0KXtxPXIrMQpwPVAuT0EoYSxDLnhCLlFpKGEsIjI1Iixx
+KT9yKzM6cSx0LCIlMjUiKX1lbHNlIHA9IiIKUC5lZyhhLHMscikKcmV0dXJuIEMueEIuTmooYSxiLHIp
+LnRvTG93ZXJDYXNlKCkrcCsiXSJ9aWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQpv
+PWIKZm9yKDtvPGM7KytvKWlmKEMueEIubShhLG8pPT09NTgpe3I9Qy54Qi5YVShhLCIlIixiKQppZigh
+KHI+PWImJnI8Yykpcj1jCmlmKHI8Yyl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShhLCIyNSIscSk/cisz
+OnEsYywiJTI1Iil9ZWxzZSBwPSIiClAuZWcoYSxiLHIpCnJldHVybiJbIitDLnhCLk5qKGEsYixyKStw
+KyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0bzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1DLnhCLlhV
+KGEsIiUiLGIpCmlmKHM+PWIpe2lmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykKdD1z
+PGN9ZWxzZSB0PSExCnJldHVybiB0P3M6Y30sCk9BOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixx
+LHAsbyxuLG0sbCxrPWQhPT0iIj9uZXcgUC5SbihkKTpudWxsCmlmKHR5cGVvZiBjIT09Im51bWJlciIp
+cmV0dXJuIEgucFkoYykKdD1iCnM9dApyPSEwCmZvcig7dDxjOyl7cT1DLnhCLm0oYSx0KQppZihxPT09
+Mzcpe3A9UC5ydihhLHQsITApCm89cD09bnVsbAppZihvJiZyKXt0Kz0zCmNvbnRpbnVlfWlmKGs9PW51
+bGwpaz1uZXcgUC5SbigiIikKbj1rLmErPUMueEIuTmooYSxzLHQpCmlmKG8pcD1DLnhCLk5qKGEsdCx0
+KzMpCmVsc2UgaWYocD09PSIlIilQLlIzKGEsdCwiWm9uZUlEIHNob3VsZCBub3QgY29udGFpbiAlIGFu
+eW1vcmUiKQprLmE9bitwCnQrPTMKcz10CnI9ITB9ZWxzZXtpZihxPDEyNyl7bz1xPj4+NAppZihvPj04
+KXJldHVybiBILmsoQy5GMyxvKQpvPShDLkYzW29dJjE8PChxJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihv
+KXtpZihyJiY2NTw9cSYmOTA+PXEpe2lmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKaWYoczx0KXtrLmEr
+PUMueEIuTmooYSxzLHQpCnM9dH1yPSExfSsrdH1lbHNle2lmKChxJjY0NTEyKT09PTU1Mjk2JiZ0KzE8
+Yyl7bT1DLnhCLm0oYSx0KzEpCmlmKChtJjY0NTEyKT09PTU2MzIwKXtxPTY1NTM2fChxJjEwMjMpPDwx
+MHxtJjEwMjMKbD0yfWVsc2UgbD0xfWVsc2UgbD0xCmlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5h
+Kz1DLnhCLk5qKGEscyx0KQprLmErPVAuelgocSkKdCs9bApzPXR9fX1pZihrPT1udWxsKXJldHVybiBD
+LnhCLk5qKGEsYixjKQppZihzPGMpay5hKz1DLnhCLk5qKGEscyxjKQpvPWsuYQpyZXR1cm4gby5jaGFy
+Q29kZUF0KDApPT0wP286b30sCk9MOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGws
+ayxqCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykKdD1iCnM9dApyPW51bGwKcT0h
+MApmb3IoO3Q8Yzspe3A9Qy54Qi5tKGEsdCkKaWYocD09PTM3KXtvPVAucnYoYSx0LCEwKQpuPW89PW51
+bGwKaWYobiYmcSl7dCs9Mwpjb250aW51ZX1pZihyPT1udWxsKXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5O
+aihhLHMsdCkKbD1yLmErPSFxP20udG9Mb3dlckNhc2UoKTptCmlmKG4pe289Qy54Qi5OaihhLHQsdCsz
+KQprPTN9ZWxzZSBpZihvPT09IiUiKXtvPSIlMjUiCms9MX1lbHNlIGs9MwpyLmE9bCtvCnQrPWsKcz10
+CnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NAppZihuPj04KXJldHVybiBILmsoQy5lYSxuKQpuPShD
+LmVhW25dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKXtpZihxJiY2NTw9cCYmOTA+PXApe2lm
+KHI9PW51bGwpcj1uZXcgUC5SbigiIikKaWYoczx0KXtyLmErPUMueEIuTmooYSxzLHQpCnM9dH1xPSEx
+fSsrdH1lbHNle2lmKHA8PTkzKXtuPXA+Pj40CmlmKG4+PTgpcmV0dXJuIEguayhDLmFrLG4pCm49KEMu
+YWtbbl0mMTw8KHAmMTUpKSE9PTB9ZWxzZSBuPSExCmlmKG4pUC5SMyhhLHQsIkludmFsaWQgY2hhcmFj
+dGVyIikKZWxzZXtpZigocCY2NDUxMik9PT01NTI5NiYmdCsxPGMpe2o9Qy54Qi5tKGEsdCsxKQppZigo
+aiY2NDUxMik9PT01NjMyMCl7cD02NTUzNnwocCYxMDIzKTw8MTB8aiYxMDIzCms9Mn1lbHNlIGs9MX1l
+bHNlIGs9MQppZihyPT1udWxsKXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5OaihhLHMsdCkKci5hKz0hcT9t
+LnRvTG93ZXJDYXNlKCk6bQpyLmErPVAuelgocCkKdCs9awpzPXR9fX19aWYocj09bnVsbClyZXR1cm4g
+Qy54Qi5OaihhLGIsYykKaWYoczxjKXttPUMueEIuTmooYSxzLGMpCnIuYSs9IXE/bS50b0xvd2VyQ2Fz
+ZSgpOm19bj1yLmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApQaTpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHQscyxyLHEKaWYoYj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5yWShhKS5XKGEsYikpKVAu
+UjMoYSxiLCJTY2hlbWUgbm90IHN0YXJ0aW5nIHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpmb3Io
+dD1iLHM9ITE7dDxjOysrdCl7cj1DLnhCLlcoYSx0KQppZihyPDEyOCl7cT1yPj4+NAppZihxPj04KXJl
+dHVybiBILmsoQy5tSyxxKQpxPShDLm1LW3FdJjE8PChyJjE1KSkhPT0wfWVsc2UgcT0hMQppZighcSlQ
+LlIzKGEsdCwiSWxsZWdhbCBzY2hlbWUgY2hhcmFjdGVyIikKaWYoNjU8PXImJnI8PTkwKXM9ITB9YT1D
+LnhCLk5qKGEsYixjKQpyZXR1cm4gUC5ZYShzP2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9u
+KGEpe2lmKGE9PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlm
+KGE9PT0iaHR0cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIK
+cmV0dXJuIGF9LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5Q
+SShhLGIsYyxDLnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdCxzPWU9PT0iZmls
+ZSIscj1zfHxmLHE9YT09bnVsbAppZihxJiZkPT1udWxsKXJldHVybiBzPyIvIjoiIgpxPSFxCmlmKHEm
+JmQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJvdGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmll
+ZCIpKQppZihxKXQ9UC5QSShhLGIsYyxDLldkLCEwKQplbHNle2QudG9TdHJpbmcKcT1ILnQ2KGQpCnQ9
+bmV3IEgubEooZCxxLkMoInFVKDEpIikuYShuZXcgUC5SWigpKSxxLkMoImxKPDEscVU+IikpLkgoMCwi
+LyIpfWlmKHQubGVuZ3RoPT09MCl7aWYocylyZXR1cm4iLyJ9ZWxzZSBpZihyJiYhQy54Qi5uKHQsIi8i
+KSl0PSIvIit0CnJldHVybiBQLkpyKHQsZSxmKX0sCkpyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1iLmxl
+bmd0aD09PTAKaWYodCYmIWMmJiFDLnhCLm4oYSwiLyIpKXJldHVybiBQLndGKGEsIXR8fGMpCnJldHVy
+biBQLnhlKGEpfSwKbGU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscz17fQppZihhIT1udWxsKXtpZihk
+IT1udWxsKXRocm93IEguYihQLnhZKCJCb3RoIHF1ZXJ5IGFuZCBxdWVyeVBhcmFtZXRlcnMgc3BlY2lm
+aWVkIikpCnJldHVybiBQLlBJKGEsYixjLEMuVkMsITApfWlmKGQ9PW51bGwpcmV0dXJuIG51bGwKdD1u
+ZXcgUC5SbigiIikKcy5hPSIiCmQuSygwLG5ldyBQLnk1KG5ldyBQLk1FKHMsdCkpKQpzPXQuYQpyZXR1
+cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCnRHOmZ1bmN0aW9uKGEsYixjKXtpZihhPT1udWxsKXJl
+dHVybiBudWxsCnJldHVybiBQLlBJKGEsYixjLEMuVkMsITApfSwKcnY6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxLHAsbz1iKzIKaWYobz49YS5sZW5ndGgpcmV0dXJuIiUiCnQ9Qy54Qi5tKGEsYisxKQpz
+PUMueEIubShhLG8pCnI9SC5vbyh0KQpxPUgub28ocykKaWYocjwwfHxxPDApcmV0dXJuIiUiCnA9ciox
+NitxCmlmKHA8MTI3KXtvPUMuam4ud0cocCw0KQppZihvPj04KXJldHVybiBILmsoQy5GMyxvKQpvPShD
+LkYzW29dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKXJldHVybiBILkx3KGMmJjY1PD1wJiY5
+MD49cD8ocHwzMik+Pj4wOnApCmlmKHQ+PTk3fHxzPj05NylyZXR1cm4gQy54Qi5OaihhLGIsYiszKS50
+b1VwcGVyQ2FzZSgpCnJldHVybiBudWxsfSwKelg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49
+IjAxMjM0NTY3ODlBQkNERUYiCmlmKGE8MTI4KXt0PW5ldyBBcnJheSgzKQp0LmZpeGVkJGxlbmd0aD1B
+cnJheQpzPUguVk0odCx1LnQpCkMuTm0uWShzLDAsMzcpCkMuTm0uWShzLDEsQy54Qi5XKG4sYT4+PjQp
+KQpDLk5tLlkocywyLEMueEIuVyhuLGEmMTUpKX1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtyPTI0
+MApxPTR9ZWxzZXtyPTIyNApxPTN9ZWxzZXtyPTE5MgpxPTJ9dD1uZXcgQXJyYXkoMypxKQp0LmZpeGVk
+JGxlbmd0aD1BcnJheQpzPUguVk0odCx1LnQpCmZvcihwPTA7LS1xLHE+PTA7cj0xMjgpe289Qy5qbi5i
+ZihhLDYqcSkmNjN8cgpDLk5tLlkocyxwLDM3KQpDLk5tLlkocyxwKzEsQy54Qi5XKG4sbz4+PjQpKQpD
+Lk5tLlkocyxwKzIsQy54Qi5XKG4sbyYxNSkpCnArPTN9fXJldHVybiBQLkhNKHMsMCxudWxsKX0sClBJ
+OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQ9UC5VbChhLGIsYyxkLGUpCnJldHVybiB0PT1udWxsP0Mu
+eEIuTmooYSxiLGMpOnR9LApVbDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbz1udWxs
+LG49IWUsbT1iLGw9bSxrPW8Kd2hpbGUoITApe2lmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0u
+SigpCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykKaWYoIShtPGMpKWJyZWFrCmMk
+MDp7dD1DLnhCLm0oYSxtKQppZih0PDEyNyl7cz10Pj4+NAppZihzPj04KXJldHVybiBILmsoZCxzKQpz
+PShkW3NdJjE8PCh0JjE1KSkhPT0wfWVsc2Ugcz0hMQppZihzKSsrbQplbHNle2lmKHQ9PT0zNyl7cj1Q
+LnJ2KGEsbSwhMSkKaWYocj09bnVsbCl7bSs9MwpicmVhayBjJDB9aWYoIiUiPT09cil7cj0iJTI1Igpx
+PTF9ZWxzZSBxPTN9ZWxzZXtpZihuKWlmKHQ8PTkzKXtzPXQ+Pj40CmlmKHM+PTgpcmV0dXJuIEguayhD
+LmFrLHMpCnM9KEMuYWtbc10mMTw8KHQmMTUpKSE9PTB9ZWxzZSBzPSExCmVsc2Ugcz0hMQppZihzKXtQ
+LlIzKGEsbSwiSW52YWxpZCBjaGFyYWN0ZXIiKQpxPW8Kcj1xfWVsc2V7aWYoKHQmNjQ1MTIpPT09NTUy
+OTYpe3M9bSsxCmlmKHM8Yyl7cD1DLnhCLm0oYSxzKQppZigocCY2NDUxMik9PT01NjMyMCl7dD02NTUz
+NnwodCYxMDIzKTw8MTB8cCYxMDIzCnE9Mn1lbHNlIHE9MX1lbHNlIHE9MX1lbHNlIHE9MQpyPVAuelgo
+dCl9fWlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5hKz1DLnhCLk5qKGEsbCxtKQprLmErPUguZChy
+KQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCm0rPXEKbD1tfX19aWYoaz09bnVs
+bClyZXR1cm4gbwppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkooKQppZihsPGMpay5hKz1D
+LnhCLk5qKGEsbCxjKQpuPWsuYQpyZXR1cm4gbi5jaGFyQ29kZUF0KDApPT0wP246bn0sCnlCOmZ1bmN0
+aW9uKGEpe2lmKEMueEIubihhLCIuIikpcmV0dXJuITAKcmV0dXJuIEMueEIuT1koYSwiLy4iKSE9PS0x
+fSwKeGU6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4KaWYoIVAueUIoYSkpcmV0dXJuIGEKdD1I
+LlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5sZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7
+bz1zW3BdCmlmKEouUk0obywiLi4iKSl7bj10Lmxlbmd0aAppZihuIT09MCl7aWYoMD49bilyZXR1cm4g
+SC5rKHQsLTEpCnQucG9wKCkKaWYodC5sZW5ndGg9PT0wKUMuTm0uaSh0LCIiKX1xPSEwfWVsc2UgaWYo
+Ii4iPT09bylxPSEwCmVsc2V7Qy5ObS5pKHQsbykKcT0hMX19aWYocSlDLk5tLmkodCwiIikKcmV0dXJu
+IEMuTm0uSCh0LCIvIil9LAp3RjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwppZighUC55Qihh
+KSlyZXR1cm4hYj9QLkMxKGEpOmEKdD1ILlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5s
+ZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7bz1zW3BdCmlmKCIuLiI9PT1vKWlmKHQubGVuZ3RoIT09MCYm
+Qy5ObS5ncloodCkhPT0iLi4iKXtpZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEpCnQucG9wKCkK
+cT0hMH1lbHNle0MuTm0uaSh0LCIuLiIpCnE9ITF9ZWxzZSBpZigiLiI9PT1vKXE9ITAKZWxzZXtDLk5t
+LmkodCxvKQpxPSExfX1zPXQubGVuZ3RoCmlmKHMhPT0wKWlmKHM9PT0xKXtpZigwPj1zKXJldHVybiBI
+LmsodCwwKQpzPXRbMF0ubGVuZ3RoPT09MH1lbHNlIHM9ITEKZWxzZSBzPSEwCmlmKHMpcmV0dXJuIi4v
+IgppZihxfHxDLk5tLmdyWih0KT09PSIuLiIpQy5ObS5pKHQsIiIpCmlmKCFiKXtpZigwPj10Lmxlbmd0
+aClyZXR1cm4gSC5rKHQsMCkKQy5ObS5ZKHQsMCxQLkMxKHRbMF0pKX1yZXR1cm4gQy5ObS5IKHQsIi8i
+KX0sCkMxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPWEubGVuZ3RoCmlmKHE+PTImJlAuRXQoSi5Reihh
+LDApKSlmb3IodD0xO3Q8cTsrK3Qpe3M9Qy54Qi5XKGEsdCkKaWYocz09PTU4KXJldHVybiBDLnhCLk5q
+KGEsMCx0KSsiJTNBIitDLnhCLkcoYSx0KzEpCmlmKHM8PTEyNyl7cj1zPj4+NAppZihyPj04KXJldHVy
+biBILmsoQy5tSyxyKQpyPShDLm1LW3JdJjE8PChzJjE1KSk9PT0wfWVsc2Ugcj0hMAppZihyKWJyZWFr
+fXJldHVybiBhfSwKbW46ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9YS5nRmooKSxwPXEubGVuZ3RoCmlm
+KHA+MCYmSi5IKHFbMF0pPT09MiYmSi5hNihxWzBdLDEpPT09NTgpe2lmKDA+PXApcmV0dXJuIEguayhx
+LDApClAucmcoSi5hNihxWzBdLDApLCExKQpQLkhOKHEsITEsMSkKdD0hMH1lbHNle1AuSE4ocSwhMSww
+KQp0PSExfXM9YS5ndFQoKSYmIXQ/IlxcIjoiIgppZihhLmdjaigpKXtyPWEuZ0pmKGEpCmlmKHIubGVu
+Z3RoIT09MClzPXMrIlxcIityKyJcXCJ9cz1QLnZnKHMscSwiXFwiKQpwPXQmJnA9PT0xP3MrIlxcIjpz
+CnJldHVybiBwLmNoYXJDb2RlQXQoMCk9PTA/cDpwfSwKSWg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIK
+Zm9yKHQ9MCxzPTA7czwyOysrcyl7cj1DLnhCLlcoYSxiK3MpCmlmKDQ4PD1yJiZyPD01Nyl0PXQqMTYr
+ci00OAplbHNle3J8PTMyCmlmKDk3PD1yJiZyPD0xMDIpdD10KjE2K3ItODcKZWxzZSB0aHJvdyBILmIo
+UC54WSgiSW52YWxpZCBVUkwgZW5jb2RpbmciKSl9fXJldHVybiB0fSwKa3U6ZnVuY3Rpb24oYSxiLGMs
+ZCxlKXt2YXIgdCxzLHIscSxwPUouclkoYSksbz1iCndoaWxlKCEwKXtpZighKG88Yykpe3Q9ITAKYnJl
+YWt9cz1wLlcoYSxvKQppZihzPD0xMjcpaWYocyE9PTM3KXI9ZSYmcz09PTQzCmVsc2Ugcj0hMAplbHNl
+IHI9ITAKaWYocil7dD0hMQpicmVha30rK299aWYodCl7aWYoQy54TSE9PWQpcj0hMQplbHNlIHI9ITAK
+aWYocilyZXR1cm4gcC5OaihhLGIsYykKZWxzZSBxPW5ldyBILnFqKHAuTmooYSxiLGMpKX1lbHNle3E9
+SC5WTShbXSx1LnQpCmZvcihvPWI7bzxjOysrbyl7cz1wLlcoYSxvKQppZihzPjEyNyl0aHJvdyBILmIo
+UC54WSgiSWxsZWdhbCBwZXJjZW50IGVuY29kaW5nIGluIFVSSSIpKQppZihzPT09Mzcpe2lmKG8rMz5h
+Lmxlbmd0aCl0aHJvdyBILmIoUC54WSgiVHJ1bmNhdGVkIFVSSSIpKQpDLk5tLmkocSxQLkloKGEsbysx
+KSkKbys9Mn1lbHNlIGlmKGUmJnM9PT00MylDLk5tLmkocSwzMikKZWxzZSBDLk5tLmkocSxzKX19dS5M
+LmEocSkKcmV0dXJuIG5ldyBQLkdZKCExKS5XSihxKX0sCkV0OmZ1bmN0aW9uKGEpe3ZhciB0PWF8MzIK
+cmV0dXJuIDk3PD10JiZ0PD0xMjJ9LApLRDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4s
+bSxsPSJJbnZhbGlkIE1JTUUgdHlwZSIsaz1ILlZNKFtiLTFdLHUudCkKZm9yKHQ9YS5sZW5ndGgscz1i
+LHI9LTEscT1udWxsO3M8dDsrK3Mpe3E9Qy54Qi5XKGEscykKaWYocT09PTQ0fHxxPT09NTkpYnJlYWsK
+aWYocT09PTQ3KXtpZihyPDApe3I9cwpjb250aW51ZX10aHJvdyBILmIoUC5ycihsLGEscykpfX1pZihy
+PDAmJnM+Yil0aHJvdyBILmIoUC5ycihsLGEscykpCmZvcig7cSE9PTQ0Oyl7Qy5ObS5pKGsscyk7Kytz
+CmZvcihwPS0xO3M8dDsrK3Mpe3E9Qy54Qi5XKGEscykKaWYocT09PTYxKXtpZihwPDApcD1zfWVsc2Ug
+aWYocT09PTU5fHxxPT09NDQpYnJlYWt9aWYocD49MClDLk5tLmkoayxwKQplbHNle289Qy5ObS5ncloo
+aykKaWYocSE9PTQ0fHxzIT09bys3fHwhQy54Qi5RaShhLCJiYXNlNjQiLG8rMSkpdGhyb3cgSC5iKFAu
+cnIoIkV4cGVjdGluZyAnPSciLGEscykpCmJyZWFrfX1DLk5tLmkoayxzKQpuPXMrMQppZigoay5sZW5n
+dGgmMSk9PT0xKWE9Qy5oOS55cihhLG4sdCkKZWxzZXttPVAuVWwoYSxuLHQsQy5WQywhMCkKaWYobSE9
+bnVsbClhPUMueEIuaTcoYSxuLHQsbSl9cmV0dXJuIG5ldyBQLlBFKGEsayxjKX0sCktOOmZ1bmN0aW9u
+KCl7dmFyIHQ9IjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1u
+b3BxcnN0dXZ3eHl6LS5ffiEkJicoKSorLDs9IixzPSIuIixyPSI6IixxPSIvIixwPSI/IixvPSIjIixu
+PXUuZ2MsbT1QLmRIKDIyLG5ldyBQLnEzKCksITAsbiksbD1uZXcgUC55SShtKSxrPW5ldyBQLmM2KCks
+aj1uZXcgUC5xZCgpLGk9bi5hKGwuJDIoMCwyMjUpKQprLiQzKGksdCwxKQprLiQzKGkscywxNCkKay4k
+MyhpLHIsMzQpCmsuJDMoaSxxLDMpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQy
+KDE0LDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxzLDE1KQprLiQzKGksciwzNCkKay4kMyhpLHEsMjM0
+KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxNSwyMjUpKQprLiQzKGksdCwx
+KQprLiQzKGksIiUiLDIyNSkKay4kMyhpLHIsMzQpCmsuJDMoaSxxLDkpCmsuJDMoaSxwLDE3MikKay4k
+MyhpLG8sMjA1KQppPW4uYShsLiQyKDEsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLHIsMzQpCmsuJDMo
+aSxxLDEwKQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigyLDIzNSkpCmsuJDMo
+aSx0LDEzOSkKay4kMyhpLHEsMTMxKQprLiQzKGkscywxNDYpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8s
+MjA1KQppPW4uYShsLiQyKDMsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDY4KQprLiQzKGkscywx
+OCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNCwyMjkpKQprLiQzKGksdCw1
+KQpqLiQzKGksIkFaIiwyMjkpCmsuJDMoaSxyLDEwMikKay4kMyhpLCJAIiw2OCkKay4kMyhpLCJbIiwy
+MzIpCmsuJDMoaSxxLDEzOCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNSwy
+MjkpKQprLiQzKGksdCw1KQpqLiQzKGksIkFaIiwyMjkpCmsuJDMoaSxyLDEwMikKay4kMyhpLCJAIiw2
+OCkKay4kMyhpLHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig2LDIz
+MSkpCmouJDMoaSwiMTkiLDcpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEzOCkKay4kMyhpLHAsMTcy
+KQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNywyMzEpKQpqLiQzKGksIjA5Iiw3KQprLiQzKGksIkAi
+LDY4KQprLiQzKGkscSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQprLiQzKG4uYShsLiQy
+KDgsOCkpLCJdIiw1KQppPW4uYShsLiQyKDksMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxzLDE2KQpr
+LiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE2LDIzNSkp
+CmsuJDMoaSx0LDExKQprLiQzKGkscywxNykKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMo
+aSxvLDIwNSkKaT1uLmEobC4kMigxNywyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEsOSkKay4kMyhp
+LHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTAsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMo
+aSxzLDE4KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQy
+KDE4LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxOSkKay4kMyhpLHEsMjM0KQprLiQzKGkscCwx
+NzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxOSwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEs
+MjM0KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxMSwyMzUpKQprLiQzKGks
+dCwxMSkKay4kMyhpLHEsMTApCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDEy
+LDIzNikpCmsuJDMoaSx0LDEyKQprLiQzKGkscCwxMikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDEz
+LDIzNykpCmsuJDMoaSx0LDEzKQprLiQzKGkscCwxMykKai4kMyhuLmEobC4kMigyMCwyNDUpKSwiYXoi
+LDIxKQpsPW4uYShsLiQyKDIxLDI0NSkpCmouJDMobCwiYXoiLDIxKQpqLiQzKGwsIjA5IiwyMSkKay4k
+MyhsLCIrLS4iLDIxKQpyZXR1cm4gbX0sClVCOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEs
+cCxvPSQudlooKQpmb3IodD1KLnJZKGEpLHM9YjtzPGM7KytzKXtpZihkPDB8fGQ+PW8ubGVuZ3RoKXJl
+dHVybiBILmsobyxkKQpyPW9bZF0KcT10LlcoYSxzKV45NgppZihxPjk1KXE9MzEKaWYocT49ci5sZW5n
+dGgpcmV0dXJuIEguayhyLHEpCnA9cltxXQpkPXAmMzEKQy5ObS5ZKGUscD4+PjUscyl9cmV0dXJuIGR9
+LApXRjpmdW5jdGlvbiBXRihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYTI6ZnVuY3Rpb24gYTIoKXt9
+LAppUDpmdW5jdGlvbiBpUChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQ1A6ZnVuY3Rpb24gQ1AoKXt9
+LApYUzpmdW5jdGlvbiBYUygpe30sCkM2OmZ1bmN0aW9uIEM2KGEpe3RoaXMuYT1hfSwKTEs6ZnVuY3Rp
+b24gTEsoKXt9LApBVDpmdW5jdGlvbiBBVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
+Yz1jCl8uZD1kfSwKYko6ZnVuY3Rpb24gYkooYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5lPWEKXy5m
+PWIKXy5hPWMKXy5iPWQKXy5jPWUKXy5kPWZ9LAplWTpmdW5jdGlvbiBlWShhLGIsYyxkLGUpe3ZhciBf
+PXRoaXMKXy5mPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LAptcDpmdW5jdGlvbiBtcChhLGIsYyxk
+KXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKdWI6ZnVuY3Rpb24gdWIoYSl7dGhp
+cy5hPWF9LApkczpmdW5jdGlvbiBkcyhhKXt0aGlzLmE9YX0sCmxqOmZ1bmN0aW9uIGxqKGEpe3RoaXMu
+YT1hfSwKVVY6ZnVuY3Rpb24gVVYoYSl7dGhpcy5hPWF9LAprNTpmdW5jdGlvbiBrNSgpe30sCktZOmZ1
+bmN0aW9uIEtZKCl7fSwKdDc6ZnVuY3Rpb24gdDcoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChh
+KXt0aGlzLmE9YX0sCmFFOmZ1bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
+Y30sCkVIOmZ1bmN0aW9uIEVIKCl7fSwKSWY6ZnVuY3Rpb24gSWYoKXt9LApjWDpmdW5jdGlvbiBjWCgp
+e30sCkFuOmZ1bmN0aW9uIEFuKCl7fSwKek06ZnVuY3Rpb24gek0oKXt9LApaMDpmdW5jdGlvbiBaMCgp
+e30sCk4zOmZ1bmN0aW9uIE4zKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKYzg6
+ZnVuY3Rpb24gYzgoKXt9LApsZjpmdW5jdGlvbiBsZigpe30sCk1oOmZ1bmN0aW9uIE1oKCl7fSwKT2Q6
+ZnVuY3Rpb24gT2QoKXt9LAppYjpmdW5jdGlvbiBpYigpe30sCnh1OmZ1bmN0aW9uIHh1KCl7fSwKR3o6
+ZnVuY3Rpb24gR3ooKXt9LApaZDpmdW5jdGlvbiBaZCgpe30sCnFVOmZ1bmN0aW9uIHFVKCl7fSwKUm46
+ZnVuY3Rpb24gUm4oYSl7dGhpcy5hPWF9LApHRDpmdW5jdGlvbiBHRCgpe30sCm4xOmZ1bmN0aW9uIG4x
+KGEpe3RoaXMuYT1hfSwKY1M6ZnVuY3Rpb24gY1MoYSl7dGhpcy5hPWF9LApWQzpmdW5jdGlvbiBWQyhh
+KXt0aGlzLmE9YX0sCkpUOmZ1bmN0aW9uIEpUKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApEbjpmdW5j
+dGlvbiBEbihhLGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8u
+ZT1lCl8uZj1mCl8ucj1nCl8uUT1fLno9Xy55PV8ueD1udWxsfSwKZTE6ZnVuY3Rpb24gZTEoYSxiKXt0
+aGlzLmE9YQp0aGlzLmI9Yn0sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1hfSwKUlo6ZnVuY3Rpb24g
+UlooKXt9LApNRTpmdW5jdGlvbiBNRShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKeTU6ZnVuY3Rpb24g
+eTUoYSl7dGhpcy5hPWF9LApQRTpmdW5jdGlvbiBQRShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
+cy5jPWN9LApxMzpmdW5jdGlvbiBxMygpe30sCnlJOmZ1bmN0aW9uIHlJKGEpe3RoaXMuYT1hfSwKYzY6
+ZnVuY3Rpb24gYzYoKXt9LApxZDpmdW5jdGlvbiBxZCgpe30sClVmOmZ1bmN0aW9uIFVmKGEsYixjLGQs
+ZSxmLGcsaCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9
+ZwpfLng9aApfLnk9bnVsbH0sCnFlOmZ1bmN0aW9uIHFlKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMK
+Xy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy5RPV8uej1fLnk9Xy54PW51
+bGx9LAppSjpmdW5jdGlvbiBpSigpe30sCmpnOmZ1bmN0aW9uIGpnKGEsYil7dGhpcy5hPWEKdGhpcy5i
+PWJ9LApUYTpmdW5jdGlvbiBUYShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQmY6ZnVuY3Rpb24gQmYo
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFzOmZ1bmN0aW9uIEFzKCl7fSwKR0U6ZnVuY3Rpb24gR0Uo
+YSl7dGhpcy5hPWF9LApONzpmdW5jdGlvbiBONyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdVE6ZnVu
+Y3Rpb24gdVEoKXt9LApoRjpmdW5jdGlvbiBoRigpe30sClI0OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0
+LHMscgpILkU5KGIpCnUuai5hKGQpCmlmKEgub1QoYikpe3Q9W2NdCkMuTm0uRlYodCxkKQpkPXR9cz11
+LnoKcj1QLkNIKEouTTEoZCxQLncwKCkscyksITAscykKdS5aLmEoYSkKcmV0dXJuIFAud1koSC5Fayhh
+LHIsbnVsbCkpfSwKRG06ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnRyeXtpZihPYmplY3QuaXNFeHRlbnNp
+YmxlKGEpJiYhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYikpe09iamVjdC5k
+ZWZpbmVQcm9wZXJ0eShhLGIse3ZhbHVlOmN9KQpyZXR1cm4hMH19Y2F0Y2godCl7SC5SdSh0KX1yZXR1
+cm4hMX0sCk9tOmZ1bmN0aW9uKGEsYil7aWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5j
+YWxsKGEsYikpcmV0dXJuIGFbYl0KcmV0dXJuIG51bGx9LAp3WTpmdW5jdGlvbihhKXtpZihhPT1udWxs
+fHx0eXBlb2YgYT09InN0cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8SC5yUShhKSlyZXR1cm4gYQpp
+ZihhIGluc3RhbmNlb2YgUC5FNClyZXR1cm4gYS5hCmlmKEguUjkoYSkpcmV0dXJuIGEKaWYodS51LmIo
+YSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIEgubzIoYSkKaWYodS5aLmIoYSkp
+cmV0dXJuIFAuaEUoYSwiJGRhcnRfanNGdW5jdGlvbiIsbmV3IFAuUEMoKSkKcmV0dXJuIFAuaEUoYSwi
+XyRkYXJ0X2pzT2JqZWN0IixuZXcgUC5tdCgkLmtJKCkpKX0sCmhFOmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dD1QLk9tKGEsYikKaWYodD09bnVsbCl7dD1jLiQxKGEpClAuRG0oYSxiLHQpfXJldHVybiB0fSwKTDc6
+ZnVuY3Rpb24oYSl7dmFyIHQscwppZihhPT1udWxsfHx0eXBlb2YgYT09InN0cmluZyJ8fHR5cGVvZiBh
+PT0ibnVtYmVyInx8dHlwZW9mIGE9PSJib29sZWFuIilyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2Vv
+ZiBPYmplY3QmJkguUjkoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZ1LnUu
+YihhKSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBEYXRlKXt0PUguV1koYS5nZXRUaW1lKCkp
+CmlmKE1hdGguYWJzKHQpPD04NjRlMTMpcz0hMQplbHNlIHM9ITAKaWYocylILnZoKFAueFkoIkRhdGVU
+aW1lIGlzIG91dHNpZGUgdmFsaWQgcmFuZ2U6ICIrdCkpClAuVUkoITEsImlzVXRjIix1LnkpCnJldHVy
+biBuZXcgUC5pUCh0LCExKX1lbHNlIGlmKGEuY29uc3RydWN0b3I9PT0kLmtJKCkpcmV0dXJuIGEubwpl
+bHNlIHJldHVybiBQLk5EKGEpfSwKTkQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIp
+cmV0dXJuIFAuaVEoYSwkLndRKCksbmV3IFAuTnooKSkKaWYoYSBpbnN0YW5jZW9mIEFycmF5KXJldHVy
+biBQLmlRKGEsJC5DcigpLG5ldyBQLlFTKCkpCnJldHVybiBQLmlRKGEsJC5DcigpLG5ldyBQLm5wKCkp
+fSwKaVE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuT20oYSxiKQppZih0PT1udWxsfHwhKGEgaW5zdGFu
+Y2VvZiBPYmplY3QpKXt0PWMuJDEoYSkKUC5EbShhLGIsdCl9cmV0dXJuIHR9LApQQzpmdW5jdGlvbiBQ
+Qygpe30sCm10OmZ1bmN0aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6ZnVuY3Rpb24gTnooKXt9LApRUzpm
+dW5jdGlvbiBRUygpe30sCm5wOmZ1bmN0aW9uIG5wKCl7fSwKRTQ6ZnVuY3Rpb24gRTQoYSl7dGhpcy5h
+PWF9LApyNzpmdW5jdGlvbiByNyhhKXt0aGlzLmE9YX0sClR6OmZ1bmN0aW9uIFR6KGEsYil7dGhpcy5h
+PWEKdGhpcy4kdGk9Yn0sCmNvOmZ1bmN0aW9uIGNvKCl7fSwKbmQ6ZnVuY3Rpb24gbmQoKXt9LApLZTpm
+dW5jdGlvbiBLZShhKXt0aGlzLmE9YX0sCmQ1OmZ1bmN0aW9uIGQ1KCl7fSwKbjY6ZnVuY3Rpb24gbjYo
+KXt9fSxXPXsKeDM6ZnVuY3Rpb24oKXtyZXR1cm4gd2luZG93fSwKWnI6ZnVuY3Rpb24oKXtyZXR1cm4g
+ZG9jdW1lbnR9LApKNjpmdW5jdGlvbihhKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIikK
+aWYoYSE9bnVsbCl0LmhyZWY9YQpyZXR1cm4gdH0sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1kb2N1
+bWVudC5ib2R5LHM9KHQmJkMuUlkpLnI2KHQsYSxiLGMpCnMudG9TdHJpbmcKdD11LmFjCnQ9bmV3IEgu
+VTUobmV3IFcuZTcocyksdC5DKCJhMihsRC5FKSIpLmEobmV3IFcuQ3YoKSksdC5DKCJVNTxsRC5FPiIp
+KQpyZXR1cm4gdS5oLmEodC5ncjgodCkpfSwKclM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPSJlbGVtZW50
+IHRhZyB1bmF2YWlsYWJsZSIKdHJ5e3Q9Si5SRShhKQppZih0eXBlb2YgdC5nbnMoYSk9PSJzdHJpbmci
+KXI9dC5nbnMoYSl9Y2F0Y2gocyl7SC5SdShzKX1yZXR1cm4gcn0sCkMwOmZ1bmN0aW9uKGEsYil7YT01
+MzY4NzA5MTEmYStiCmE9NTM2ODcwOTExJmErKCg1MjQyODcmYSk8PDEwKQpyZXR1cm4gYV5hPj4+Nn0s
+CnJFOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0PVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxk
+KSxzPTUzNjg3MDkxMSZ0KygoNjcxMDg4NjMmdCk8PDMpCnNePXM+Pj4xMQpyZXR1cm4gNTM2ODcwOTEx
+JnMrKCgxNjM4MyZzKTw8MTUpfSwKVE46ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5jbGFzc0xpc3QK
+Zm9yKHQ9Yi5sZW5ndGgscz0wO3M8Yi5sZW5ndGg7Yi5sZW5ndGg9PT10fHwoMCxILmxrKShiKSwrK3Mp
+ci5hZGQoYltzXSl9LApKRTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PVcuYUYobmV3IFcudk4oYyks
+dS5CKQppZih0IT1udWxsJiYhMClKLmRaKGEsYix0LCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHQsITEs
+ZS5DKCJ4QzwwPiIpKX0sClR3OmZ1bmN0aW9uKGEpe3ZhciB0PVcuSjYobnVsbCkscz13aW5kb3cubG9j
+YXRpb24KdD1uZXcgVy5KUShuZXcgVy5tayh0LHMpKQp0LkNZKGEpCnJldHVybiB0fSwKcUQ6ZnVuY3Rp
+b24oYSxiLGMsZCl7dS5oLmEoYSkKSC5jKGIpCkguYyhjKQp1Lk8uYShkKQpyZXR1cm4hMH0sClFXOmZ1
+bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgp1LmguYShhKQpILmMoYikKSC5jKGMpCnQ9dS5PLmEoZCku
+YQpzPXQuYQpzLmhyZWY9YwpyPXMuaG9zdG5hbWUKdD10LmIKaWYoIShyPT10Lmhvc3RuYW1lJiZzLnBv
+cnQ9PXQucG9ydCYmcy5wcm90b2NvbD09dC5wcm90b2NvbCkpaWYocj09PSIiKWlmKHMucG9ydD09PSIi
+KXt0PXMucHJvdG9jb2wKdD10PT09IjoifHx0PT09IiJ9ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9
+ITAKcmV0dXJuIHR9LApCbDpmdW5jdGlvbigpe3ZhciB0PXUuTixzPVAudE0oQy5ReCx0KSxyPXUuZEcu
+YShuZXcgVy5JQSgpKSxxPUguVk0oWyJURU1QTEFURSJdLHUucykKdD1uZXcgVy5jdChzLFAuTHModCks
+UC5Mcyh0KSxQLkxzKHQpLG51bGwpCnQuQ1kobnVsbCxuZXcgSC5sSihDLlF4LHIsdS5kdikscSxudWxs
+KQpyZXR1cm4gdH0sClB2OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFcu
+UDEoYSl9LApxYzpmdW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCmlmKCJwb3N0
+TWVzc2FnZSIgaW4gYSl7dD1XLlAxKGEpCmlmKHUuci5iKHQpKXJldHVybiB0CnJldHVybiBudWxsfWVs
+c2UgcmV0dXJuIHUuci5hKGEpfSwKUDE6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdylyZXR1cm4gdS5j
+aS5hKGEpCmVsc2UgcmV0dXJuIG5ldyBXLmRXKGEpfSwKSEg6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRv
+dy5sb2NhdGlvbilyZXR1cm4gYQplbHNlIHJldHVybiBuZXcgVy5GYigpfSwKYUY6ZnVuY3Rpb24oYSxi
+KXt2YXIgdD0kLlgzCmlmKHQ9PT1DLk5VKXJldHVybiBhCnJldHVybiB0LlB5KGEsYil9LApxRTpmdW5j
+dGlvbiBxRSgpe30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVuY3Rpb24gZlkoKXt9LApuQjpmdW5j
+dGlvbiBuQigpe30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUVA6ZnVuY3Rpb24gUVAoKXt9LApueDpmdW5j
+dGlvbiBueCgpe30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rpb24gaWQoKXt9LApRRjpmdW5j
+dGlvbiBRRigpe30sCk5oOmZ1bmN0aW9uIE5oKCl7fSwKSUI6ZnVuY3Rpb24gSUIoKXt9LApuNzpmdW5j
+dGlvbiBuNygpe30sCnd6OmZ1bmN0aW9uIHd6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmN2OmZ1
+bmN0aW9uIGN2KCl7fSwKQ3Y6ZnVuY3Rpb24gQ3YoKXt9LAplYTpmdW5jdGlvbiBlYSgpe30sCkQwOmZ1
+bmN0aW9uIEQwKCl7fSwKaEg6ZnVuY3Rpb24gaEgoKXt9LApoNDpmdW5jdGlvbiBoNCgpe30sCmJyOmZ1
+bmN0aW9uIGJyKCl7fSwKVmI6ZnVuY3Rpb24gVmIoKXt9LApmSjpmdW5jdGlvbiBmSigpe30sCndhOmZ1
+bmN0aW9uIHdhKCl7fSwKU2c6ZnVuY3Rpb24gU2coKXt9LAp1ODpmdW5jdGlvbiB1OCgpe30sCk9LOmZ1
+bmN0aW9uIE9LKCl7fSwKZTc6ZnVuY3Rpb24gZTcoYSl7dGhpcy5hPWF9LAp1SDpmdW5jdGlvbiB1SCgp
+e30sCkJIOmZ1bmN0aW9uIEJIKCl7fSwKU046ZnVuY3Rpb24gU04oKXt9LApldzpmdW5jdGlvbiBldygp
+e30sCmxwOmZ1bmN0aW9uIGxwKCl7fSwKVGI6ZnVuY3Rpb24gVGIoKXt9LApJdjpmdW5jdGlvbiBJdigp
+e30sCldQOmZ1bmN0aW9uIFdQKCl7fSwKeVk6ZnVuY3Rpb24geVkoKXt9LAp3NjpmdW5jdGlvbiB3Nigp
+e30sCks1OmZ1bmN0aW9uIEs1KCl7fSwKQ206ZnVuY3Rpb24gQ20oKXt9LApDUTpmdW5jdGlvbiBDUSgp
+e30sCnc0OmZ1bmN0aW9uIHc0KCl7fSwKcmg6ZnVuY3Rpb24gcmgoKXt9LApjZjpmdW5jdGlvbiBjZigp
+e30sCmk3OmZ1bmN0aW9uIGk3KGEpe3RoaXMuYT1hfSwKU3k6ZnVuY3Rpb24gU3koYSl7dGhpcy5hPWF9
+LApLUzpmdW5jdGlvbiBLUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQTM6ZnVuY3Rpb24gQTMoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkk0OmZ1bmN0aW9uIEk0KGEpe3RoaXMuYT1hfSwKRms6ZnVuY3Rp
+b24gRmsoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUk86ZnVuY3Rpb24gUk8oYSxiLGMsZCl7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKZXU6ZnVuY3Rpb24gZXUoYSxiLGMsZCl7
+dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKeEM6ZnVuY3Rpb24geEMoYSxiLGMs
+ZCxlKXt2YXIgXz10aGlzCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2TjpmdW5jdGlv
+biB2TihhKXt0aGlzLmE9YX0sCkpROmZ1bmN0aW9uIEpRKGEpe3RoaXMuYT1hfSwKR206ZnVuY3Rpb24g
+R20oKXt9LAp2RDpmdW5jdGlvbiB2RChhKXt0aGlzLmE9YX0sClV2OmZ1bmN0aW9uIFV2KGEpe3RoaXMu
+YT1hfSwKRWc6ZnVuY3Rpb24gRWcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKbTY6
+ZnVuY3Rpb24gbTYoKXt9LApFbzpmdW5jdGlvbiBFbygpe30sCldrOmZ1bmN0aW9uIFdrKCl7fSwKY3Q6
+ZnVuY3Rpb24gY3QoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZT1hCl8uYT1iCl8uYj1jCl8uYz1kCl8u
+ZD1lfSwKSUE6ZnVuY3Rpb24gSUEoKXt9LApPdzpmdW5jdGlvbiBPdygpe30sClc5OmZ1bmN0aW9uIFc5
+KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0tMQpfLmQ9bnVsbApfLiR0aT1jfSwKZFc6
+ZnVuY3Rpb24gZFcoYSl7dGhpcy5hPWF9LApGYjpmdW5jdGlvbiBGYigpe30sCmtGOmZ1bmN0aW9uIGtG
+KCl7fSwKbWs6ZnVuY3Rpb24gbWsoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktvOmZ1bmN0aW9uIEtv
+KGEpe3RoaXMuYT1hCnRoaXMuYj0hMX0sCmZtOmZ1bmN0aW9uIGZtKGEpe3RoaXMuYT1hfSwKTGU6ZnVu
+Y3Rpb24gTGUoKXt9LApLNzpmdW5jdGlvbiBLNygpe30sCnJCOmZ1bmN0aW9uIHJCKCl7fSwKWFc6ZnVu
+Y3Rpb24gWFcoKXt9LApvYTpmdW5jdGlvbiBvYSgpe319LE09ewpPWDpmdW5jdGlvbihhKXtzd2l0Y2go
+YSl7Y2FzZSBDLkFkOnJldHVybiJBZGQgLyo/Ki8gaGludCIKY2FzZSBDLm5lOnJldHVybiJBZGQgLyoh
+Ki8gaGludCIKY2FzZSBDLndWOnJldHVybiJSZW1vdmUgLyo/Ki8gaGludCIKY2FzZSBDLmZSOnJldHVy
+biJSZW1vdmUgLyohKi8gaGludCIKY2FzZSBDLm15OnJldHVybiJDaGFuZ2UgdG8gLyo/Ki8gaGludCIK
+Y2FzZSBDLnJ4OnJldHVybiJDaGFuZ2UgdG8gLyohKi8gaGludCJ9cmV0dXJuIG51bGx9LApINzpmdW5j
+dGlvbiBINyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWUY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIs
+cSxwLG8sbgpmb3IodD1iLmxlbmd0aCxzPTE7czx0Oysrcyl7aWYoYltzXT09bnVsbHx8YltzLTFdIT1u
+dWxsKWNvbnRpbnVlCmZvcig7dD49MTt0PXIpe3I9dC0xCmlmKGJbcl0hPW51bGwpYnJlYWt9cT1uZXcg
+UC5SbigiIikKcD1hKyIoIgpxLmE9cApvPUgucUMoYiwwLHQsSC50NihiKS5jKQpuPW8uJHRpCm49cCtu
+ZXcgSC5sSihvLG4uQygicVUoYUwuRSkiKS5hKG5ldyBNLk5vKCkpLG4uQygibEo8YUwuRSxxVT4iKSku
+SCgwLCIsICIpCnEuYT1uCnEuYT1uKygiKTogcGFydCAiKyhzLTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0
+ICIrcysiIHdhcyBub3QuIikKdGhyb3cgSC5iKFAueFkocS5aKDApKSl9fSwKbEk6ZnVuY3Rpb24gbEko
+YSl7dGhpcy5hPWF9LApNaTpmdW5jdGlvbiBNaSgpe30sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVu
+Y3Rpb24gTm8oKXt9fSxVPXsKbno6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5XWShhLnEoMCwibm9kZUlkIikp
+CnJldHVybiBuZXcgVS5MTChDLk5tLkh0KEMucmssbmV3IFUuTUQoYSkpLHQpfSwKTEw6ZnVuY3Rpb24g
+TEwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1EOmZ1bmN0aW9uIE1EKGEpe3RoaXMuYT1hfSwKamY6
+ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEKaWYoYT09bnVsbCl0PW51bGwKZWxzZXt0PUguVk0oW10sdS5m
+QSkKZm9yKHM9Si5JVCh1LlIuYShhKSk7cy5GKCk7KXtyPXMuZ2woKQpxPUouVTYocikKQy5ObS5pKHQs
+bmV3IFUuU2UoSC5jKHEucShyLCJkZXNjcmlwdGlvbiIpKSxILmMocS5xKHIsImhyZWYiKSkpKX19cmV0
+dXJuIHR9LApOZDpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKGE9PW51bGwpdD1udWxsCmVsc2V7dD1ILlZN
+KFtdLHUuaGgpCmZvcihzPUouSVQodS5SLmEoYSkpO3MuRigpOylDLk5tLmkodCxVLkpqKHMuZ2woKSkp
+fXJldHVybiB0fSwKSmo6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5VNihhKSxzPUguYyh0LnEoYSwiZGVzY3Jp
+cHRpb24iKSkscj1ILlZNKFtdLHUuYUopCmZvcih0PUouSVQodS5SLmEodC5xKGEsImVudHJpZXMiKSkp
+O3QuRigpOylDLk5tLmkocixVLlJqKHQuZ2woKSkpCnJldHVybiBuZXcgVS55RChzLHIpfSwKUmo6ZnVu
+Y3Rpb24oYSl7dmFyIHQscz1KLlU2KGEpLHI9SC5jKHMucShhLCJkZXNjcmlwdGlvbiIpKSxxPUguYyhz
+LnEoYSwiZnVuY3Rpb24iKSkscD1zLnEoYSwibGluayIpCmlmKHA9PW51bGwpcD1udWxsCmVsc2V7dD1K
+LlU2KHApCnA9bmV3IFUuTWwoSC5jKHQucShwLCJocmVmIikpLEguV1kodC5xKHAsImxpbmUiKSksSC5j
+KHQucShwLCJwYXRoIikpKX1zPXUuai5hKHMucShhLCJoaW50QWN0aW9ucyIpKQpzPXM9PW51bGw/bnVs
+bDpKLk0xKHMsbmV3IFUuYU4oKSx1LkUpCnM9cz09bnVsbD9udWxsOnMuYnIoMCkKcmV0dXJuIG5ldyBV
+LndiKHIscSxwLHM9PW51bGw/Qy5kbjpzKX0sCmQyOmZ1bmN0aW9uIGQyKGEsYixjLGQsZSxmKXt2YXIg
+Xz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKU2U6ZnVuY3Rpb24gU2Uo
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0aGlz
+LmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3Yjpm
+dW5jdGlvbiB3YihhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYU46
+ZnVuY3Rpb24gYU4oKXt9LApiMDpmdW5jdGlvbiBiMCgpe319LEI9ewpZZjpmdW5jdGlvbihhKXt2YXIg
+dCxzLHIscSxwLG8sbixtLGw9SC5jKGEucSgwLCJyZWdpb25zIikpLGs9SC5jKGEucSgwLCJuYXZpZ2F0
+aW9uQ29udGVudCIpKSxqPUguYyhhLnEoMCwic291cmNlQ29kZSIpKSxpPVAuRmwodS5OLHUuZjQpCmZv
+cih0PXUuUy5hKGEucSgwLCJlZGl0cyIpKSx0PXQuZ1B1KHQpLHQ9dC5na3oodCkscz11LlIscj11Lmdp
+O3QuRigpOyl7cT10LmdsKCkKcD1xLmEKbz1ILlZNKFtdLHIpCmZvcihxPUouSVQocy5hKHEuYikpO3Eu
+RigpOyl7bj1xLmdsKCkKbT1KLlU2KG4pCkMuTm0uaShvLG5ldyBCLmo4KEguV1kobS5xKG4sImxpbmUi
+KSksSC5jKG0ucShuLCJleHBsYW5hdGlvbiIpKSxILldZKG0ucShuLCJvZmZzZXQiKSkpKX1pLlkoMCxw
+LG8pfXJldHVybiBuZXcgQi5xcChsLGssaixpKX0sCmo4OmZ1bmN0aW9uIGo4KGEsYixjKXt0aGlzLmE9
+YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnFwOmZ1bmN0aW9uIHFwKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5h
+PWEKXy5iPWIKXy5jPWMKXy5kPWR9LApmdjpmdW5jdGlvbiBmdigpe30sCk9TOmZ1bmN0aW9uKGEpe3Zh
+ciB0CmlmKCEoYT49NjUmJmE8PTkwKSl0PWE+PTk3JiZhPD0xMjIKZWxzZSB0PSEwCnJldHVybiB0fSwK
+WXU6ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLmxlbmd0aCxzPWIrMgppZih0PHMpcmV0dXJuITEKaWYoIUIu
+T1MoQy54Qi5tKGEsYikpKXJldHVybiExCmlmKEMueEIubShhLGIrMSkhPT01OClyZXR1cm4hMQppZih0
+PT09cylyZXR1cm4hMApyZXR1cm4gQy54Qi5tKGEscyk9PT00N319LFQ9e21ROmZ1bmN0aW9uIG1RKCl7
+fX0sTD17CklxOmZ1bmN0aW9uKCl7Qy5CWi5CKGRvY3VtZW50LCJET01Db250ZW50TG9hZGVkIixuZXcg
+TC5lKCkpCkMub2wuQih3aW5kb3csInBvcHN0YXRlIixuZXcgTC5MKCkpfSwKa3o6ZnVuY3Rpb24oYSl7
+dmFyIHQscz11LmguYShhLnBhcmVudE5vZGUpLnF1ZXJ5U2VsZWN0b3IoIjpzY29wZSA+IHVsIikscj1z
+LnN0eWxlLHE9IiIrQy5DRC56UShzLm9mZnNldEhlaWdodCkqMisicHgiCnIubWF4SGVpZ2h0PXEKcj1K
+LnFGKGEpCnE9ci4kdGkKdD1xLkMoIn4oMSkiKS5hKG5ldyBMLld4KHMsYSkpCnUuTS5hKG51bGwpClcu
+SkUoci5hLHIuYix0LCExLHEuYyl9LAp5WDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz0icXVl
+cnlTZWxlY3RvckFsbCIsbj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGEpLG09dS5oCm4udG9TdHJpbmcK
+SC5EaChtLG0sIlQiLG8pCnQ9dS5UCnM9bmV3IFcud3oobi5xdWVyeVNlbGVjdG9yQWxsKCIubmF2LWxp
+bmsiKSx0KQpzLksocyxuZXcgTC5BTyhiKSkKSC5EaChtLG0sIlQiLG8pCnI9bmV3IFcud3oobi5xdWVy
+eVNlbGVjdG9yQWxsKCIucmVnaW9uIiksdCkKaWYoci5nQShyKSE9PTApe3E9bi5xdWVyeVNlbGVjdG9y
+KCJ0YWJsZVtkYXRhLXBhdGhdIikKcS50b1N0cmluZwpyLksocixuZXcgTC5IbyhxLmdldEF0dHJpYnV0
+ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHEpKS5PKCJwYXRoIikpKSl9SC5EaChtLG0sIlQiLG8p
+CnA9bmV3IFcud3oobi5xdWVyeVNlbGVjdG9yQWxsKCIuYWRkLWhpbnQtbGluayIpLHQpCnAuSyhwLG5l
+dyBMLklDKCkpfSwKUTY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMu
+RHQuZW8odCwiR0VUIixMLlE0KGEsYiksITApCnQuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBl
+IiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHQsbnVsbCxjKX0s
+CnR5OmZ1bmN0aW9uKGEsYil7dmFyIHQ9bmV3IFhNTEh0dHBSZXF1ZXN0KCkscz11Lk4KQy5EdC5lbyh0
+LCJQT1NUIixMLlE0KGEsUC5GbChzLHMpKSwhMCkKdC5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5
+cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04IikKcmV0dXJuIEwuTFUodCxiLHUuUyl9
+LApMVTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEwuVGcoYSxiLGMsYyl9LApUZzpmdW5jdGlvbihhLGIs
+YyxkKXt2YXIgdD0wLHM9UC5GWChkKSxyLHE9MixwLG89W10sbixtLGwsayxqLGksaCxnCnZhciAkYXN5
+bmMkTFU9UC5seihmdW5jdGlvbihlLGYpe2lmKGU9PT0xKXtwPWYKdD1xfXdoaWxlKHRydWUpc3dpdGNo
+KHQpe2Nhc2UgMDpqPW5ldyBQLlpmKG5ldyBQLnZzKCQuWDMsdS5hbyksdS5iaikKaT11LmFuCmg9aS5h
+KG5ldyBMLmZDKGosYSkpCnUuTS5hKG51bGwpCm09dS5GClcuSkUoYSwibG9hZCIsaCwhMSxtKQpXLkpF
+KGEsImVycm9yIixpLmEoai5nWUooKSksITEsbSkKYS5zZW5kKGI9PW51bGw/bnVsbDpDLkN0Lk9CKGIs
+bnVsbCkpCnE9NAp0PTcKcmV0dXJuIFAualEoai5hLCRhc3luYyRMVSkKY2FzZSA3OnE9Mgp0PTYKYnJl
+YWsKY2FzZSA0OnE9MwpnPXAKSC5SdShnKQpuPUgudHMoZykKaT1QLlRsKCJFcnJvciByZWFjaGluZyBt
+aWdyYXRpb24gcHJldmlldyBzZXJ2ZXIuIixuKQp0aHJvdyBILmIoaSkKdD02CmJyZWFrCmNhc2UgMzp0
+PTIKYnJlYWsKY2FzZSA2Oms9Qy5DdC5wVygwLGEucmVzcG9uc2VUZXh0LG51bGwpCmlmKGEuc3RhdHVz
+PT09MjAwKXtyPWMuYShrKQp0PTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIoaykKY2FzZSAxOnJldHVybiBQ
+LnlDKHIscykKY2FzZSAyOnJldHVybiBQLmYzKHAscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5jJExVLHMp
+fSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHQ9UC5oSyhhKS5naFkoKS5xKDAsImxpbmUiKQpyZXR1cm4gdD09
+bnVsbD9udWxsOkguSHAodCxudWxsKX0sCkc2OmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSkuZ2hZKCku
+cSgwLCJvZmZzZXQiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAodCxudWxsKX0sCmk2OmZ1bmN0aW9u
+KGEpe3JldHVybiBMLm5XKHUuVi5hKGEpKX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciB0PTAscz1QLkZYKHUu
+eikscj0xLHEscD1bXSxvLG4sbSxsLGsKdmFyICRhc3luYyRpNj1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYo
+Yj09PTEpe3E9Ywp0PXJ9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOmw9dS5oLmEoVy5xYyhhLmN1
+cnJlbnRUYXJnZXQpKS5nZXRBdHRyaWJ1dGUoImhyZWYiKQphLnByZXZlbnREZWZhdWx0KCkKcj0zCnQ9
+NgpyZXR1cm4gUC5qUShMLnR5KGwsbnVsbCksJGFzeW5jJGk2KQpjYXNlIDY6dS5hXy5hKEouR3IoVy5Q
+dihkb2N1bWVudC5kZWZhdWx0VmlldykpKS5yZWxvYWQoKQpyPTEKdD01CmJyZWFrCmNhc2UgMzpyPTIK
+az1xCm89SC5SdShrKQpuPUgudHMoaykKTC5DMigiQ291bGQgbm90IGFkZC9yZW1vdmUgaGludCIsbyxu
+KQp0PTUKYnJlYWsKY2FzZSAyOnQ9MQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNl
+IDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkaTYscyl9LApDMjpmdW5jdGlv
+bihhLGIsYyl7dmFyIHQscyxyPSJleGNlcHRpb24iLHE9InN0YWNrVHJhY2UiLHA9dS5TLmIoYikmJkou
+Uk0oYi5xKDAsInN1Y2Nlc3MiKSwhMSkmJkgub1QoYi54NChyKSkmJkgub1QoYi54NChxKSksbz1KLmlh
+KGIpCmlmKHApe3Q9SC5jKG8ucShiLHIpKQpjPW8ucShiLHEpfWVsc2UgdD1vLlooYikKcD1kb2N1bWVu
+dApzPXAucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpzLnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5u
+ZXJUZXh0PWEKcy5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PXQKcy5xdWVyeVNlbGVjdG9yKCJw
+cmUiKS5pbm5lclRleHQ9Si5BYyhjKQpvPXUuTgp1LmJxLmEocy5xdWVyeVNlbGVjdG9yKCJhLmJvdHRv
+bSIpKS5ocmVmPVAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9zZGsvaXNzdWVzL25l
+dyIsUC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVwb3J0ZWQgaXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlv
+biB0b29sOiAiK2EsImxhYmVscyIsImFyZWEtYW5hbHl6ZXIsYW5hbHl6ZXItbm5iZC1taWdyYXRpb24s
+dHlwZS1idWciLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5kKHQpKyJcblxuUGxlYXNlIGZpbGwgaW4g
+dGhlIGZvbGxvd2luZzpcblxuKipOYW1lIG9mIHBhY2thZ2UgYmVpbmcgbWlncmF0ZWQgKGlmIHB1Ymxp
+YykqKjpcbioqV2hhdCBJIHdhcyBkb2luZyB3aGVuIHRoaXMgaXNzdWUgb2NjdXJyZWQqKjpcbioqSXMg
+aXQgcG9zc2libGUgdG8gd29yayBhcm91bmQgdGhpcyBpc3N1ZSoqOlxuKipIYXMgdGhpcyBpc3N1ZSBo
+YXBwZW5lZCBiZWZvcmUsIGFuZCBpZiBzbywgaG93IG9mdGVuKio6XG4qKkRhcnQgU0RLIHZlcnNpb24q
+KjogIitILmQocC5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkrIlxuKipB
+ZGRpdGlvbmFsIGRldGFpbHMqKjpcblxuVGhhbmtzIGZvciBmaWxpbmchXG5cblN0YWNrdHJhY2U6IF9h
+dXRvIHBvcHVsYXRlZCBieSBtaWdyYXRpb24gcHJldmlldyB0b29sLl9cblxuYGBgXG4iK0guZChjKSsi
+XG5gYGBcbiJdLG8sbykpLlooMCkKbz1zLnN0eWxlCm8uZGlzcGxheT0iaW5pdGlhbCIKcD1hKyI6ICIr
+SC5kKGIpCndpbmRvdwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUu
+ZXJyb3IocCkKd2luZG93CnA9SC5kKGMpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5k
+b3cuY29uc29sZS5lcnJvcihwKX0sCnQyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwPXt9LG89
+dS5oLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKQphLnByZXZlbnREZWZhdWx0KCkKdD1wLmE9by5nZXRB
+dHRyaWJ1dGUoImhyZWYiKQpzPUouemwodCwiPyIpP3AuYT1DLnhCLk5qKHQsMCxDLnhCLk9ZKHQsIj8i
+KSk6dApyPUwuRzYodCkKcT1MLmFLKHQpCmlmKHIhPW51bGwpTC5hZihzLHIscSxiLG5ldyBMLm5UKHAs
+cixxKSkKZWxzZSBMLmFmKHMsbnVsbCxudWxsLGIsbmV3IEwuQloocCkpfSwKdlU6ZnVuY3Rpb24oKXt2
+YXIgdD1kb2N1bWVudCxzPXUuaApILkRoKHMscywiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQp0PW5ldyBX
+Lnd6KHQucXVlcnlTZWxlY3RvckFsbCgiLmNvZGUiKSx1LlQpCnQuSyh0LG5ldyBMLkdIKCkpfSwKaFg6
+ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBMLll3KGEsYixjKX0sCll3OmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dD0wLHM9UC5GWCh1LnopLHI9MSxxLHA9W10sbyxuLG0sbCxrLGosaSxoCnZhciAkYXN5bmMkaFg9UC5s
+eihmdW5jdGlvbihkLGUpe2lmKGQ9PT0xKXtxPWUKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2Ug
+MDpyPTMKaz11Lk4KdD02CnJldHVybiBQLmpRKEwuUTYoYSxQLkVGKFsicmVnaW9uIiwicmVnaW9uIiwi
+b2Zmc2V0IixILmQoYildLGssayksdS5TKSwkYXN5bmMkaFgpCmNhc2UgNjpvPWUKaz1vCmo9Si5VNihr
+KQpuPW5ldyBVLmQyKFUuamYoai5xKGssImVkaXRzIikpLEguYyhqLnEoaywiZXhwbGFuYXRpb24iKSks
+SC5XWShqLnEoaywibGluZSIpKSxILmMoai5xKGssImRpc3BsYXlQYXRoIikpLEguYyhqLnEoaywidXJp
+UGF0aCIpKSxVLk5kKGoucShrLCJ0cmFjZXMiKSkpCkwuVDEobikKTC5GcihhLGIsYykKTC55WCgiLmVk
+aXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiLCExKQpyPTEKdD01CmJyZWFrCmNhc2UgMzpyPTIKaD1xCm09
+SC5SdShoKQpsPUgudHMoaCkKTC5DMigiQ291bGQgbm90IGxvYWQgZWRpdCBkZXRhaWxzIixtLGwpCnQ9
+NQpicmVhawpjYXNlIDI6dD0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHMpCmNhc2UgMTpy
+ZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyRoWCxzKX0sCkc3OmZ1bmN0aW9uKGEs
+YixjLGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMsZCxlKX0sCkw1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFy
+IHQ9MCxzPVAuRlgodS56KSxyLHE9MixwLG89W10sbixtLGwsayxqLGksaAp2YXIgJGFzeW5jJEc3PVAu
+bHooZnVuY3Rpb24oZixnKXtpZihmPT09MSl7cD1nCnQ9cX13aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNl
+IDA6aWYoIUouclkoYSkuVGMoYSwiLmRhcnQiKSl7TC5CRShhLG5ldyBCLnFwKCIiLCIiLCIiLEMuQ00p
+LGQpCkwuQlgoYSxudWxsKQppZihlIT1udWxsKWUuJDAoKQp0PTEKYnJlYWt9cT00Cmo9dS5OCnQ9Nwpy
+ZXR1cm4gUC5qUShMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUiXSxqLGopLHUuUyksJGFzeW5jJEc3
+KQpjYXNlIDc6bj1nCkwuQkUoYSxCLllmKG4pLGQpCkwuZkcoYixjKQptPUMueEIudGcoYSwiPyIpP0Mu
+eEIuTmooYSwwLEMueEIuT1koYSwiPyIpKTphCkwuQlgobSxiKQppZihlIT1udWxsKWUuJDAoKQpxPTIK
+dD02CmJyZWFrCmNhc2UgNDpxPTMKaD1wCmw9SC5SdShoKQprPUgudHMoaCkKTC5DMigiQ291bGQgbm90
+IGxvYWQgZGFydCBmaWxlICIrYSxsLGspCnQ9NgpicmVhawpjYXNlIDM6dD0yCmJyZWFrCmNhc2UgNjpj
+YXNlIDE6cmV0dXJuIFAueUMocixzKQpjYXNlIDI6cmV0dXJuIFAuZjMocCxzKX19KQpyZXR1cm4gUC5E
+SSgkYXN5bmMkRzcscyl9LApHZTpmdW5jdGlvbigpe3ZhciB0PTAscz1QLkZYKHUueikscj0xLHEscD1b
+XSxvLG4sbSxsLGssaixpCnZhciAkYXN5bmMkR2U9UC5seihmdW5jdGlvbihhLGIpe2lmKGE9PT0xKXtx
+PWIKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2UgMDpqPSIvX3ByZXZpZXcvbmF2aWdhdGlvblRy
+ZWUuanNvbiIKcj0zCnQ9NgpyZXR1cm4gUC5qUShMLlE2KGosQy5XTyx1LmV3KSwkYXN5bmMkR2UpCmNh
+c2UgNjpvPWIKbj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubmF2LXRyZWUiKQpKLmw1KG4sIiIpCkwu
+dFgobixMLm1LKG8pKQpyPTEKdD01CmJyZWFrCmNhc2UgMzpyPTIKaT1xCm09SC5SdShpKQpsPUgudHMo
+aSkKTC5DMigiQ291bGQgbm90IGxvYWQgbmF2aWdhdGlvbiB0cmVlIixtLGwpCnQ9NQpicmVhawpjYXNl
+IDI6dD0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHMpCmNhc2UgMTpyZXR1cm4gUC5mMyhx
+LHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyRHZSxzKX0sCnFPOmZ1bmN0aW9uKGEpe3ZhciB0LHM9YS5n
+ZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxyPUMuQ0QuelEoJC5maSgpLm9mZnNldEhlaWdodCkscT13aW5k
+b3cuaW5uZXJIZWlnaHQscD1DLkNELnpRKCQuRFcoKS5vZmZzZXRIZWlnaHQpCmlmKHR5cGVvZiBxIT09
+Im51bWJlciIpcmV0dXJuIHEuSE4oKQp0PXMuYm90dG9tCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0
+dXJuIHQub3MoKQppZih0PnEtKHArMTQpKUouZGgoYSkKZWxzZXtxPXMudG9wCmlmKHR5cGVvZiBxIT09
+Im51bWJlciIpcmV0dXJuIHEuSigpCmlmKHE8cisxNClKLmRoKGEpfX0sCmZHOmZ1bmN0aW9uKGEsYil7
+dmFyIHQscyxyCmlmKGEhPW51bGwpe3Q9ZG9jdW1lbnQKcz10LmdldEVsZW1lbnRCeUlkKCJvIitILmQo
+YSkpCnI9dC5xdWVyeVNlbGVjdG9yKCIubGluZS0iK0guZChiKSkKaWYocyE9bnVsbCl7TC5xTyhzKQpK
+LmRSKHMpLmkoMCwidGFyZ2V0Iil9ZWxzZSBpZihyIT1udWxsKUwucU8oci5wYXJlbnRFbGVtZW50KQpp
+ZihyIT1udWxsKUouZFIodS5oLmEoci5wYXJlbnROb2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNlIEwu
+cU8oJC5EOSgpKX0sCmFmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyPUwuRzYod2luZG93Lmxv
+Y2F0aW9uLmhyZWYpLHE9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYociE9bnVsbCl7dD1kb2N1
+bWVudC5nZXRFbGVtZW50QnlJZCgibyIrSC5kKHIpKQppZih0IT1udWxsKUouZFIodCkuUigwLCJ0YXJn
+ZXQiKX1pZihxIT1udWxsKXtzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIrSC5kKHEpKQpp
+ZihzIT1udWxsKUouZFIocy5wYXJlbnRFbGVtZW50KS5SKDAsImhpZ2hsaWdodCIpfWlmKGE9PXdpbmRv
+dy5sb2NhdGlvbi5wYXRobmFtZSl7TC5mRyhiLGMpCmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0s
+ClE0OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPVAuaEsoYSkscT11Lk4KcT1QLkZsKHEscSkKZm9yKHQ9
+ci5naFkoKSx0PXQuZ1B1KHQpLHQ9dC5na3oodCk7dC5GKCk7KXtzPXQuZ2woKQpxLlkoMCxzLmEscy5i
+KX1mb3IodD1iLmdQdShiKSx0PXQuZ2t6KHQpO3QuRigpOyl7cz10LmdsKCkKcS5ZKDAscy5hLHMuYil9
+cS5ZKDAsImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1cm4gci5ubSgwLHEpLlooMCl9LApUMTpmdW5jdGlv
+bihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsaz0kLmhMKCkKSi5sNShrLCIiKQppZihhPT1udWxsKXt0
+PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInAiKQp0LnRleHRDb250ZW50PSJTZWUgZGV0YWlscyBhYm91
+dCBhIHByb3Bvc2VkIGVkaXQuIgpDLkx0LnNQKHQsSC5WTShbInBsYWNlaG9sZGVyIl0sdS5zKSkKay5h
+cHBlbmRDaGlsZCh0KQpDLkx0LkZGKHQpCnJldHVybn1zPWEuZApyPSQublUoKQpxPXIuemYocykKcD1h
+LmIKbz1kb2N1bWVudApuPXIuSFAocyxKLlQwKG8ucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29u
+dGVudCkpCm09YS5jCmw9by5jcmVhdGVFbGVtZW50KCJwIikKay5hcHBlbmRDaGlsZChsKQpsLmFwcGVu
+ZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoSC5kKHApKyIgYXQgIikpCnI9dS5OCnI9Vy5KNihMLlE0KGEu
+ZSxQLkVGKFsibGluZSIsSi5BYyhtKV0scixyKSkpCnIuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9k
+ZShILmQobikrIjoiK0guZChtKSsiLiIpKQpsLmFwcGVuZENoaWxkKHIpCkouZGgobCkKTC5DQyhhLGss
+cSkKTC5GeihhLGspfSwKTEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGos
+aSxoLGc9JC55UCgpCkoubDUoZywiIikKaWYoYi5nQShiKT09PTApe3Q9ZG9jdW1lbnQKcz10LmNyZWF0
+ZUVsZW1lbnQoInAiKQpnLmFwcGVuZENoaWxkKHMpCnMuYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9k
+ZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQdShiKSxnPWcuZ2t6KGcpLHQ9dS5R
+LHI9dC5DKCJ+KDEpIikscT11Lk0sdD10LmM7Zy5GKCk7KXtwPWcuZ2woKQpvPWRvY3VtZW50CnM9by5j
+cmVhdGVFbGVtZW50KCJwIikKbj0kLnlQKCkKbi5hcHBlbmRDaGlsZChzKQpzLmFwcGVuZENoaWxkKG8u
+Y3JlYXRlVGV4dE5vZGUoSC5kKHAuYSkrIjoiKSkKbT1vLmNyZWF0ZUVsZW1lbnQoInVsIikKbi5hcHBl
+bmRDaGlsZChtKQpmb3IocD1KLklUKHAuYik7cC5GKCk7KXtuPXAuZ2woKQpsPW8uY3JlYXRlRWxlbWVu
+dCgibGkiKQptLmFwcGVuZENoaWxkKGwpCkouZFIobCkuaSgwLCJlZGl0IikKaz1vLmNyZWF0ZUVsZW1l
+bnQoImEiKQpsLmFwcGVuZENoaWxkKGspCmsuY2xhc3NMaXN0LmFkZCgiZWRpdC1saW5rIikKaj1uLmMK
+aT1ILmQoaikKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygib2Zm
+c2V0IiksaSkKaD1uLmEKaT1ILmQoaCkKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcg
+Vy5pNyhrKSkuTygibGluZSIpLGkpCmsuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZSgibGluZSAi
+K0guZChoKSkpCmk9ci5hKG5ldyBMLkVFKGosaCxhKSkKcS5hKG51bGwpClcuSkUoaywiY2xpY2siLGks
+ITEsdCkKbC5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5kKG4uYikpKX19aWYoYylM
+LlQxKG51bGwpfSwKRnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj13aW5kb3cubG9jYXRpb24scT1Q
+LmhLKChyJiZDLkV4KS5nRHIocikrSC5kKGEpKQpyPXUuTgpyPVAuRmwocixyKQppZihiIT1udWxsKXIu
+WSgwLCJvZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbClyLlkoMCwibGluZSIsSC5kKGMpKQpyLlkoMCwi
+YXV0aFRva2VuIiwkLlVFKCkpCnE9cS5ubSgwLHIpCnI9d2luZG93Lmhpc3RvcnkKdD11LnoKcz1xLloo
+MCkKci50b1N0cmluZwpyLnB1c2hTdGF0ZShuZXcgUC5CZihbXSxbXSkuUHYoUC5GbCh0LHQpKSwiIixz
+KX0sCkVuOmZ1bmN0aW9uKGEpe3ZhciB0PUoubShkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucm9vdCIp
+LnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uKGEsdCkpcmV0dXJuIEMueEIuRyhhLHQubGVuZ3RoKQpl
+bHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9e30Kci5hPWEKYT1MLkVuKGEp
+CnIuYT1hCiQuRDkoKS50ZXh0Q29udGVudD1hCnQ9ZG9jdW1lbnQKcz11LmgKSC5EaChzLHMsIlQiLCJx
+dWVyeVNlbGVjdG9yQWxsIikKdD1uZXcgVy53eih0LnF1ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtcGFuZWwg
+Lm5hdi1saW5rIiksdS5UKQp0LksodCxuZXcgTC5WUyhyKSl9LApCRTpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQ9Ii5yZWdpb25zIixzPWRvY3VtZW50LHI9cy5xdWVyeVNlbGVjdG9yKHQpLHE9cy5xdWVyeVNlbGVj
+dG9yKCIuY29kZSIpCkoudEgocixiLmEsJC5LRygpKQpKLnRIKHEsYi5iLCQuS0coKSkKTC5MSChhLGIu
+ZCxjKQpMLnZVKCkKTC55WCgiLmNvZGUiLCEwKQpMLnlYKHQsITApfSwKdFg6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnPWRvY3VtZW50LGY9Zy5jcmVhdGVFbGVtZW50KCJ1
+bCIpCmEuYXBwZW5kQ2hpbGQoZikKZm9yKHQ9Yi5sZW5ndGgscz11Lk0scj0wO3I8Yi5sZW5ndGg7Yi5s
+ZW5ndGg9PT10fHwoMCxILmxrKShiKSwrK3Ipe3E9YltyXQpwPWcuY3JlYXRlRWxlbWVudCgibGkiKQpm
+LmFwcGVuZENoaWxkKHApCm89Si5SRShwKQppZihxLmE9PT1DLlkyKXtvLmdQKHApLmkoMCwiZGlyIikK
+bj1nLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwLmFwcGVuZENoaWxkKG4pCm89Si5SRShuKQpvLmdQKG4p
+LmkoMCwiYXJyb3ciKQpvLnNoZihuLCImI3gyNUJDOyIpCm09Zy5jcmVhdGVFbGVtZW50KCJzcGFuIikK
+cC5hcHBlbmRDaGlsZChtKQpKLmw1KG0sIiYjeDFGNEMxOyIpCnAuYXBwZW5kQ2hpbGQoZy5jcmVhdGVU
+ZXh0Tm9kZShxLmIpKQpMLnRYKHAscS5jKQpMLmt6KG4pfWVsc2V7by5zaGYocCwiJiN4MUY0QzQ7IikK
+bD1nLmNyZWF0ZUVsZW1lbnQoImEiKQpwLmFwcGVuZENoaWxkKGwpCm89Si5SRShsKQpvLmdQKGwpLmko
+MCwibmF2LWxpbmsiKQpsLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGwpKS5P
+KCJuYW1lIikscS5kKQpsLnNldEF0dHJpYnV0ZSgiaHJlZiIscS5lKQpsLmFwcGVuZENoaWxkKGcuY3Jl
+YXRlVGV4dE5vZGUocS5iKSkKbz1vLmdWbChsKQprPW8uJHRpCmo9ay5DKCJ+KDEpIikuYShuZXcgTC5U
+RCgpKQpzLmEobnVsbCkKVy5KRShvLmEsby5iLGosITEsay5jKQppPXEuZgppZih0eXBlb2YgaSE9PSJu
+dW1iZXIiKXJldHVybiBpLm9zKCkKaWYoaT4wKXtoPWcuY3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBw
+ZW5kQ2hpbGQoaCkKSi5kUihoKS5pKDAsImVkaXQtY291bnQiKQpvPSIiK2krIiAiCmlmKGk9PT0xKWs9
+ImVkaXQiCmVsc2Ugaz0iZWRpdHMiCmguc2V0QXR0cmlidXRlKCJ0aXRsZSIsbytrKQpoLmFwcGVuZENo
+aWxkKGcuY3JlYXRlVGV4dE5vZGUoQy5qbi5aKGkpKSl9fX19LApGejpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMscixxLHAsbyxuLG0sbCxrLGosaT1hLmEKaWYoaT09bnVsbClyZXR1cm4KdD1kb2N1bWVudApzPXQu
+Y3JlYXRlRWxlbWVudCgicCIpCnI9Yi5hcHBlbmRDaGlsZChzKQpzPXQuY3JlYXRlRWxlbWVudCgic3Bh
+biIpCnE9dS5zCkouTXUocyxILlZNKFsidHlwZS1kZXNjcmlwdGlvbiJdLHEpKQpzLmFwcGVuZENoaWxk
+KHQuY3JlYXRlVGV4dE5vZGUoIkFjdGlvbnMiKSkKci5hcHBlbmRDaGlsZChzKQpyLmFwcGVuZENoaWxk
+KHQuY3JlYXRlVGV4dE5vZGUoIjoiKSkKcD10LmNyZWF0ZUVsZW1lbnQoInAiKQpiLmFwcGVuZENoaWxk
+KHApCmZvcihzPWkubGVuZ3RoLG89dS5YLG49MDtuPGkubGVuZ3RoO2kubGVuZ3RoPT09c3x8KDAsSC5s
+aykoaSksKytuKXttPWlbbl0KbD10LmNyZWF0ZUVsZW1lbnQoImEiKQpwLmFwcGVuZENoaWxkKGwpCmwu
+YXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZShtLmEpKQpsLnNldEF0dHJpYnV0ZSgiaHJlZiIsbS5i
+KQprPW8uYShILlZNKFsiYWRkLWhpbnQtbGluayIsImJlZm9yZS1hcHBseSIsImJ1dHRvbiJdLHEpKQpq
+PUouZFIobCkKai5WMSgwKQpqLkZWKDAsayl9fSwKQ0M6ZnVuY3Rpb24oYTgsYTksYjApe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMsYTQsYTUsYTYsYTcK
+Zm9yKHQ9YTguZixzPXQubGVuZ3RoLHI9dS5zLHE9dS5YLHA9dS5RLG89cC5DKCJ+KDEpIiksbj11Lk0s
+cD1wLmMsbT0wO208dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK20pe2w9dFttXQpr
+PWRvY3VtZW50Cmo9ay5jcmVhdGVFbGVtZW50KCJwIikKaT1xLmEoSC5WTShbInRyYWNlIl0scikpCmg9
+Si5kUihqKQpoLlYxKDApCmguRlYoMCxpKQpnPWE5LmFwcGVuZENoaWxkKGopCmo9ay5jcmVhdGVFbGVt
+ZW50KCJzcGFuIikKaT1xLmEoSC5WTShbInR5cGUtZGVzY3JpcHRpb24iXSxyKSkKaD1KLmRSKGopCmgu
+VjEoMCkKaC5GVigwLGkpCmouYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZShsLmEpKQpnLmFwcGVu
+ZENoaWxkKGopCmcuYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZSgiOiIpKQpqPWsuY3JlYXRlRWxl
+bWVudCgidWwiKQppPXEuYShILlZNKFsidHJhY2UiXSxyKSkKaD1KLmRSKGopCmguVjEoMCkKaC5GVigw
+LGkpCmY9Zy5hcHBlbmRDaGlsZChqKQpmb3Ioaj1sLmIsaT1qLmxlbmd0aCxlPTA7ZTxqLmxlbmd0aDtq
+Lmxlbmd0aD09PWl8fCgwLEgubGspKGopLCsrZSl7ZD1qW2VdCmM9ay5jcmVhdGVFbGVtZW50KCJsaSIp
+CmYuYXBwZW5kQ2hpbGQoYykKYj1rLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQphPXEuYShILlZNKFsiZnVu
+Y3Rpb24iXSxyKSkKaD1KLmRSKGIpCmguVjEoMCkKaC5GVigwLGEpCmE9ZC5iCkwua0QoYixhPT1udWxs
+PyJ1bmtub3duIjphKQpjLmFwcGVuZENoaWxkKGIpCmEwPWQuYwppZihhMCE9bnVsbCl7Yy5hcHBlbmRD
+aGlsZChrLmNyZWF0ZVRleHROb2RlKCIgKCIpKQphMT1hMC5iCmEyPWsuY3JlYXRlRWxlbWVudCgiYSIp
+CmEyLmFwcGVuZENoaWxkKGsuY3JlYXRlVGV4dE5vZGUoSC5kKGEwLmMpKyI6IitILmQoYTEpKSkKYTIu
+c2V0QXR0cmlidXRlKCJocmVmIixhMC5hKQphMi5jbGFzc0xpc3QuYWRkKCJuYXYtbGluayIpCmMuYXBw
+ZW5kQ2hpbGQoYTIpCmMuYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZSgiKSIpKX1jLmFwcGVuZENo
+aWxkKGsuY3JlYXRlVGV4dE5vZGUoIjogIikpCmI9ZC5hCkwua0QoYyxiPT1udWxsPyJ1bmtub3duIjpi
+KQpiPWQuZAppZihiLmxlbmd0aCE9PTApe2E9ay5jcmVhdGVFbGVtZW50KCJwIikKYTM9cS5hKEguVk0o
+WyJkcmF3ZXIiLCJiZWZvcmUtYXBwbHkiXSxyKSkKaD1KLmRSKGEpCmguVjEoMCkKaC5GVigwLGEzKQph
+ND1jLmFwcGVuZENoaWxkKGEpCmZvcihhPWIubGVuZ3RoLGE1PTA7YTU8Yi5sZW5ndGg7Yi5sZW5ndGg9
+PT1hfHwoMCxILmxrKShiKSwrK2E1KXthNj1iW2E1XQphMz1rLmNyZWF0ZUVsZW1lbnQoImJ1dHRvbiIp
+CmE3PW8uYShuZXcgTC5BUyhhNixhMCkpCm4uYShudWxsKQpXLkpFKGEzLCJjbGljayIsYTcsITEscCkK
+YTMuYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZShNLk9YKGE2LmEpKSkKYTQuYXBwZW5kQ2hpbGQo
+YTMpfX19fX0sCmtEOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPUguVk0oYi5zcGxpdCgiLiIpLHUucyks
+cT1DLk5tLmd0SChyKSxwPWRvY3VtZW50CmEuYXBwZW5kQ2hpbGQocC5jcmVhdGVUZXh0Tm9kZShxKSkK
+Zm9yKHE9SC5xQyhyLDEsbnVsbCx1Lk4pLHE9bmV3IEguYTcocSxxLmdBKHEpLHEuJHRpLkMoImE3PGFM
+LkU+IikpLHQ9Si5SRShhKTtxLkYoKTspe3M9cS5kCnQubnooYSwiYmVmb3JlZW5kIiwiJiM4MjAzOy4i
+LG51bGwsbnVsbCkKYS5hcHBlbmRDaGlsZChwLmNyZWF0ZVRleHROb2RlKHMpKX19LAplOmZ1bmN0aW9u
+IGUoKXt9LApWVzpmdW5jdGlvbiBWVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApv
+WjpmdW5jdGlvbiBvWigpe30sCmpyOmZ1bmN0aW9uIGpyKCl7fSwKcWw6ZnVuY3Rpb24gcWwoKXt9LAp5
+ODpmdW5jdGlvbiB5OCgpe30sCkhpOmZ1bmN0aW9uIEhpKCl7fSwKQlQ6ZnVuY3Rpb24gQlQoKXt9LApM
+OmZ1bmN0aW9uIEwoKXt9LApXeDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQU86
+ZnVuY3Rpb24gQU8oYSl7dGhpcy5hPWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9YX0sCkhvOmZ1
+bmN0aW9uIEhvKGEpe3RoaXMuYT1hfSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sCklDOmZ1bmN0aW9uIElDKCl7fSwKZkM6ZnVuY3Rpb24gZkMoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sCm5UOmZ1bmN0aW9uIG5UKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkJaOmZ1
+bmN0aW9uIEJaKGEpe3RoaXMuYT1hfSwKR0g6ZnVuY3Rpb24gR0goKXt9LApFRTpmdW5jdGlvbiBFRShh
+LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBRTChhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKVlM6ZnVuY3Rpb24gVlMoYSl7dGhpcy5hPWF9LApURDpmdW5jdGlvbiBURCgp
+e30sCkFTOmZ1bmN0aW9uIEFTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApYQTpmdW5jdGlvbiBYQSgp
+e30sCm1LOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuPUguVk0oW10sdS5maCkKZm9yKHQ9Si5J
+VCh1LlIuYShhKSk7dC5GKCk7KXtzPXQuZ2woKQpyPUouVTYocykKcT1MLnAyKEguYyhyLnEocywidHlw
+ZSIpKSkKcD1ILmMoci5xKHMsIm5hbWUiKSkKbz1yLnEocywic3VidHJlZSIpCm89bz09bnVsbD9udWxs
+OkwubUsobykKQy5ObS5pKG4sbmV3IEwuWloocSxwLG8sSC5jKHIucShzLCJwYXRoIikpLEguYyhyLnEo
+cywiaHJlZiIpKSxILldZKHIucShzLCJlZGl0Q291bnQiKSkpKX1yZXR1cm4gbn0sClZEOmZ1bmN0aW9u
+KGEpe3ZhciB0LHMscj1ILlZNKFtdLHUuSikKZm9yKHQ9YS5sZW5ndGgscz0wO3M8YS5sZW5ndGg7YS5s
+ZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3MpQy5ObS5pKHIsYVtzXS5MdCgpKQpyZXR1cm4gcn0sCnAy
+OmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlImRpcmVjdG9yeSI6cmV0dXJuIEMuWTIKY2FzZSJmaWxl
+IjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRocm93IEguYihQLlBWKCJVbnJlY29nbml6ZWQgbmF2aWdhdGlv
+biB0cmVlIG5vZGUgdHlwZTogIitILmQoYSkpKX19LAp2eTpmdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2Fz
+ZSBDLlkyOnJldHVybiJkaXJlY3RvcnkiCmNhc2UgQy5yZjpyZXR1cm4iZmlsZSJ9dGhyb3cgSC5iKFAu
+UFYoIlVucmVjb2duaXplZCBuYXZpZ2F0aW9uIHRyZWUgbm9kZSB0eXBlOiAiK2EuWigwKSkpfSwKWlo6
+ZnVuY3Rpb24gWlooYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQK
+Xy5lPWUKXy5mPWZ9LApPOTpmdW5jdGlvbiBPOShhKXt0aGlzLmI9YX0sCklWOmZ1bmN0aW9uIElWKGEs
+YixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxYPXsKQ0w6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzLHIscSxwLG89Yi54WihhKQpiLmhLKGEpCmlmKG8hPW51bGwpYT1KLktWKGEsby5s
+ZW5ndGgpCnQ9dS5zCnM9SC5WTShbXSx0KQpyPUguVk0oW10sdCkKdD1hLmxlbmd0aAppZih0IT09MCYm
+Yi5yNChDLnhCLlcoYSwwKSkpe2lmKDA+PXQpcmV0dXJuIEguayhhLDApCkMuTm0uaShyLGFbMF0pCnE9
+MX1lbHNle0MuTm0uaShyLCIiKQpxPTB9Zm9yKHA9cTtwPHQ7KytwKWlmKGIucjQoQy54Qi5XKGEscCkp
+KXtDLk5tLmkocyxDLnhCLk5qKGEscSxwKSkKQy5ObS5pKHIsYVtwXSkKcT1wKzF9aWYocTx0KXtDLk5t
+LmkocyxDLnhCLkcoYSxxKSkKQy5ObS5pKHIsIiIpfXJldHVybiBuZXcgWC5XRChiLG8scyxyKX0sCldE
+OmZ1bmN0aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMKXy5lPWR9LApx
+UjpmdW5jdGlvbiBxUihhKXt0aGlzLmE9YX0sCkk3OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgWC5kdihh
+KX0sCmR2OmZ1bmN0aW9uIGR2KGEpe3RoaXMuYT1hfX0sTz17ClJoOmZ1bmN0aW9uKCl7dmFyIHQscz1u
+dWxsCmlmKFAudW8oKS5nRmkoKSE9PSJmaWxlIilyZXR1cm4gJC5FYigpCnQ9UC51bygpCmlmKCFDLnhC
+LlRjKHQuZ0lpKHQpLCIvIikpcmV0dXJuICQuRWIoKQppZihQLktMKHMsImEvYiIscyxzLHMscyxzKS50
+NCgpPT09ImFcXGIiKXJldHVybiAkLktrKCkKcmV0dXJuICQuYkQoKX0sCnpMOmZ1bmN0aW9uIHpMKCl7
+fX0sRT17T0Y6ZnVuY3Rpb24gT0YoYSxiLGMpe3RoaXMuZD1hCnRoaXMuZT1iCnRoaXMuZj1jfX0sRj17
+cnU6ZnVuY3Rpb24gcnUoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19
+LEQ9ewpSWDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9bnVsbAp0cnl7cD1QLnVvKCl9Y2F0Y2godCl7
+aWYodS5nOC5iKEguUnUodCkpKXtzPSQuRmYKaWYocyE9bnVsbClyZXR1cm4gcwp0aHJvdyB0fWVsc2Ug
+dGhyb3cgdH1pZihKLlJNKHAsJC5JNikpcmV0dXJuICQuRmYKJC5JNj1wCmlmKCQuSGsoKT09JC5FYigp
+KXM9JC5GZj1wLlpJKCIuIikuWigwKQplbHNle3I9cC50NCgpCnE9ci5sZW5ndGgtMQpzPSQuRmY9cT09
+PTA/cjpDLnhCLk5qKHIsMCxxKX1yZXR1cm4gc319CnZhciB3PVtDLEgsSixQLFcsTSxVLEIsVCxMLFgs
+TyxFLEYsRF0KaHVua0hlbHBlcnMuc2V0RnVuY3Rpb25OYW1lc0lmTmVjZXNzYXJ5KHcpCnZhciAkPXt9
+CkguRksucHJvdG90eXBlPXt9CkoudkIucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+YT09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEoYSl9LApaOmZ1bmN0aW9uKGEpe3JldHVy
+biJJbnN0YW5jZSBvZiAnIitILmQoSC5saChhKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8uYShi
+KQp0aHJvdyBILmIoUC5scihhLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9fQpKLnlFLnByb3RvdHlw
+ZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4g
+YT81MTkwMTg6MjE4MTU5fSwKJGlhMjoxfQpKLllFLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIG51bGw9PWJ9LApaOmZ1bmN0aW9uKGEpe3JldHVybiJudWxsIn0sCmdpTzpmdW5jdGlvbihh
+KXtyZXR1cm4gMH0sCmU3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU2ooYSx1Lm8uYShiKSl9LAok
+aWM4OjF9CkouTUYucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfSwKWjpmdW5jdGlv
+bihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl2bToxfQpKLmlDLnByb3RvdHlwZT17fQpKLmtkLnByb3Rv
+dHlwZT17fQpKLmM1LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9YVskLndRKCldCmlmKHQ9
+PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILmQo
+Si5BYyh0KSl9LAokUzpmdW5jdGlvbigpe3JldHVybntmdW5jOjEsb3B0OlssLCwsLCwsLCwsLCwsLCws
+XX19LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKaTpmdW5jdGlvbihhLGIpe0gudDYoYSkuYy5hKGIp
+CmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGQiKSkKYS5wdXNoKGIpfSwKVzQ6ZnVuY3Rp
+b24oYSxiKXt2YXIgdAppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgicmVtb3ZlQXQiKSkKdD1h
+Lmxlbmd0aAppZihiPj10KXRocm93IEguYihQLk83KGIsbnVsbCkpCnJldHVybiBhLnNwbGljZShiLDEp
+WzBdfSwKVUc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpILnQ2KGEpLkMoImNYPDE+IikuYShjKQpp
+ZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53QShi
+LDAsdCwiaW5kZXgiKQpzPWMubGVuZ3RoCnRoaXMuc0EoYSx0K3MpCnI9YitzCnRoaXMuWVcoYSxyLGEu
+bGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0sCm12OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhlZCRs
+ZW5ndGgpSC52aChQLkw0KCJyZW1vdmVMYXN0IikpCmlmKGEubGVuZ3RoPT09MCl0aHJvdyBILmIoSC5I
+WShhLC0xKSkKcmV0dXJuIGEucG9wKCl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0CkgudDYoYSkuQygi
+Y1g8MT4iKS5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGRBbGwiKSkKZm9yKHQ9
+Si5JVChiKTt0LkYoKTspYS5wdXNoKHQuZ2woKSl9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2
+KGEpLkMoIn4oMSkiKS5hKGIpCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKXtiLiQxKGFbc10pCmlm
+KGEubGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChhKSl9fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+PUgudDYoYSkKcmV0dXJuIG5ldyBILmxKKGEsdC5LcShjKS5DKCIxKDIpIikuYShiKSx0LkMoIkA8MT4i
+KS5LcShjKS5DKCJsSjwxLDI+IikpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9bmV3IEFycmF5KGEu
+bGVuZ3RoKQpzLmZpeGVkJGxlbmd0aD1BcnJheQpmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0KXRoaXMuWShz
+LHQsSC5kKGFbdF0pKQpyZXR1cm4gcy5qb2luKGIpfSwKTjA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
+cyxyCmQuYShiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmEoYykKdD1hLmxlbmd0aApmb3Iocz1i
+LHI9MDtyPHQ7KytyKXtzPWMuJDIocyxhW3JdKQppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQo
+YSkpfXJldHVybiBzfSwKSHQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89SC50NihhKQpvLkMo
+ImEyKDEpIikuYShiKQpvLkMoIjEoKSIpLmEobnVsbCkKdD1hLmxlbmd0aApmb3Iocz1udWxsLHI9ITEs
+cT0wO3E8dDsrK3Epe3A9YVtxXQppZihILm9UKGIuJDEocCkpKXtpZihyKXRocm93IEguYihILmRVKCkp
+CnM9cApyPSEwfWlmKHQhPT1hLmxlbmd0aCl0aHJvdyBILmIoUC5hNChhKSl9aWYocilyZXR1cm4gcwp0
+aHJvdyBILmIoSC5XcCgpKX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVy
+biBILmsoYSxiKQpyZXR1cm4gYVtiXX0sCkQ2OmZ1bmN0aW9uKGEsYixjKXtpZihiPDB8fGI+YS5sZW5n
+dGgpdGhyb3cgSC5iKFAuVEUoYiwwLGEubGVuZ3RoLCJzdGFydCIsbnVsbCkpCmlmKGM8Ynx8Yz5hLmxl
+bmd0aCl0aHJvdyBILmIoUC5URShjLGIsYS5sZW5ndGgsImVuZCIsbnVsbCkpCmlmKGI9PT1jKXJldHVy
+biBILlZNKFtdLEgudDYoYSkpCnJldHVybiBILlZNKGEuc2xpY2UoYixjKSxILnQ2KGEpKX0sCmd0SDpm
+dW5jdGlvbihhKXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEguYihILldwKCkpfSwKZ3Ja
+OmZ1bmN0aW9uKGEpe3ZhciB0PWEubGVuZ3RoCmlmKHQ+MClyZXR1cm4gYVt0LTFdCnRocm93IEguYihI
+LldwKCkpfSwKWVc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHI9SC50NihhKQpyLkMoImNYPDE+
+IikuYShkKQppZighIWEuaW1tdXRhYmxlJGxpc3QpSC52aChQLkw0KCJzZXRSYW5nZSIpKQpQLmpCKGIs
+YyxhLmxlbmd0aCkKdD1jLWIKaWYodD09PTApcmV0dXJuClAuazEoZSwic2tpcENvdW50IikKci5DKCJ6
+TTwxPiIpLmEoZCkKcj1KLlU2KGQpCmlmKGUrdD5yLmdBKGQpKXRocm93IEguYihILmFyKCkpCmlmKGU8
+Yilmb3Iocz10LTE7cz49MDstLXMpYVtiK3NdPXIucShkLGUrcykKZWxzZSBmb3Iocz0wO3M8dDsrK3Mp
+YVtiK3NdPXIucShkLGUrcyl9LAp2ZzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gdGhpcy5ZVyhhLGIs
+YyxkLDApfSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgudDYoYSkuQygiYTIoMSkiKS5hKGIpCnQ9
+YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKXtpZihILm9UKGIuJDEoYVtzXSkpKXJldHVybiEwCmlmKGEu
+bGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChhKSl9cmV0dXJuITF9LAp0ZzpmdW5jdGlvbihhLGIpe3Zh
+ciB0CmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpaWYoSi5STShhW3RdLGIpKXJldHVybiEwCnJldHVybiEx
+fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aD09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEubGVuZ3RoIT09MH0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0sCmdr
+ejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+Iikp
+fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
+bGVuZ3RofSwKc0E6ZnVuY3Rpb24oYSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgic2V0
+IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAuVEUoYiwwLG51bGwsIm5ld0xlbmd0aCIsbnVsbCkp
+CmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQppZihiPj1hLmxlbmd0aHx8YjwwKXRo
+cm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC50NihhKS5j
+LmEoYykKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgudmgoUC5MNCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49
+YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwK
+JGl6TToxfQpKLlBvLnByb3RvdHlwZT17fQpKLm0xLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj1zLmEscT1yLmxlbmd0aAppZihz
+LmIhPT1xKXRocm93IEguYihILmxrKHIpKQp0PXMuYwppZih0Pj1xKXtzLnNNKG51bGwpCnJldHVybiEx
+fXMuc00oclt0XSk7KytzLmMKcmV0dXJuITB9LApzTTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGku
+Yy5hKGEpfSwKJGlBbjoxfQpKLnFJLnByb3RvdHlwZT17Cnl1OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE+
+PS0yMTQ3NDgzNjQ4JiZhPD0yMTQ3NDgzNjQ3KXJldHVybiBhfDAKaWYoaXNGaW5pdGUoYSkpe3Q9YTww
+P01hdGguY2VpbChhKTpNYXRoLmZsb29yKGEpCnJldHVybiB0KzB9dGhyb3cgSC5iKFAuTDQoIiIrYSsi
+LnRvSW50KCkiKSl9LAp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0dXJuIE1hdGgu
+cm91bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRocm93IEguYihQ
+Lkw0KCIiK2ErIi5yb3VuZCgpIikpfSwKV1o6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQppZihiPDJ8
+fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbnVsbCkpCnQ9YS50b1N0cmluZyhiKQpp
+ZihDLnhCLm0odCx0Lmxlbmd0aC0xKSE9PTQxKXJldHVybiB0CnM9L14oW1xkYS16XSspKD86XC4oW1xk
+YS16XSspKT9cKGVcKyhcZCspXCkkLy5leGVjKHQpCmlmKHM9PW51bGwpSC52aChQLkw0KCJVbmV4cGVj
+dGVkIHRvU3RyaW5nIHJlc3VsdDogIit0KSkKcj1zLmxlbmd0aAppZigxPj1yKXJldHVybiBILmsocywx
+KQp0PXNbMV0KaWYoMz49cilyZXR1cm4gSC5rKHMsMykKcT0rc1szXQpyPXNbMl0KaWYociE9bnVsbCl7
+dCs9cgpxLT1yLmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sClo6ZnVuY3Rpb24oYSl7aWYo
+YT09PTAmJjEvYTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVuY3Rpb24oYSl7
+dmFyIHQscyxyLHEscD1hfDAKaWYoYT09PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0aC5hYnMoYSkK
+cz1NYXRoLmxvZyh0KS8wLjY5MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykKcT10PDE/dC9y
+OnIvdApyZXR1cm4gNTM2ODcwOTExJigocSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1NDIyNDMxODEx
+NzY1MjF8MCkpKjU5OTE5NytzKjEyNTl9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWElYgppZih0PT09
+MClyZXR1cm4gMAppZih0PjApcmV0dXJuIHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSByZXR1cm4gdCti
+fSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPjApdD10aGlzLnAzKGEsYikKZWxzZXt0PWI+MzE/
+MzE6Ygp0PWE+PnQ+Pj4wfXJldHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5i
+KEguSShiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGI+MzE/
+MDphPj4+Yn0sCiRpQ1A6MSwKJGlsZjoxfQpKLmJVLnByb3RvdHlwZT17JGlJZjoxfQpKLlZBLnByb3Rv
+dHlwZT17fQpKLkRyLnByb3RvdHlwZT17Cm06ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgu
+SFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52aChILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQo
+Yil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5sZW5ndGgpdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0
+dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILk5GKGIsYSww
+KX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyIpdGhyb3cgSC5iKFAuTDMoYixu
+dWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmxlbmd0aCxzPWEu
+bGVuZ3RoCmlmKHQ+cylyZXR1cm4hMQpyZXR1cm4gYj09PXRoaXMuRyhhLHMtdCl9LAppNzpmdW5jdGlv
+bihhLGIsYyxkKXt2YXIgdCxzCmM9UC5qQihiLGMsYS5sZW5ndGgpCnQ9YS5zdWJzdHJpbmcoMCxiKQpz
+PWEuc3Vic3RyaW5nKGMpCnJldHVybiB0K2Qrc30sClFpOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZigh
+SC5vayhjKSlILnZoKEguSShjKSkKaWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gYy5KKCkKaWYo
+YzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWMr
+Yi5sZW5ndGgKaWYodD5hLmxlbmd0aClyZXR1cm4hMQpyZXR1cm4gYj09PWEuc3Vic3RyaW5nKGMsdCl9
+LApuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUWkoYSxiLDApfSwKTmo6ZnVuY3Rpb24oYSxiLGMp
+e2lmKCFILm9rKGIpKUgudmgoSC5JKGIpKQppZihjPT1udWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIh
+PT0ibnVtYmVyIilyZXR1cm4gYi5KKCkKaWYoYjwwKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlmKGI+
+Yyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEguYihQLk83KGMsbnVs
+bCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLk5q
+KGEsYixudWxsKX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpmdW5j
+dGlvbihhKXt2YXIgdCxzLHIscT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBxCmlm
+KHRoaXMuVyhxLDApPT09MTMzKXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9MApz
+PXAtMQpyPXRoaXMubShxLHMpPT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4g
+cQpyZXR1cm4gcS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1i
+KXJldHVybiIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93
+IEguYihDLkVxKQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihi
+PT09MClicmVhawp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8
+Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4
+T2YoYixjKQpyZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwK
+UGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzww
+fHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVu
+Z3RoCnM9YS5sZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNu
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0PWEubGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1
+cm4gSC5tMihhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sClo6
+ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVu
+Z3RoLHM9MCxyPTA7cjx0Oysrcil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4NzA5
+MTEmcysoKDUyNDI4NyZzKTw8MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwz
+KQpzXj1zPj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24o
+YSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj49YS5sZW5ndGh8
+fCExKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgucWou
+cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIEMueEIubSh0aGlzLmEsSC5XWShiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFM
+LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzCnJldHVybiBuZXcgSC5hNyh0LHQu
+Z0EodCksSC5MaCh0KS5DKCJhNzxhTC5FPiIpKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5n
+QSh0aGlzKT09PTB9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhpcyxwPXEuZ0EocSkKaWYo
+Yi5sZW5ndGghPT0wKXtpZihwPT09MClyZXR1cm4iIgp0PUguZChxLkUoMCwwKSkKaWYocCE9PXEuZ0Eo
+cSkpdGhyb3cgSC5iKFAuYTQocSkpCmZvcihzPXQscj0xO3I8cDsrK3Ipe3M9cytiK0guZChxLkUoMCxy
+KSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9
+PTA/czpzfWVsc2V7Zm9yKHI9MCxzPSIiO3I8cDsrK3Ipe3MrPUguZChxLkUoMCxyKSkKaWYocCE9PXEu
+Z0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfX0sCmV2
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMoImEyKGFMLkUpIikuYShi
+KSl9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEgubEoodGhp
+cyx0LktxKGMpLkMoIjEoYUwuRSkiKS5hKGIpLHQuQygiQDxhTC5FPiIpLktxKGMpLkMoImxKPDEsMj4i
+KSl9LAp0dDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcyxyPUguVk0oW10sSC5MaChzKS5DKCJqZDxh
+TC5FPiIpKQpDLk5tLnNBKHIscy5nQShzKSkKZm9yKHQ9MDt0PHMuZ0Eocyk7Kyt0KUMuTm0uWShyLHQs
+cy5FKDAsdCkpCnJldHVybiByfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudHQoYSwhMCl9fQpI
+Lm5ILnByb3RvdHlwZT17CmdVRDpmdW5jdGlvbigpe3ZhciB0PUouSCh0aGlzLmEpLHM9dGhpcy5jCmlm
+KHM9PW51bGx8fHM+dClyZXR1cm4gdApyZXR1cm4gc30sCmdBczpmdW5jdGlvbigpe3ZhciB0PUouSCh0
+aGlzLmEpLHM9dGhpcy5iCmlmKHM+dClyZXR1cm4gdApyZXR1cm4gc30sCmdBOmZ1bmN0aW9uKGEpe3Zh
+ciB0LHM9Si5IKHRoaXMuYSkscj10aGlzLmIKaWYocj49cylyZXR1cm4gMAp0PXRoaXMuYwppZih0PT1u
+dWxsfHx0Pj1zKXJldHVybiBzLXIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5ITigpCnJl
+dHVybiB0LXJ9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5nQXMoKStiCmlmKGI+PTAp
+e3Q9cy5nVUQoKQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiBILnBZKHQpCnQ9cj49dH1lbHNl
+IHQ9ITAKaWYodCl0aHJvdyBILmIoUC50KGIscywiaW5kZXgiLG51bGwsbnVsbCkpCnJldHVybiBKLkdB
+KHMuYSxyKX19CkguYTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpm
+dW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYocikscD1xLmdBKHIpCmlmKHMuYiE9PXAp
+dGhyb3cgSC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Muc0kobnVsbCkKcmV0dXJuITF9cy5zSShx
+LkUocix0KSk7KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuYy5h
+KGEpfSwKJGlBbjoxfQpILmkxLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD1ILkxoKHRo
+aXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHQuQygiQDwxPiIpLktxKHQuUVsx
+XSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkgodGhpcy5hKX19CkgueHku
+cHJvdG90eXBlPXskaWJROjF9CkguTUgucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMs
+cz10LmIKaWYocy5GKCkpe3Quc0kodC5jLiQxKHMuZ2woKSkpCnJldHVybiEwfXQuc0kobnVsbCkKcmV0
+dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9
+dGhpcy4kdGkuUVsxXS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4g
+Si5IKHRoaXMuYSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYi4kMShKLkdBKHRoaXMuYSxi
+KSl9fQpILlU1LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEgudkcoSi5JVCh0
+aGlzLmEpLHRoaXMuYix0aGlzLiR0aS5DKCJ2RzwxPiIpKX19CkgudkcucHJvdG90eXBlPXsKRjpmdW5j
+dGlvbigpe3ZhciB0LHMKZm9yKHQ9dGhpcy5hLHM9dGhpcy5iO3QuRigpOylpZihILm9UKHMuJDEodC5n
+bCgpKSkpcmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19
+CkguU1UucHJvdG90eXBlPXt9CkguUmUucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5MaCh0
+aGlzKS5DKCJSZS5FIikuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBhbiB1bm1vZGlm
+aWFibGUgbGlzdCIpKX19CkgudzIucHJvdG90eXBlPXt9Ckgud3YucHJvdG90eXBlPXsKZ2lPOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuX2hhc2hDb2RlCmlmKHQhPW51bGwpcmV0dXJuIHQKdD01MzY4NzA5MTEm
+NjY0NTk3KkouaGYodGhpcy5hKQp0aGlzLl9oYXNoQ29kZT10CnJldHVybiB0fSwKWjpmdW5jdGlvbihh
+KXtyZXR1cm4nU3ltYm9sKCInK0guZCh0aGlzLmEpKyciKSd9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9
+PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0aGlzLmE9PWIuYX0sCiRpR0Q6
+MX0KSC5QRC5wcm90b3R5cGU9e30KSC5XVS5wcm90b3R5cGU9ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuZ0EodGhpcyk9PT0wfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sClk6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdC5jLmEoYikKdC5RWzFdLmEoYykKcmV0dXJuIEgu
+ZGMoKX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5xNChhLEguTGgodGhpcykuQygiTjM8MSwy
+PiIpKX0sCnE0OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwpyZXR1cm4gUC5sMChmdW5jdGlvbigpe3Zh
+ciBzPWEKdmFyIHI9MCxxPTEscCxvLG4sbQpyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQpe2lm
+KGM9PT0xKXtwPWQKcj1xfXdoaWxlKHRydWUpc3dpdGNoKHIpe2Nhc2UgMDpvPXQuZ1YoKSxvPW8uZ2t6
+KG8pLG49SC5MaCh0KSxuPW4uQygiQDwxPiIpLktxKG4uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjpp
+Zighby5GKCkpe3I9MwpicmVha31tPW8uZ2woKQpyPTQKcmV0dXJuIG5ldyBQLk4zKG0sdC5xKDAsbSks
+bikKY2FzZSA0OnI9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0o
+cCl9fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19w
+cm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVu
+Y3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5EKGIpfSwKRDpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0guYyhhKV19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
+LHEscD1ILkxoKHRoaXMpCnAuQygifigxLDIpIikuYShiKQp0PXRoaXMuYwpmb3Iocz10Lmxlbmd0aCxw
+PXAuUVsxXSxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxwLmEodGhpcy5EKHEpKSl9fSwKZ1Y6ZnVu
+Y3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhSPDE+IikpfX0KSC5YUi5w
+cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmMKcmV0dXJuIG5ldyBKLm0xKHQs
+dC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
+Yy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYQpyZXR1
+cm4gdH0sCmduZDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwppZihwLmM9PT0xKXJldHVybiBD
+LmhVCnQ9cC5kCnM9dC5sZW5ndGgtcC5lLmxlbmd0aC1wLmYKaWYocz09PTApcmV0dXJuIEMuaFUKcj1b
+XQpmb3IocT0wO3E8czsrK3Epe2lmKHE+PXQubGVuZ3RoKXJldHVybiBILmsodCxxKQpyLnB1c2godFtx
+XSl9cmV0dXJuIEoudW4ocil9LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhp
+cwppZihsLmMhPT0wKXJldHVybiBDLkR4CnQ9bC5lCnM9dC5sZW5ndGgKcj1sLmQKcT1yLmxlbmd0aC1z
+LWwuZgppZihzPT09MClyZXR1cm4gQy5EeApwPW5ldyBILk41KHUuZW8pCmZvcihvPTA7bzxzOysrbyl7
+aWYobz49dC5sZW5ndGgpcmV0dXJuIEguayh0LG8pCm49dFtvXQptPXErbwppZihtPDB8fG0+PXIubGVu
+Z3RoKXJldHVybiBILmsocixtKQpwLlkoMCxuZXcgSC53dihuKSxyW21dKX1yZXR1cm4gbmV3IEguUEQo
+cCx1LmdGKX0sCiRpdlE6MX0KSC5Dai5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0Ckgu
+YyhhKQp0PXRoaXMuYQp0LmI9dC5iKyIkIitILmQoYSkKQy5ObS5pKHRoaXMuYixhKQpDLk5tLmkodGhp
+cy5jLGIpOysrdC5hfSwKJFM6MTJ9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24oYSl7dmFyIHQs
+cyxyPXRoaXMscT1uZXcgUmVnRXhwKHIuYSkuZXhlYyhhKQppZihxPT1udWxsKXJldHVybiBudWxsCnQ9
+T2JqZWN0LmNyZWF0ZShudWxsKQpzPXIuYgppZihzIT09LTEpdC5hcmd1bWVudHM9cVtzKzFdCnM9ci5j
+CmlmKHMhPT0tMSl0LmFyZ3VtZW50c0V4cHI9cVtzKzFdCnM9ci5kCmlmKHMhPT0tMSl0LmV4cHI9cVtz
+KzFdCnM9ci5lCmlmKHMhPT0tMSl0Lm1ldGhvZD1xW3MrMV0Kcz1yLmYKaWYocyE9PS0xKXQucmVjZWl2
+ZXI9cVtzKzFdCnJldHVybiB0fX0KSC5XMC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuYgppZih0PT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILmQodGhpcy5hKQpyZXR1
+cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3QrIicgb24gbnVsbCJ9fQpI
+LmF6LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9Ik5vU3VjaE1ldGhvZEVy
+cm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixxPXMuYgppZihxPT1udWxsKXJldHVybiJOb1N1Y2hNZXRo
+b2RFcnJvcjogIitILmQocy5hKQp0PXMuYwppZih0PT1udWxsKXJldHVybiByK3ErIicgKCIrSC5kKHMu
+YSkrIikiCnJldHVybiByK3ErIicgb24gJyIrdCsiJyAoIitILmQocy5hKSsiKSJ9fQpILnZWLnByb3Rv
+dHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0Lmxlbmd0aD09PTA/IkVycm9y
+IjoiRXJyb3I6ICIrdH19CkguYnEucHJvdG90eXBlPXt9CkguQW0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
+b24oYSl7aWYodS5XLmIoYSkpaWYoYS4kdGhyb3duSnNFcnJvcj09bnVsbClhLiR0aHJvd25Kc0Vycm9y
+PXRoaXMuYQpyZXR1cm4gYX0sCiRTOjF9CkguWE8ucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIg
+dCxzPXRoaXMuYgppZihzIT1udWxsKXJldHVybiBzCnM9dGhpcy5hCnQ9cyE9PW51bGwmJnR5cGVvZiBz
+PT09Im9iamVjdCI/cy5zdGFjazpudWxsCnJldHVybiB0aGlzLmI9dD09bnVsbD8iIjp0fSwKJGlHejox
+fQpILlRwLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jb25zdHJ1Y3RvcixzPXQ9
+PW51bGw/bnVsbDp0Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5OUShzPT1udWxsPyJ1bmtub3duIjpz
+KSsiJyJ9LAokaUVIOjEsCmdRbDpmdW5jdGlvbigpe3JldHVybiB0aGlzfSwKJEM6IiQxIiwKJFI6MSwK
+JEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3Zh
+ciB0PXRoaXMuJHN0YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0dXJuIkNsb3N1cmUgb2YgdW5rbm93biBz
+dGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHQpKyInIn19CkguankucHJvdG90eXBl
+PXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodD09PWIp
+cmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5qeSkpcmV0dXJuITEKcmV0dXJuIHQuYT09PWIuYSYm
+dC5iPT09Yi5iJiZ0LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmMKaWYocz09
+bnVsbCl0PUguZVEodGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMhPT0ib2JqZWN0Ij9KLmhmKHMpOkguZVEo
+cykKcmV0dXJuKHReSC5lUSh0aGlzLmIpKT4+PjB9LApaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpp
+Zih0PT1udWxsKXQ9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guZCh0aGlzLmQpKyInIG9mICIrKCJJ
+bnN0YW5jZSBvZiAnIitILmQoSC5saCh0KSkrIiciKX19CkguRXEucHJvdG90eXBlPXsKWjpmdW5jdGlv
+bihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK0guZCh0aGlzLmEpfX0KSC5rWS5wcm90b3R5cGU9ewpa
+OmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AuaCh0aGlzLmEpfX0KSC5ONS5w
+cm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ2wwOmZ1bmN0aW9uKGEpe3Jl
+dHVybiB0aGlzLmE9PT0wfSwKZ1Y6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguaTUodGhpcyxILkxoKHRo
+aXMpLkMoImk1PDE+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7dmFyIHQscwppZih0eXBlb2YgYT09InN0cmlu
+ZyIpe3Q9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuWHUodCxhKX1lbHNle3M9
+dGhpcy5DWChhKQpyZXR1cm4gc319LApDWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQKaWYodD09bnVs
+bClyZXR1cm4hMQpyZXR1cm4gdGhpcy5GaCh0aGlzLkJ0KHQsSi5oZihhKSYweDNmZmZmZmYpLGEpPj0w
+fSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhpcyxvPW51bGwKaWYodHlwZW9mIGI9PSJz
+dHJpbmciKXt0PXAuYgppZih0PT1udWxsKXJldHVybiBvCnM9cC5qMih0LGIpCnI9cz09bnVsbD9vOnMu
+YgpyZXR1cm4gcn1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3E9
+cC5jCmlmKHE9PW51bGwpcmV0dXJuIG8Kcz1wLmoyKHEsYikKcj1zPT1udWxsP286cy5iCnJldHVybiBy
+fWVsc2UgcmV0dXJuIHAuYWEoYil9LAphYTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcy5kCmlmKHI9
+PW51bGwpcmV0dXJuIG51bGwKdD10aGlzLkJ0KHIsSi5oZihhKSYweDNmZmZmZmYpCnM9dGhpcy5GaCh0
+LGEpCmlmKHM8MClyZXR1cm4gbnVsbApyZXR1cm4gdFtzXS5ifSwKWTpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQscyxyLHEscCxvLG49dGhpcyxtPUguTGgobikKbS5jLmEoYikKbS5RWzFdLmEoYykKaWYodHlwZW9m
+IGI9PSJzdHJpbmciKXt0PW4uYgpuLkVIKHQ9PW51bGw/bi5iPW4ueksoKTp0LGIsYyl9ZWxzZSBpZih0
+eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1iKXtzPW4uYwpuLkVIKHM9PW51bGw/bi5j
+PW4ueksoKTpzLGIsYyl9ZWxzZXtyPW4uZAppZihyPT1udWxsKXI9bi5kPW4ueksoKQpxPUouaGYoYikm
+MHgzZmZmZmZmCnA9bi5CdChyLHEpCmlmKHA9PW51bGwpbi5FSShyLHEsW24uSG4oYixjKV0pCmVsc2V7
+bz1uLkZoKHAsYikKaWYobz49MClwW29dLmI9YwplbHNlIHAucHVzaChuLkhuKGIsYykpfX19LApLOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKSC5MaChyKS5DKCJ+KDEsMikiKS5hKGIpCnQ9ci5lCnM9
+ci5yCmZvcig7dCE9bnVsbDspe2IuJDIodC5hLHQuYikKaWYocyE9PXIucil0aHJvdyBILmIoUC5hNChy
+KSkKdD10LmN9fSwKRUg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9dGhpcyxyPUguTGgocykKci5jLmEo
+YikKci5RWzFdLmEoYykKdD1zLmoyKGEsYikKaWYodD09bnVsbClzLkVJKGEsYixzLkhuKGIsYykpCmVs
+c2UgdC5iPWN9LAprczpmdW5jdGlvbigpe3RoaXMucj10aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0
+aW9uKGEsYil7dmFyIHQscz10aGlzLHI9SC5MaChzKSxxPW5ldyBILmRiKHIuYy5hKGEpLHIuUVsxXS5h
+KGIpKQppZihzLmU9PW51bGwpcy5lPXMuZj1xCmVsc2V7dD1zLmYKcS5kPXQKcy5mPXQuYz1xfSsrcy5h
+CnMua3MoKQpyZXR1cm4gcX0sCkZoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJldHVy
+bi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBzCnJl
+dHVybi0xfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCmoyOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIGFbYl19LApCdDpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKRUk6ZnVuY3Rpb24oYSxi
+LGMpe2FbYl09Y30sCnJuOmZ1bmN0aW9uKGEsYil7ZGVsZXRlIGFbYl19LApYdTpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLmoyKGEsYikhPW51bGx9LAp6SzpmdW5jdGlvbigpe3ZhciB0PSI8bm9uLWlkZW50
+aWZpZXIta2V5PiIscz1PYmplY3QuY3JlYXRlKG51bGwpCnRoaXMuRUkocyx0LHMpCnRoaXMucm4ocyx0
+KQpyZXR1cm4gc30sCiRpRm86MX0KSC5kYi5wcm90b3R5cGU9e30KSC5pNS5wcm90b3R5cGU9ewpnQTpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmF9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5h
+PT09MH0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz1uZXcgSC5ONih0LHQucix0aGlzLiR0
+aS5DKCJONjwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
+cy5hLng0KGIpfX0KSC5ONi5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApG
+OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYQppZih0LmIhPT1zLnIpdGhyb3cgSC5iKFAuYTQocykp
+CmVsc2V7cz10LmMKaWYocz09bnVsbCl7dC5zcVkobnVsbCkKcmV0dXJuITF9ZWxzZXt0LnNxWShzLmEp
+CnQuYz10LmMuYwpyZXR1cm4hMH19fSwKc3FZOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5jLmEo
+YSl9LAokaUFuOjF9Ckguci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKGEp
+fSwKJFM6MX0KSC5kQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEoYSxi
+KX0sCiRTOjQ2fQpILndOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoSC5j
+KGEpKX0sCiRTOjM5fQpILlZSLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIlJlZ0V4cC8i
+K3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYwpp
+ZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0LmM9SC52NCh0LmEscy5tdWx0aWxpbmUsIXMu
+aWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITApfSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+bmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuZ0hjKCkKcy5s
+YXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxsKXJldHVybiBudWxsCnJldHVybiBuZXcgSC5F
+Syh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIg
+dApILldZKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3RoKXJldHVybiBILmsodCxiKQpyZXR1cm4gdFti
+XX0sCiRpT2Q6MSwKJGlpYjoxfQpILktXLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IEguUGIodGhpcy5hLHRoaXMuYix0aGlzLmMpfX0KSC5QYi5wcm90b3R5cGU9ewpnbDpmdW5jdGlv
+bigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89cC5iCmlm
+KG89PW51bGwpcmV0dXJuITEKdD1wLmMKaWYodDw9by5sZW5ndGgpe3M9cC5hCnI9cy5VWihvLHQpCmlm
+KHIhPW51bGwpe3AuZD1yCm89ci5iCnQ9by5pbmRleApxPXQrb1swXS5sZW5ndGgKaWYodD09PXEpe2lm
+KHMuYi51bmljb2RlKXtvPXAuYwp0PW8rMQpzPXAuYgppZih0PHMubGVuZ3RoKXtvPUouclkocykubShz
+LG8pCmlmKG8+PTU1Mjk2JiZvPD01NjMxOSl7bz1DLnhCLm0ocyx0KQpvPW8+PTU2MzIwJiZvPD01NzM0
+M31lbHNlIG89ITF9ZWxzZSBvPSExfWVsc2Ugbz0hMQpxPShvP3ErMTpxKSsxfXAuYz1xCnJldHVybiEw
+fX1wLmI9cC5kPW51bGwKcmV0dXJuITF9LAokaUFuOjF9CkgudFEucHJvdG90eXBlPXsKcTpmdW5jdGlv
+bihhLGIpe0guV1koYikKaWYoYiE9PTApSC52aChQLk83KGIsbnVsbCkpCnJldHVybiB0aGlzLmN9LAok
+aU9kOjF9CkguTkYucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5TZCh0aGlz
+LmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9
+dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5hLG09bi5sZW5ndGgKaWYocStvPm0pe3IuZD1u
+dWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYodDwwKXtyLmM9bSsxCnIuZD1udWxsCnJldHVy
+biExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1zPT09ci5jP3MrMTpzCnJldHVybiEwfSwKZ2w6
+ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjoxfQpILmVILnByb3RvdHlwZT17JGllSDoxLCRp
+ZXE6MX0KSC5MWi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhq
+OjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChiLGEsYS5sZW5n
+dGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5kaihjKQpILm9kKGIsYSxhLmxlbmd0
+aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSC5QZy5wcm90b3R5cGU9ewpZOmZ1bmN0
+aW9uKGEsYixjKXtILldZKGMpCkgub2QoYixhLGEubGVuZ3RoKQphW2JdPWN9LAokaWJROjEsCiRpY1g6
+MSwKJGl6TToxfQpILnhqLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixh
+LGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZEUucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gu
+V1koYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5aQS5wcm90b3R5cGU9ewpxOmZ1
+bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILndmLnBy
+b3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4g
+YVtiXX19CkguUHEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChiLGEsYS5s
+ZW5ndGgpCnJldHVybiBhW2JdfX0KSC5lRS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4g
+YS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJu
+IGFbYl19fQpILlY2LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6
+ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sCiRpVjY6
+MSwKJGluNjoxfQpILlJHLnByb3RvdHlwZT17fQpILlZQLnByb3RvdHlwZT17fQpILldCLnByb3RvdHlw
+ZT17fQpILlpHLnByb3RvdHlwZT17fQpILkpjLnByb3RvdHlwZT17CkM6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEguY0Uodi50eXBlVW5pdmVyc2UsdGhpcyxhKX0sCktxOmZ1bmN0aW9uKGEpe3JldHVybiBILnY1KHYu
+dHlwZVVuaXZlcnNlLHRoaXMsYSl9fQpILkVULnByb3RvdHlwZT17fQpILnU5LnByb3RvdHlwZT17Clo6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX19CkgueC5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz10LmEKdC5hPW51bGwKcy4kMCgpfSwKJFM6MTB9
+ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp0aGlzLmEuYT11Lk0uYShhKQp0
+PXRoaXMuYgpzPXRoaXMuYwp0LmZpcnN0Q2hpbGQ/dC5yZW1vdmVDaGlsZChzKTp0LmFwcGVuZENoaWxk
+KHMpfSwKJFM6MjB9ClAuVnMucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRD
+OiIkMCIsCiRSOjAsCiRTOjB9ClAuRnQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAo
+KX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuVzMucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtp
+ZihzZWxmLnNldFRpbWVvdXQhPW51bGwpc2VsZi5zZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxi
+KSwwKSxhKQplbHNlIHRocm93IEguYihQLkw0KCJgc2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0K
+UC55SC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwK
+JFM6Mn0KUC5paC5wcm90b3R5cGU9ewphTTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzLiR0aQpy
+LkMoIjEvIikuYShiKQp0PSF0aGlzLmJ8fHIuQygiYjg8MT4iKS5iKGIpCnM9dGhpcy5hCmlmKHQpcy5Y
+ZihiKQplbHNlIHMuWDIoci5jLmEoYikpfSwKdzA6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihiPT1udWxs
+KWI9UC52MChhKQp0PXRoaXMuYQppZih0aGlzLmIpdC5aTChhLGIpCmVsc2UgdC5OayhhLGIpfX0KUC5X
+TS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLiQyKDAsYSl9LAokUzo1MH0K
+UC5TWC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS4kMigxLG5ldyBILmJxKGEsdS5s
+LmEoYikpKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjIxfQpQLkdzLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9u
+KGEsYil7dGhpcy5hKEguV1koYSksYil9LAokUzoyNn0KUC5GeS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9u
+KGEpe3JldHVybiJJdGVyYXRpb25NYXJrZXIoIit0aGlzLmIrIiwgIitILmQodGhpcy5hKSsiKSJ9fQpQ
+LkdWLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJu
+IHRoaXMuYgpyZXR1cm4gdGhpcy4kdGkuYy5hKHQuZ2woKSl9LApGOmZ1bmN0aW9uKCl7dmFyIHQscyxy
+LHEscD10aGlzCmZvcig7ITA7KXt0PXAuYwppZih0IT1udWxsKWlmKHQuRigpKXJldHVybiEwCmVsc2Ug
+cC5jPW51bGwKcz1mdW5jdGlvbihhLGIsYyl7dmFyIG8sbj1iCndoaWxlKHRydWUpdHJ5e3JldHVybiBh
+KG4sbyl9Y2F0Y2gobSl7bz1tCm49Y319KHAuYSwwLDEpCmlmKHMgaW5zdGFuY2VvZiBQLkZ5KXtyPXMu
+YgppZihyPT09Mil7dD1wLmQKaWYodD09bnVsbHx8dC5sZW5ndGg9PT0wKXtwLnNFQyhudWxsKQpyZXR1
+cm4hMX1pZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEpCnAuYT10LnBvcCgpCmNvbnRpbnVlfWVs
+c2V7dD1zLmEKaWYocj09PTMpdGhyb3cgdAplbHNle3E9Si5JVCh0KQppZihxIGluc3RhbmNlb2YgUC5H
+Vil7dD1wLmQKaWYodD09bnVsbCl0PXAuZD1bXQpDLk5tLmkodCxwLmEpCnAuYT1xLmEKY29udGludWV9
+ZWxzZXtwLmM9cQpjb250aW51ZX19fX1lbHNle3Auc0VDKHMpCnJldHVybiEwfX1yZXR1cm4hMX0sCnNF
+QzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuYy5hKGEpfSwKJGlBbjoxfQpQLnE0LnByb3RvdHlw
+ZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuR1YodGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8
+MT4iKSl9fQpQLmI4LnByb3RvdHlwZT17fQpQLlBmLnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7
+dmFyIHQKUC5VSShhLCJlcnJvciIsdS5LKQp0PXRoaXMuYQppZih0LmEhPT0wKXRocm93IEguYihQLlBW
+KCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5OayhhLGI9PW51bGw/UC52MChhKTpiKX0sCnBt
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLncwKGEsbnVsbCl9fQpQLlpmLnByb3RvdHlwZT17CmFNOmZ1
+bmN0aW9uKGEsYil7dmFyIHQKdGhpcy4kdGkuQygiMS8iKS5hKGIpCnQ9dGhpcy5hCmlmKHQuYSE9PTAp
+dGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQp0LlhmKGIpfX0KUC5GZS5w
+cm90b3R5cGU9ewpIUjpmdW5jdGlvbihhKXtpZigodGhpcy5jJjE1KSE9PTYpcmV0dXJuITAKcmV0dXJu
+IHRoaXMuYi5iLmJ2KHUuYWwuYSh0aGlzLmQpLGEuYSx1LnksdS5LKX0sCkt3OmZ1bmN0aW9uKGEpe3Zh
+ciB0PXRoaXMuZSxzPXUueixyPXUuSyxxPXRoaXMuJHRpLkMoIjIvIikscD10aGlzLmIuYgppZih1LmFn
+LmIodCkpcmV0dXJuIHEuYShwLnJwKHQsYS5hLGEuYixzLHIsdS5sKSkKZWxzZSByZXR1cm4gcS5hKHAu
+YnYodS5iSS5hKHQpLGEuYSxzLHIpKX19ClAudnMucHJvdG90eXBlPXsKU3E6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0LHMscixxPXRoaXMuJHRpCnEuS3EoYykuQygiMS8oMikiKS5hKGEpCnQ9JC5YMwppZih0IT09
+Qy5OVSl7Yy5DKCJAPDAvPiIpLktxKHEuYykuQygiMSgyKSIpLmEoYSkKaWYoYiE9bnVsbCliPVAuVkgo
+Yix0KX1zPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpyPWI9PW51bGw/MTozCnRoaXMueGYobmV3
+IFAuRmUocyxyLGEsYixxLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gc30sClc3
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxsLGIpfSwKUWQ6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0LHM9dGhpcy4kdGkKcy5LcShjKS5DKCIxLygyKSIpLmEoYSkKdD1uZXcgUC52cygkLlgzLGMu
+QygidnM8MD4iKSkKdGhpcy54ZihuZXcgUC5GZSh0LDE5LGEsYixzLkMoIkA8MT4iKS5LcShjKS5DKCJG
+ZTwxLDI+IikpKQpyZXR1cm4gdH0sCnhmOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPXMuYQppZihy
+PD0xKXthLmE9dS54LmEocy5jKQpzLmM9YX1lbHNle2lmKHI9PT0yKXt0PXUuXy5hKHMuYykKcj10LmEK
+aWYocjw0KXt0LnhmKGEpCnJldHVybn1zLmE9cgpzLmM9dC5jfVAuVGsobnVsbCxudWxsLHMuYix1Lk0u
+YShuZXcgUC5kYShzLGEpKSl9fSwKalE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvPXRoaXMsbj17
+fQpuLmE9YQppZihhPT1udWxsKXJldHVybgp0PW8uYQppZih0PD0xKXtzPXUueC5hKG8uYykKcj1vLmM9
+YQppZihzIT1udWxsKXtmb3IoO3E9ci5hLHEhPW51bGw7cj1xKTtyLmE9c319ZWxzZXtpZih0PT09Mil7
+cD11Ll8uYShvLmMpCnQ9cC5hCmlmKHQ8NCl7cC5qUShhKQpyZXR1cm59by5hPXQKby5jPXAuY31uLmE9
+by5OOChhKQpQLlRrKG51bGwsbnVsbCxvLmIsdS5NLmEobmV3IFAub1EobixvKSkpfX0sCmFoOmZ1bmN0
+aW9uKCl7dmFyIHQ9dS54LmEodGhpcy5jKQp0aGlzLmM9bnVsbApyZXR1cm4gdGhpcy5OOCh0KX0sCk44
+OmZ1bmN0aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLHM9bnVsbDt0IT1udWxsO3M9dCx0PXIpe3I9dC5h
+CnQuYT1zfXJldHVybiBzfSwKSEg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9cy4kdGkKci5DKCIx
+LyIpLmEoYSkKaWYoci5DKCJiODwxPiIpLmIoYSkpaWYoci5iKGEpKVAuQTkoYSxzKQplbHNlIFAuazMo
+YSxzKQplbHNle3Q9cy5haCgpCnIuYy5hKGEpCnMuYT00CnMuYz1hClAuSFoocyx0KX19LApYMjpmdW5j
+dGlvbihhKXt2YXIgdCxzPXRoaXMKcy4kdGkuYy5hKGEpCnQ9cy5haCgpCnMuYT00CnMuYz1hClAuSFoo
+cyx0KX0sClpMOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKdS5sLmEoYikKdD1yLmFoKCkKcz1Q
+LlRsKGEsYikKci5hPTgKci5jPXMKUC5IWihyLHQpfSwKWGY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxz
+PXQuJHRpCnMuQygiMS8iKS5hKGEpCmlmKHMuQygiYjg8MT4iKS5iKGEpKXt0LmNVKGEpCnJldHVybn10
+LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmEobmV3IFAuckgodCxhKSkpfSwKY1U6ZnVuY3Rpb24o
+YSl7dmFyIHQ9dGhpcyxzPXQuJHRpCnMuQygiYjg8MT4iKS5hKGEpCmlmKHMuYihhKSl7aWYoYS5hPT09
+OCl7dC5hPTEKUC5UayhudWxsLG51bGwsdC5iLHUuTS5hKG5ldyBQLktGKHQsYSkpKX1lbHNlIFAuQTko
+YSx0KQpyZXR1cm59UC5rMyhhLHQpfSwKTms6ZnVuY3Rpb24oYSxiKXt0aGlzLmE9MQpQLlRrKG51bGws
+bnVsbCx0aGlzLmIsdS5NLmEobmV3IFAuWkwodGhpcyxhLGIpKSl9LAokaWI4OjF9ClAuZGEucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KUC5vUS5wcm90b3R5
+cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5iLHRoaXMuYS5hKX0sCiRTOjB9ClAucFYucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnQuYT0wCnQuSEgoYSl9LAokUzoxMH0KUC5V
+Ny5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3UubC5hKGIpCnRoaXMuYS5aTChhLGIpfSwKJDE6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuJDIoYSxudWxsKX0sCiRDOiIkMiIsCiREOmZ1bmN0aW9uKCl7
+cmV0dXJuW251bGxdfSwKJFM6Mjl9ClAudnIucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEu
+WkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLnJILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFy
+IHQ9dGhpcy5hCnQuWDIodC4kdGkuYy5hKHRoaXMuYikpfSwKJFM6MH0KUC5LRi5wcm90b3R5cGU9ewok
+MDpmdW5jdGlvbigpe1AuQTkodGhpcy5iLHRoaXMuYSl9LAokUzowfQpQLlpMLnByb3RvdHlwZT17CiQw
+OmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KUC5SVC5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMsbT1udWxsCnRyeXtyPW4uYwptPXIu
+Yi5iLnp6KHUuZk8uYShyLmQpLHUueil9Y2F0Y2gocSl7dD1ILlJ1KHEpCnM9SC50cyhxKQppZihuLmQp
+e3I9dS5uLmEobi5hLmEuYykuYQpwPXQKcD1yPT1udWxsP3A9PW51bGw6cj09PXAKcj1wfWVsc2Ugcj0h
+MQpwPW4uYgppZihyKXAuYj11Lm4uYShuLmEuYS5jKQplbHNlIHAuYj1QLlRsKHQscykKcC5hPSEwCnJl
+dHVybn1pZih1LmMuYihtKSl7aWYobSBpbnN0YW5jZW9mIFAudnMmJm0uYT49NCl7aWYobS5hPT09OCl7
+cj1uLmIKci5iPXUubi5hKG0uYykKci5hPSEwfXJldHVybn1vPW4uYS5hCnI9bi5iCnIuYj1tLlc3KG5l
+dyBQLmpaKG8pLHUueikKci5hPSExfX0sCiRTOjJ9ClAualoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMuYX0sCiRTOjMyfQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFy
+IHQscyxyLHEscCxvLG4sbT10aGlzCnRyeXtyPW0uYgpxPXIuJHRpCnA9cS5jCm89cC5hKG0uYykKbS5h
+LmI9ci5iLmIuYnYocS5DKCIyLygxKSIpLmEoci5kKSxvLHEuQygiMi8iKSxwKX1jYXRjaChuKXt0PUgu
+UnUobikKcz1ILnRzKG4pCnI9bS5hCnIuYj1QLlRsKHQscykKci5hPSEwfX0sCiRTOjJ9ClAuUlcucHJv
+dG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwp0cnl7dD11Lm4u
+YShsLmEuYS5jKQpxPWwuYwppZihILm9UKHEuSFIodCkpJiZxLmUhPW51bGwpe3A9bC5iCnAuYj1xLkt3
+KHQpCnAuYT0hMX19Y2F0Y2gobyl7cz1ILlJ1KG8pCnI9SC50cyhvKQpxPXUubi5hKGwuYS5hLmMpCnA9
+cS5hCm49cwptPWwuYgppZihwPT1udWxsP249PW51bGw6cD09PW4pbS5iPXEKZWxzZSBtLmI9UC5UbChz
+LHIpCm0uYT0hMH19LAokUzoyfQpQLk9NLnByb3RvdHlwZT17fQpQLnFoLnByb3RvdHlwZT17CmdBOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9e30scD1uZXcgUC52cygkLlgzLHUuZkopCnEuYT0wCnQ9
+SC5MaChyKQpzPXQuQygifigxKSIpLmEobmV3IFAuQjUocSxyKSkKdS5NLmEobmV3IFAudU8ocSxwKSkK
+Vy5KRShyLmEsci5iLHMsITEsdC5jKQpyZXR1cm4gcH19ClAuQjUucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
+b24oYSl7SC5MaCh0aGlzLmIpLmMuYShhKTsrK3RoaXMuYS5hfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4g
+SC5MaCh0aGlzLmIpLkMoImM4KDEpIil9fQpQLnVPLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhp
+cy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJvdG90eXBlPXt9ClAua1QucHJvdG90eXBlPXt9
+ClAueEkucHJvdG90eXBlPXt9ClAuT0gucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4gSC5k
+KHRoaXMuYSl9LAokaVhTOjEsCmdJSTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ9fQpQLm0wLnByb3Rv
+dHlwZT17JGlKQjoxfQpQLnBLLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLmEs
+cj1zLmIKaWYocj09bnVsbCl0aHJvdyBILmIocy5hKQp0PUguYihzLmEpCnQuc3RhY2s9ci5aKDApCnRo
+cm93IHR9LAokUzowfQpQLkppLnByb3RvdHlwZT17CmJIOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPW51
+bGwKdS5NLmEoYSkKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQwKCkKcmV0dXJufVAuVDgocSxxLHRoaXMs
+YSx1LkgpfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5MMihxLHEsdGhpcyx0LHUubC5hKHMp
+KX19LApEbDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9bnVsbApjLkMoIn4oMCkiKS5hKGEpCmMu
+YShiKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDEoYikKcmV0dXJufVAueXYocSxxLHRoaXMsYSxiLHUu
+SCxjKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIocSxxLHRoaXMsdCx1LmwuYShzKSl9
+fSwKUlQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuaGoodGhpcyxiLkMoIjAoKSIpLmEoYSksYil9
+LApHWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVnAodGhpcyx1Lk0uYShhKSl9LApQeTpmdW5jdGlv
+bihhLGIpe3JldHVybiBuZXcgUC5PUih0aGlzLGIuQygifigwKSIpLmEoYSksYil9LApxOmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIG51bGx9LAp6ejpmdW5jdGlvbihhLGIpe2IuQygiMCgpIikuYShhKQppZigkLlgz
+PT09Qy5OVSlyZXR1cm4gYS4kMCgpCnJldHVybiBQLlQ4KG51bGwsbnVsbCx0aGlzLGEsYil9LApidjpm
+dW5jdGlvbihhLGIsYyxkKXtjLkMoIkA8MD4iKS5LcShkKS5DKCIxKDIpIikuYShhKQpkLmEoYikKaWYo
+JC5YMz09PUMuTlUpcmV0dXJuIGEuJDEoYikKcmV0dXJuIFAueXYobnVsbCxudWxsLHRoaXMsYSxiLGMs
+ZCl9LApycDpmdW5jdGlvbihhLGIsYyxkLGUsZil7ZC5DKCJAPDA+IikuS3EoZSkuS3EoZikuQygiMSgy
+LDMpIikuYShhKQplLmEoYikKZi5hKGMpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQyKGIsYykKcmV0
+dXJuIFAuUXgobnVsbCxudWxsLHRoaXMsYSxiLGMsZCxlLGYpfSwKTGo6ZnVuY3Rpb24oYSxiLGMsZCl7
+cmV0dXJuIGIuQygiQDwwPiIpLktxKGMpLktxKGQpLkMoIjEoMiwzKSIpLmEoYSl9fQpQLmhqLnByb3Rv
+dHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS56eih0aGlzLmIsdGhpcy5jKX0sCiRTOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCIwKCkiKX19ClAuVnAucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
+b24oKXtyZXR1cm4gdGhpcy5hLmJIKHRoaXMuYil9LAokUzoyfQpQLk9SLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpyZXR1cm4gdGhpcy5hLkRsKHRoaXMuYix0LmEoYSksdCl9LAok
+UzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMuQygifigwKSIpfX0KUC5iNi5wcm90b3R5cGU9ewpna3o6
+ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPW5ldyBQLmxtKHQsdC5yLEguTGgodCkuQygibG08MT4iKSkK
+cy5jPXQuZQpyZXR1cm4gc30sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAp0ZzpmdW5jdGlv
+bihhLGIpe3ZhciB0LHMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3Q9dGhp
+cy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUuRC5hKHRbYl0pIT1udWxsfWVsc2V7cz10aGlz
+LlBSKGIpCnJldHVybiBzfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZAppZih0PT1udWxsKXJl
+dHVybiExCnJldHVybiB0aGlzLkRGKHRbdGhpcy5OKGEpXSxhKT49MH0sCmk6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHI9dGhpcwpILkxoKHIpLmMuYShiKQppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19w
+cm90b19fIil7dD1yLmIKcmV0dXJuIHIuYlEodD09bnVsbD9yLmI9UC5UMigpOnQsYil9ZWxzZSBpZih0
+eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09Yil7cz1yLmMKcmV0dXJuIHIuYlEocz09
+bnVsbD9yLmM9UC5UMigpOnMsYil9ZWxzZSByZXR1cm4gci5CNyhiKX0sCkI3OmZ1bmN0aW9uKGEpe3Zh
+ciB0LHMscixxPXRoaXMKSC5MaChxKS5jLmEoYSkKdD1xLmQKaWYodD09bnVsbCl0PXEuZD1QLlQyKCkK
+cz1xLk4oYSkKcj10W3NdCmlmKHI9PW51bGwpdFtzXT1bcS55byhhKV0KZWxzZXtpZihxLkRGKHIsYSk+
+PTApcmV0dXJuITEKci5wdXNoKHEueW8oYSkpfXJldHVybiEwfSwKUjpmdW5jdGlvbihhLGIpe3ZhciB0
+PXRoaXMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpcmV0dXJuIHQuSDQodC5i
+LGIpCmVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHQu
+SDQodC5jLGIpCmVsc2UgcmV0dXJuIHQucWcoYil9LApxZzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxw
+PXRoaXMsbz1wLmQKaWYobz09bnVsbClyZXR1cm4hMQp0PXAuTihhKQpzPW9bdF0Kcj1wLkRGKHMsYSkK
+aWYocjwwKXJldHVybiExCnE9cy5zcGxpY2UociwxKVswXQppZigwPT09cy5sZW5ndGgpZGVsZXRlIG9b
+dF0KcC5HUyhxKQpyZXR1cm4hMH0sCmJROmZ1bmN0aW9uKGEsYil7SC5MaCh0aGlzKS5jLmEoYikKaWYo
+dS5ELmEoYVtiXSkhPW51bGwpcmV0dXJuITEKYVtiXT10aGlzLnlvKGIpCnJldHVybiEwfSwKSDQ6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdAppZihhPT1udWxsKXJldHVybiExCnQ9dS5ELmEoYVtiXSkKaWYodD09bnVs
+bClyZXR1cm4hMQp0aGlzLkdTKHQpCmRlbGV0ZSBhW2JdCnJldHVybiEwfSwKUzpmdW5jdGlvbigpe3Ro
+aXMucj0xMDczNzQxODIzJnRoaXMucisxfSwKeW86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9bmV3
+IFAuYm4oSC5MaChzKS5jLmEoYSkpCmlmKHMuZT09bnVsbClzLmU9cy5mPXIKZWxzZXt0PXMuZgpyLmM9
+dApzLmY9dC5iPXJ9KytzLmEKcy5TKCkKcmV0dXJuIHJ9LApHUzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+LHM9YS5jLHI9YS5iCmlmKHM9PW51bGwpdC5lPXIKZWxzZSBzLmI9cgppZihyPT1udWxsKXQuZj1zCmVs
+c2Ugci5jPXM7LS10LmEKdC5TKCl9LApOOmZ1bmN0aW9uKGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4
+MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYoYT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3Ro
+CmZvcihzPTA7czx0OysrcylpZihKLlJNKGFbc10uYSxiKSlyZXR1cm4gcwpyZXR1cm4tMX19ClAuYm4u
+cHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwK
+RjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmEKaWYodC5iIT09cy5yKXRocm93IEguYihQLmE0KHMp
+KQplbHNle3M9dC5jCmlmKHM9PW51bGwpe3Quc2oobnVsbCkKcmV0dXJuITF9ZWxzZXt0LnNqKHQuJHRp
+LmMuYShzLmEpKQp0LmM9dC5jLmIKcmV0dXJuITB9fX0sCnNqOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlz
+LiR0aS5jLmEoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBlPXt9ClAudXkucHJvdG90eXBlPXskaWJR
+OjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
+dyBILmE3KGEsdGhpcy5nQShhKSxILnEoYSkuQygiYTc8bEQuRT4iKSl9LApFOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC5xKGEpLkMoIn4obEQu
+RSkiKS5hKGIpCnQ9dGhpcy5nQShhKQpmb3Iocz0wO3M8dDsrK3Mpe2IuJDEodGhpcy5xKGEscykpCmlm
+KHQhPT10aGlzLmdBKGEpKXRocm93IEguYihQLmE0KGEpKX19LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuZ0EoYSkhPT0wfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgucShhKQpyZXR1cm4gbmV3
+IEgubEooYSx0LktxKGMpLkMoIjEobEQuRSkiKS5hKGIpLHQuQygiQDxsRC5FPiIpLktxKGMpLkMoImxK
+PDEsMj4iKSl9LApkdTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdApILnEoYSkuQygibEQuRSIpLmEoZCkK
+UC5qQihiLGMsdGhpcy5nQShhKSkKZm9yKHQ9Yjt0PGM7Kyt0KXRoaXMuWShhLHQsZCl9LApaOmZ1bmN0
+aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9fQpQLmlsLnByb3RvdHlwZT17fQpQLnJhLnByb3Rv
+dHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmEKaWYoIXMuYSl0aGlzLmIuYSs9Iiwg
+IgpzLmE9ITEKcz10aGlzLmIKdD1zLmErPUguZChhKQpzLmE9dCsiOiAiCnMuYSs9SC5kKGIpfSwKJFM6
+NH0KUC5Zay5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILkxoKHRoaXMpLkMoIn4o
+WWsuSyxZay5WKSIpLmEoYikKZm9yKHQ9Si5JVCh0aGlzLmdWKCkpO3QuRigpOyl7cz10LmdsKCkKYi4k
+MihzLHRoaXMucSgwLHMpKX19LApnUHU6ZnVuY3Rpb24oYSl7cmV0dXJuIEouTTEodGhpcy5nVigpLG5l
+dyBQLnlRKHRoaXMpLEguTGgodGhpcykuQygiTjM8WWsuSyxZay5WPiIpKX0sCng0OmZ1bmN0aW9uKGEp
+e3JldHVybiBKLnpsKHRoaXMuZ1YoKSxhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkgodGhpcy5n
+VigpKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5DaSh0aGlzLmdWKCkpfSwKWjpmdW5jdGlvbihh
+KXtyZXR1cm4gUC5uTyh0aGlzKX0sCiRpWjA6MX0KUC55US5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
+KXt2YXIgdD10aGlzLmEscz1ILkxoKHQpCnMuQygiWWsuSyIpLmEoYSkKcmV0dXJuIG5ldyBQLk4zKGEs
+dC5xKDAsYSkscy5DKCJAPFlrLks+IikuS3Eocy5DKCJZay5WIikpLkMoIk4zPDEsMj4iKSl9LAokUzpm
+dW5jdGlvbigpe3JldHVybiBILkxoKHRoaXMuYSkuQygiTjM8WWsuSyxZay5WPihZay5LKSIpfX0KUC5L
+UC5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnQuYy5hKGIpCnQu
+UVsxXS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5IHVubW9kaWZpYWJsZSBtYXAiKSl9
+fQpQLlBuLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLnEoMCxiKX0sClk6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdGhpcy5hLlkoMCx0LmMuYShiKSx0LlFbMV0u
+YShjKSl9LAp4NDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLng0KGEpfSwKSzpmdW5jdGlvbihhLGIp
+e3RoaXMuYS5LKDAsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5hKGIpKX0sCmdsMDpmdW5jdGlvbihhKXt2
+YXIgdD10aGlzLmEKcmV0dXJuIHQuZ2wwKHQpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJl
+dHVybiB0LmdBKHQpfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gSi5BYyh0aGlzLmEpfSwKZ1B1OmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nUHUodCl9LAokaVowOjF9ClAuR2oucHJvdG90eXBl
+PXt9ClAuTWEucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5XRSh0aGlzLCJ7IiwifSIp
+fX0KUC5Wai5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl4dToxfQpQLlh2LnByb3RvdHlwZT17CkZW
+OmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9Si5JVChILkxoKHRoaXMpLkMoImNYPDE+IikuYShiKSk7
+dC5GKCk7KXRoaXMuaSgwLHQuZ2woKSl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKHRoaXMsInsi
+LCJ9Iil9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1QLnJqKHRoaXMsdGhpcy5yLEguTGgodGhpcyku
+YykKaWYoIXMuRigpKXJldHVybiIiCmlmKGI9PT0iIil7dD0iIgpkbyB0Kz1ILmQocy5kKQp3aGlsZShz
+LkYoKSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5GKCk7KXQ9dCtiK0guZChzLmQpfXJldHVybiB0LmNo
+YXJDb2RlQXQoMCk9PTA/dDp0fSwKJGliUToxLAokaWNYOjEsCiRpeHU6MX0KUC5uWS5wcm90b3R5cGU9
+e30KUC5UQy5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQpl
+bHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4gbnVsbAplbHNle3Q9c1tiXQpyZXR1cm4gdHlw
+ZW9mIHQ9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6dH19LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
+cy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5ndGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuZ0EodGhpcyk9PT0wfSwKZ1Y6ZnVuY3Rpb24oKXtpZih0aGlzLmI9PW51bGwpe3ZhciB0PXRo
+aXMuYwpyZXR1cm4gbmV3IEguaTUodCxILkxoKHQpLkMoImk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0
+aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj10aGlzCmlmKHIuYj09bnVsbClyLmMuWSgw
+LGIsYykKZWxzZSBpZihyLng0KGIpKXt0PXIuYgp0W2JdPWMKcz1yLmEKaWYocz09bnVsbD90IT1udWxs
+OnMhPT10KXNbYl09bnVsbH1lbHNlIHIuWEsoKS5ZKDAsYixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRo
+aXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0KGEpCnJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093
+blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhp
+cwp1LmNBLmEoYikKaWYocC5iPT1udWxsKXJldHVybiBwLmMuSygwLGIpCnQ9cC5DZigpCmZvcihzPTA7
+czx0Lmxlbmd0aDsrK3Mpe3I9dFtzXQpxPXAuYltyXQppZih0eXBlb2YgcT09InVuZGVmaW5lZCIpe3E9
+UC5RZShwLmFbcl0pCnAuYltyXT1xfWIuJDIocixxKQppZih0IT09cC5jKXRocm93IEguYihQLmE0KHAp
+KX19LApDZjpmdW5jdGlvbigpe3ZhciB0PXUuai5hKHRoaXMuYykKaWYodD09bnVsbCl0PXRoaXMuYz1I
+LlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdS5zKQpyZXR1cm4gdH0sClhLOmZ1bmN0aW9uKCl7dmFyIHQs
+cyxyLHEscCxvPXRoaXMKaWYoby5iPT1udWxsKXJldHVybiBvLmMKdD1QLkZsKHUuTix1LnopCnM9by5D
+ZigpCmZvcihyPTA7cT1zLmxlbmd0aCxyPHE7KytyKXtwPXNbcl0KdC5ZKDAscCxvLnEoMCxwKSl9aWYo
+cT09PTApQy5ObS5pKHMsbnVsbCkKZWxzZSBDLk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBv
+LmM9dH0sCmZiOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3Bl
+cnR5LmNhbGwodGhpcy5hLGEpKXJldHVybiBudWxsCnQ9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlz
+LmJbYV09dH19ClAuaTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVy
+biB0LmdBKHQpfSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpdD10LmdW
+KCkuRSgwLGIpCmVsc2V7dD10LkNmKCkKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikK
+dD10W2JdfXJldHVybiB0fSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwp
+e3Q9dC5nVigpCnQ9dC5na3oodCl9ZWxzZXt0PXQuQ2YoKQp0PW5ldyBKLm0xKHQsdC5sZW5ndGgsSC50
+Nih0KS5DKCJtMTwxPiIpKX1yZXR1cm4gdH0sCnRnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54
+NChiKX19ClAuQ1YucHJvdG90eXBlPXsKeXI6ZnVuY3Rpb24oYSxhMCxhMSl7dmFyIHQscyxyLHEscCxv
+LG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGI9IkludmFsaWQgYmFzZTY0IGVuY29kaW5nIGxlbmd0aCAi
+CmExPVAuakIoYTAsYTEsYS5sZW5ndGgpCnQ9JC5WNygpCmZvcihzPWEwLHI9cyxxPW51bGwscD0tMSxv
+PS0xLG49MDtzPGExO3M9bSl7bT1zKzEKbD1DLnhCLlcoYSxzKQppZihsPT09Mzcpe2s9bSsyCmlmKGs8
+PWExKXtqPUgub28oQy54Qi5XKGEsbSkpCmk9SC5vbyhDLnhCLlcoYSxtKzEpKQpoPWoqMTYraS0oaSYy
+NTYpCmlmKGg9PT0zNyloPS0xCm09a31lbHNlIGg9LTF9ZWxzZSBoPWwKaWYoMDw9aCYmaDw9MTI3KXtp
+ZihoPDB8fGg+PXQubGVuZ3RoKXJldHVybiBILmsodCxoKQpnPXRbaF0KaWYoZz49MCl7aD1DLnhCLm0o
+IkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2
+Nzg5Ky8iLGcpCmlmKGg9PT1sKWNvbnRpbnVlCmw9aH1lbHNle2lmKGc9PT0tMSl7aWYocDwwKXtmPXE9
+PW51bGw/bnVsbDpxLmEubGVuZ3RoCmlmKGY9PW51bGwpZj0wCnA9Zisocy1yKQpvPXN9KytuCmlmKGw9
+PT02MSljb250aW51ZX1sPWh9aWYoZyE9PS0yKXtpZihxPT1udWxsKXE9bmV3IFAuUm4oIiIpCnEuYSs9
+Qy54Qi5OaihhLHIscykKcS5hKz1ILkx3KGwpCnI9bQpjb250aW51ZX19dGhyb3cgSC5iKFAucnIoIklu
+dmFsaWQgYmFzZTY0IGRhdGEiLGEscykpfWlmKHEhPW51bGwpe2Y9cS5hKz1DLnhCLk5qKGEscixhMSkK
+ZT1mLmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAsbixlKQplbHNle2Q9Qy5qbi56WShlLTEsNCkr
+MQppZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEpKQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9Zjsr
+K2R9fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEsZi5jaGFyQ29kZUF0KDApPT0wP2Y6Zil9Yz1h
+MS1hMAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQplbHNle2Q9Qy5qbi56WShjLDQpCmlmKGQ9PT0x
+KXRocm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlhPUMueEIuaTcoYSxhMSxhMSxkPT09Mj8iPT0i
+OiI9Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17fQpQLndJLnBy
+b3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLlVkLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7
+dmFyIHQ9UC5oKHRoaXMuYSkKcmV0dXJuKHRoaXMuYiE9bnVsbD8iQ29udmVydGluZyBvYmplY3QgdG8g
+YW4gZW5jb2RhYmxlIG9iamVjdCBmYWlsZWQ6IjoiQ29udmVydGluZyBvYmplY3QgZGlkIG5vdCByZXR1
+cm4gYW4gZW5jb2RhYmxlIG9iamVjdDoiKSsiICIrdH19ClAuSzgucHJvdG90eXBlPXsKWjpmdW5jdGlv
+bihhKXtyZXR1cm4iQ3ljbGljIGVycm9yIGluIEpTT04gc3RyaW5naWZ5In19ClAuYnkucHJvdG90eXBl
+PXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnUuZXAuYShjKQp0PVAuQlMoYix0aGlzLmdIZSgpLmEp
+CnJldHVybiB0fSwKT0I6ZnVuY3Rpb24oYSxiKXt2YXIgdAp1LmJjLmEoYikKdD1QLnVYKGEsdGhpcy5n
+WkUoKS5iLG51bGwpCnJldHVybiB0fSwKZ1pFOmZ1bmN0aW9uKCl7cmV0dXJuIEMublh9LApnSGU6ZnVu
+Y3Rpb24oKXtyZXR1cm4gQy5BM319ClAub2oucHJvdG90eXBlPXt9ClAuTXgucHJvdG90eXBlPXt9ClAu
+U2gucHJvdG90eXBlPXsKdnA6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49YS5sZW5ndGgKZm9y
+KHQ9Si5yWShhKSxzPXRoaXMuYyxyPTAscT0wO3E8bjsrK3Epe3A9dC5XKGEscSkKaWYocD45Miljb250
+aW51ZQppZihwPDMyKXtpZihxPnIpcy5hKz1DLnhCLk5qKGEscixxKQpyPXErMQpzLmErPUguTHcoOTIp
+CnN3aXRjaChwKXtjYXNlIDg6cy5hKz1ILkx3KDk4KQpicmVhawpjYXNlIDk6cy5hKz1ILkx3KDExNikK
+YnJlYWsKY2FzZSAxMDpzLmErPUguTHcoMTEwKQpicmVhawpjYXNlIDEyOnMuYSs9SC5MdygxMDIpCmJy
+ZWFrCmNhc2UgMTM6cy5hKz1ILkx3KDExNCkKYnJlYWsKZGVmYXVsdDpzLmErPUguTHcoMTE3KQpzLmEr
+PUguTHcoNDgpCnMuYSs9SC5Mdyg0OCkKbz1wPj4+NCYxNQpzLmErPUguTHcobzwxMD80OCtvOjg3K28p
+Cm89cCYxNQpzLmErPUguTHcobzwxMD80OCtvOjg3K28pCmJyZWFrfX1lbHNlIGlmKHA9PT0zNHx8cD09
+PTkyKXtpZihxPnIpcy5hKz1DLnhCLk5qKGEscixxKQpyPXErMQpzLmErPUguTHcoOTIpCnMuYSs9SC5M
+dyhwKX19aWYocj09PTApcy5hKz1ILmQoYSkKZWxzZSBpZihyPG4pcy5hKz10Lk5qKGEscixuKX0sCkpu
+OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxCmZvcih0PXRoaXMuYSxzPXQubGVuZ3RoLHI9MDtyPHM7Kyty
+KXtxPXRbcl0KaWYoYT09bnVsbD9xPT1udWxsOmE9PT1xKXRocm93IEguYihuZXcgUC5LOChhLG51bGwp
+KX1DLk5tLmkodCxhKX0sCmlVOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9dGhpcwppZihwLnRNKGEp
+KXJldHVybgpwLkpuKGEpCnRyeXt0PXAuYi4kMShhKQppZighcC50TSh0KSl7cj1QLkd5KGEsbnVsbCxw
+LmdWSygpKQp0aHJvdyBILmIocil9cj1wLmEKaWYoMD49ci5sZW5ndGgpcmV0dXJuIEguayhyLC0xKQpy
+LnBvcCgpfWNhdGNoKHEpe3M9SC5SdShxKQpyPVAuR3koYSxzLHAuZ1ZLKCkpCnRocm93IEguYihyKX19
+LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcwppZih0eXBlb2YgYT09Im51bWJlciIpe2lmKCFp
+c0Zpbml0ZShhKSlyZXR1cm4hMQpyLmMuYSs9Qy5DRC5aKGEpCnJldHVybiEwfWVsc2UgaWYoYT09PSEw
+KXtyLmMuYSs9InRydWUiCnJldHVybiEwfWVsc2UgaWYoYT09PSExKXtyLmMuYSs9ImZhbHNlIgpyZXR1
+cm4hMH1lbHNlIGlmKGE9PW51bGwpe3IuYy5hKz0ibnVsbCIKcmV0dXJuITB9ZWxzZSBpZih0eXBlb2Yg
+YT09InN0cmluZyIpe3Q9ci5jCnQuYSs9JyInCnIudnAoYSkKdC5hKz0nIicKcmV0dXJuITB9ZWxzZSBp
+Zih1LmouYihhKSl7ci5KbihhKQpyLmxLKGEpCnQ9ci5hCmlmKDA+PXQubGVuZ3RoKXJldHVybiBILmso
+dCwtMSkKdC5wb3AoKQpyZXR1cm4hMH1lbHNlIGlmKHUuRy5iKGEpKXtyLkpuKGEpCnM9ci5qdyhhKQp0
+PXIuYQppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEpCnQucG9wKCkKcmV0dXJuIHN9ZWxzZSBy
+ZXR1cm4hMX0sCmxLOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLmMKci5hKz0iWyIKdD1KLlU2KGEp
+CmlmKHQuZ29yKGEpKXt0aGlzLmlVKHQucShhLDApKQpmb3Iocz0xO3M8dC5nQShhKTsrK3Mpe3IuYSs9
+IiwiCnRoaXMuaVUodC5xKGEscykpfX1yLmErPSJdIn0sCmp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
+LHAsbyxuPXRoaXMsbT17fQppZihhLmdsMChhKSl7bi5jLmErPSJ7fSIKcmV0dXJuITB9dD1hLmdBKGEp
+KjIKcz1uZXcgQXJyYXkodCkKcy5maXhlZCRsZW5ndGg9QXJyYXkKcj1tLmE9MAptLmI9ITAKYS5LKDAs
+bmV3IFAudGkobSxzKSkKaWYoIW0uYilyZXR1cm4hMQpxPW4uYwpxLmErPSJ7Igpmb3IocD0nIic7cjx0
+O3IrPTIscD0nLCInKXtxLmErPXAKbi52cChILmMoc1tyXSkpCnEuYSs9JyI6JwpvPXIrMQppZihvPj10
+KXJldHVybiBILmsocyxvKQpuLmlVKHNbb10pfXEuYSs9In0iCnJldHVybiEwfX0KUC50aS5wcm90b3R5
+cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYodHlwZW9mIGEhPSJzdHJpbmciKXRoaXMuYS5i
+PSExCnQ9dGhpcy5iCnM9dGhpcy5hCkMuTm0uWSh0LHMuYSsrLGEpCkMuTm0uWSh0LHMuYSsrLGIpfSwK
+JFM6NH0KUC50dS5wcm90b3R5cGU9ewpnVks6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmMuYQpyZXR1cm4g
+dC5jaGFyQ29kZUF0KDApPT0wP3Q6dH19ClAudTUucHJvdG90eXBlPXsKZ1pFOmZ1bmN0aW9uKCl7cmV0
+dXJuIEMuUWt9fQpQLkUzLnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj1QLmpCKDAs
+bnVsbCxhLmxlbmd0aCkscT1yLTAKaWYocT09PTApcmV0dXJuIG5ldyBVaW50OEFycmF5KDApCnQ9bmV3
+IFVpbnQ4QXJyYXkocSozKQpzPW5ldyBQLlJ3KHQpCmlmKHMuR3goYSwwLHIpIT09cilzLk82KEouYTYo
+YSxyLTEpLDApCnJldHVybiBuZXcgVWludDhBcnJheSh0LnN1YmFycmF5KDAsSC5yTSgwLHMuYix0Lmxl
+bmd0aCkpKX19ClAuUncucHJvdG90eXBlPXsKTzY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMscj1z
+LmMscT1zLmIscD1xKzEsbz1yLmxlbmd0aAppZigoYiY2NDUxMik9PT01NjMyMCl7dD02NTUzNisoKGEm
+MTAyMyk8PDEwKXxiJjEwMjMKcy5iPXAKaWYocT49bylyZXR1cm4gSC5rKHIscSkKcltxXT0yNDB8dD4+
+PjE4CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHx0Pj4+MTImNjMKcD1z
+LmI9cSsxCmlmKHE+PW8pcmV0dXJuIEguayhyLHEpCnJbcV09MTI4fHQ+Pj42JjYzCnMuYj1wKzEKaWYo
+cD49bylyZXR1cm4gSC5rKHIscCkKcltwXT0xMjh8dCY2MwpyZXR1cm4hMH1lbHNle3MuYj1wCmlmKHE+
+PW8pcmV0dXJuIEguayhyLHEpCnJbcV09MjI0fGE+Pj4xMgpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4g
+SC5rKHIscCkKcltwXT0xMjh8YT4+PjYmNjMKcy5iPXErMQppZihxPj1vKXJldHVybiBILmsocixxKQpy
+W3FdPTEyOHxhJjYzCnJldHVybiExfX0sCkd4OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8s
+bixtPXRoaXMKaWYoYiE9PWMmJihDLnhCLm0oYSxjLTEpJjY0NTEyKT09PTU1Mjk2KS0tYwpmb3IodD1t
+LmMscz10Lmxlbmd0aCxyPWI7cjxjOysrcil7cT1DLnhCLlcoYSxyKQppZihxPD0xMjcpe3A9bS5iCmlm
+KHA+PXMpYnJlYWsKbS5iPXArMQp0W3BdPXF9ZWxzZSBpZigocSY2NDUxMik9PT01NTI5Nil7aWYobS5i
+KzM+PXMpYnJlYWsKbz1yKzEKaWYobS5PNihxLEMueEIuVyhhLG8pKSlyPW99ZWxzZSBpZihxPD0yMDQ3
+KXtwPW0uYgpuPXArMQppZihuPj1zKWJyZWFrCm0uYj1uCmlmKHA+PXMpcmV0dXJuIEguayh0LHApCnRb
+cF09MTkyfHE+Pj42Cm0uYj1uKzEKdFtuXT0xMjh8cSY2M31lbHNle3A9bS5iCmlmKHArMj49cylicmVh
+awpuPW0uYj1wKzEKaWYocD49cylyZXR1cm4gSC5rKHQscCkKdFtwXT0yMjR8cT4+PjEyCnA9bS5iPW4r
+MQppZihuPj1zKXJldHVybiBILmsodCxuKQp0W25dPTEyOHxxPj4+NiY2MwptLmI9cCsxCmlmKHA+PXMp
+cmV0dXJuIEguayh0LHApCnRbcF09MTI4fHEmNjN9fXJldHVybiByfX0KUC5HWS5wcm90b3R5cGU9ewpX
+SjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwKdS5MLmEoYSkKdD1QLmt5KCExLGEsMCxu
+dWxsKQppZih0IT1udWxsKXJldHVybiB0CnM9UC5qQigwLG51bGwsSi5IKGEpKQpyPVAuY1AoYSwwLHMp
+CmlmKHI+MCl7cT1QLkhNKGEsMCxyKQppZihyPT09cylyZXR1cm4gcQpwPW5ldyBQLlJuKHEpCm89cgpu
+PSExfWVsc2V7bz0wCnA9bnVsbApuPSEwfWlmKHA9PW51bGwpcD1uZXcgUC5SbigiIikKbT1uZXcgUC5i
+eighMSxwKQptLmM9bgptLk1FKGEsbyxzKQppZihtLmU+MCl7SC52aChQLnJyKCJVbmZpbmlzaGVkIFVU
+Ri04IG9jdGV0IHNlcXVlbmNlIixhLHMpKQpwLmErPUguTHcoNjU1MzMpCm0uZj1tLmU9bS5kPTB9bD1w
+LmEKcmV0dXJuIGwuY2hhckNvZGVBdCgwKT09MD9sOmx9fQpQLmJ6LnByb3RvdHlwZT17Ck1FOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaD10aGlzLGc9IkJhZCBVVEYtOCBl
+bmNvZGluZyAweCIKdS5MLmEoYSkKdD1oLmQKcz1oLmUKcj1oLmYKaC5mPWguZT1oLmQ9MAokbGFiZWww
+JDA6Zm9yKHE9Si5VNihhKSxwPWguYixvPWI7ITA7bz1qKXskbGFiZWwxJDE6aWYocz4wKXtkb3tpZihv
+PT09YylicmVhayAkbGFiZWwwJDAKbj1xLnEoYSxvKQppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVy
+biBuLnpNKCkKaWYoKG4mMTkyKSE9PTEyOCl7bT1QLnJyKGcrQy5qbi5XWihuLDE2KSxhLG8pCnRocm93
+IEguYihtKX1lbHNle3Q9KHQ8PDZ8biY2Myk+Pj4wOy0tczsrK299fXdoaWxlKHM+MCkKbT1yLTEKaWYo
+bTwwfHxtPj00KXJldHVybiBILmsoQy5HYixtKQppZih0PD1DLkdiW21dKXttPVAucnIoIk92ZXJsb25n
+IGVuY29kaW5nIG9mIDB4IitDLmpuLldaKHQsMTYpLGEsby1yLTEpCnRocm93IEguYihtKX1pZih0PjEx
+MTQxMTEpe209UC5ycigiQ2hhcmFjdGVyIG91dHNpZGUgdmFsaWQgVW5pY29kZSByYW5nZTogMHgiK0Mu
+am4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0pfWlmKCFoLmN8fHQhPT02NTI3OSlwLmErPUgu
+THcodCkKaC5jPSExfWZvcihtPW88YzttOyl7bD1QLmNQKGEsbyxjKQppZihsPjApe2guYz0hMQprPW8r
+bApwLmErPVAuSE0oYSxvLGspCmlmKGs9PT1jKWJyZWFrfWVsc2Ugaz1vCmo9aysxCm49cS5xKGEsaykK
+aWYodHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5KKCkKaWYobjwwKXtpPVAucnIoIk5lZ2F0aXZl
+IFVURi04IGNvZGUgdW5pdDogLTB4IitDLmpuLldaKC1uLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfWVs
+c2V7aWYoKG4mMjI0KT09PTE5Mil7dD1uJjMxCnM9MQpyPTEKY29udGludWUgJGxhYmVsMCQwfWlmKChu
+JjI0MCk9PT0yMjQpe3Q9biYxNQpzPTIKcj0yCmNvbnRpbnVlICRsYWJlbDAkMH1pZigobiYyNDgpPT09
+MjQwJiZuPDI0NSl7dD1uJjcKcz0zCnI9Mwpjb250aW51ZSAkbGFiZWwwJDB9aT1QLnJyKGcrQy5qbi5X
+WihuLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfX1icmVhayAkbGFiZWwwJDB9aWYocz4wKXtoLmQ9dApo
+LmU9cwpoLmY9cn19fQpQLldGLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCnUu
+Zm8uYShhKQp0PXRoaXMuYgpzPXRoaXMuYQp0LmErPXMuYQpyPXQuYSs9SC5kKGEuYSkKdC5hPXIrIjog
+Igp0LmErPVAuaChiKQpzLmE9IiwgIn0sCiRTOjQwfQpQLmEyLnByb3RvdHlwZT17fQpQLmlQLnByb3Rv
+dHlwZT17CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5j
+ZW9mIFAuaVAmJnRoaXMuYT09PWIuYSYmITB9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJl
+dHVybih0XkMuam4ud0codCwzMCkpJjEwNzM3NDE4MjN9LApaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMs
+cz1QLkdxKEgudEoodCkpLHI9UC5oMChILk5TKHQpKSxxPVAuaDAoSC5qQSh0KSkscD1QLmgwKEguSVgo
+dCkpLG89UC5oMChILmNoKHQpKSxuPVAuaDAoSC5KZCh0KSksbT1QLlZ4KEguVmEodCkpLGw9cysiLSIr
+cisiLSIrcSsiICIrcCsiOiIrbysiOiIrbisiLiIrbQpyZXR1cm4gbH19ClAuQ1AucHJvdG90eXBlPXt9
+ClAuWFMucHJvdG90eXBlPXsKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIEgudHModGhpcy4kdGhyb3duSnNF
+cnJvcil9fQpQLkM2LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQhPW51
+bGwpcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5oKHQpCnJldHVybiJBc3NlcnRpb24gZmFpbGVk
+In19ClAuTEsucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iVGhyb3cgb2YgbnVsbC4ifX0K
+UC5BVC5wcm90b3R5cGU9ewpnTDpmdW5jdGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3VtZW50IisoIXRo
+aXMuYT8iKHMpIjoiIil9LApndTpmdW5jdGlvbigpe3JldHVybiIifSwKWjpmdW5jdGlvbihhKXt2YXIg
+dCxzLHIscSxwPXRoaXMsbz1wLmMsbj1vIT1udWxsPyIgKCIrbysiKSI6IiIKbz1wLmQKdD1vPT1udWxs
+PyIiOiI6ICIrSC5kKG8pCnM9cC5nTCgpK24rdAppZighcC5hKXJldHVybiBzCnI9cC5ndSgpCnE9UC5o
+KHAuYikKcmV0dXJuIHMrcisiOiAiK3F9fQpQLmJKLnByb3RvdHlwZT17CmdMOmZ1bmN0aW9uKCl7cmV0
+dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5lCmlmKHI9PW51bGwp
+e3I9dGhpcy5mCnQ9ciE9bnVsbD8iOiBOb3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICIrSC5kKHIpOiIi
+fWVsc2V7cz10aGlzLmYKaWYocz09bnVsbCl0PSI6IE5vdCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8g
+IitILmQocikKZWxzZSBpZihzPnIpdD0iOiBOb3QgaW4gcmFuZ2UgIitILmQocikrIi4uIitILmQocykr
+IiwgaW5jbHVzaXZlIgplbHNlIHQ9czxyPyI6IFZhbGlkIHZhbHVlIHJhbmdlIGlzIGVtcHR5IjoiOiBP
+bmx5IHZhbGlkIHZhbHVlIGlzICIrSC5kKHIpfXJldHVybiB0fX0KUC5lWS5wcm90b3R5cGU9ewpnTDpm
+dW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQscz1ILldZKHRo
+aXMuYikKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5KKCkKaWYoczwwKXJldHVybiI6IGlu
+ZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZlIgp0PXRoaXMuZgppZih0PT09MClyZXR1cm4iOiBubyBpbmRp
+Y2VzIGFyZSB2YWxpZCIKcmV0dXJuIjogaW5kZXggc2hvdWxkIGJlIGxlc3MgdGhhbiAiK0guZCh0KX0s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmZ9fQpQLm1wLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24o
+YSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPXRoaXMsaz17fSxqPW5ldyBQLlJuKCIiKQprLmE9IiIKZm9y
+KHQ9bC5jLHM9dC5sZW5ndGgscj0wLHE9IiIscD0iIjtyPHM7KytyLHA9IiwgIil7bz10W3JdCmouYT1x
+K3AKcT1qLmErPVAuaChvKQprLmE9IiwgIn1sLmQuSygwLG5ldyBQLldGKGssaikpCm49UC5oKGwuYSkK
+bT1qLlooMCkKdD0iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK0guZChsLmIu
+YSkrIidcblJlY2VpdmVyOiAiK24rIlxuQXJndW1lbnRzOiBbIittKyJdIgpyZXR1cm4gdH19ClAudWIu
+cHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iVW5zdXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3Ro
+aXMuYX19ClAuZHMucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQh
+PW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIit0OiJVbmltcGxlbWVudGVkRXJyb3IifX0KUC5sai5w
+cm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJCYWQgc3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5w
+cm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0PT1udWxsKXJldHVybiJDb25j
+dXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9uLiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9k
+aWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5oKHQpKyIuIn19ClAuazUucHJvdG90eXBlPXsK
+WjpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4g
+bnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJTdGFjayBP
+dmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC50Ny5wcm90b3R5
+cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdD09bnVsbD8iUmVhZGluZyBzdGF0
+aWMgdmFyaWFibGUgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiI6IlJlYWRpbmcgc3RhdGljIHZhcmlh
+YmxlICciK3QrIicgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiJ9fQpQLkNELnByb3RvdHlwZT17Clo6
+ZnVuY3Rpb24oYSl7cmV0dXJuIkV4Y2VwdGlvbjogIit0aGlzLmF9LAokaVJ6OjF9ClAuYUUucHJvdG90
+eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaD10aGlzLmEsZz1o
+IT1udWxsJiYiIiE9PWg/IkZvcm1hdEV4Y2VwdGlvbjogIitILmQoaCk6IkZvcm1hdEV4Y2VwdGlvbiIs
+Zj10aGlzLmMsZT10aGlzLmIKaWYodHlwZW9mIGU9PSJzdHJpbmciKXtpZihmIT1udWxsKWg9ZjwwfHxm
+PmUubGVuZ3RoCmVsc2UgaD0hMQppZihoKWY9bnVsbAppZihmPT1udWxsKXt0PWUubGVuZ3RoPjc4P0Mu
+eEIuTmooZSwwLDc1KSsiLi4uIjplCnJldHVybiBnKyJcbiIrdH1mb3Iocz0xLHI9MCxxPSExLHA9MDtw
+PGY7KytwKXtvPUMueEIuVyhlLHApCmlmKG89PT0xMCl7aWYociE9PXB8fCFxKSsrcwpyPXArMQpxPSEx
+fWVsc2UgaWYobz09PTEzKXsrK3MKcj1wKzEKcT0hMH19Zz1zPjE/ZysoIiAoYXQgbGluZSAiK3MrIiwg
+Y2hhcmFjdGVyICIrKGYtcisxKSsiKVxuIik6ZysoIiAoYXQgY2hhcmFjdGVyICIrKGYrMSkrIilcbiIp
+Cm49ZS5sZW5ndGgKZm9yKHA9ZjtwPG47KytwKXtvPUMueEIubShlLHApCmlmKG89PT0xMHx8bz09PTEz
+KXtuPXAKYnJlYWt9fWlmKG4tcj43OClpZihmLXI8NzUpe209cis3NQpsPXIKaz0iIgpqPSIuLi4ifWVs
+c2V7aWYobi1mPDc1KXtsPW4tNzUKbT1uCmo9IiJ9ZWxzZXtsPWYtMzYKbT1mKzM2Cmo9Ii4uLiJ9az0i
+Li4uIn1lbHNle209bgpsPXIKaz0iIgpqPSIifWk9Qy54Qi5OaihlLGwsbSkKcmV0dXJuIGcraytpK2or
+IlxuIitDLnhCLkl4KCIgIixmLWwray5sZW5ndGgpKyJeXG4ifWVsc2UgcmV0dXJuIGYhPW51bGw/Zyso
+IiAoYXQgb2Zmc2V0ICIrSC5kKGYpKyIpIik6Z30sCiRpUno6MX0KUC5FSC5wcm90b3R5cGU9e30KUC5J
+Zi5wcm90b3R5cGU9e30KUC5jWC5wcm90b3R5cGU9ewpFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5M
+aCh0aGlzKQpyZXR1cm4gSC5LMSh0aGlzLHQuS3EoYykuQygiMShjWC5FKSIpLmEoYiksdC5DKCJjWC5F
+IiksYyl9LApldjpmdW5jdGlvbihhLGIpe3ZhciB0PUguTGgodGhpcykKcmV0dXJuIG5ldyBILlU1KHRo
+aXMsdC5DKCJhMihjWC5FKSIpLmEoYiksdC5DKCJVNTxjWC5FPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3Zh
+ciB0LHM9dGhpcy5na3oodGhpcykKZm9yKHQ9MDtzLkYoKTspKyt0CnJldHVybiB0fSwKZ2wwOmZ1bmN0
+aW9uKGEpe3JldHVybiF0aGlzLmdreih0aGlzKS5GKCl9LApncjg6ZnVuY3Rpb24oYSl7dmFyIHQscz10
+aGlzLmdreih0aGlzKQppZighcy5GKCkpdGhyb3cgSC5iKEguV3AoKSkKdD1zLmdsKCkKaWYocy5GKCkp
+dGhyb3cgSC5iKEguZFUoKSkKcmV0dXJuIHR9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9Imlu
+ZGV4IgpQLlVJKGIscSx1LnApClAuazEoYixxKQpmb3IodD10aGlzLmdreih0aGlzKSxzPTA7dC5GKCk7
+KXtyPXQuZ2woKQppZihiPT09cylyZXR1cm4gcjsrK3N9dGhyb3cgSC5iKFAudChiLHRoaXMscSxudWxs
+LHMpKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuRVAodGhpcywiKCIsIikiKX19ClAuQW4ucHJvdG90
+eXBlPXt9ClAuek0ucHJvdG90eXBlPXskaWJROjEsJGljWDoxfQpQLlowLnByb3RvdHlwZT17fQpQLk4z
+LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIk1hcEVudHJ5KCIrSC5kKHRoaXMuYSkrIjog
+IitILmQodGhpcy5iKSsiKSJ9fQpQLmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4g
+UC5NaC5wcm90b3R5cGUuZ2lPLmNhbGwodGhpcyx0aGlzKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIm51
+bGwifX0KUC5sZi5wcm90b3R5cGU9e30KUC5NaC5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlAuTWgsJGlN
+aDoxLApETjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzPT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1
+cm4gSC5lUSh0aGlzKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIkluc3RhbmNlIG9mICciK0guZChILmxo
+KHRoaXMpKSsiJyJ9LAplNzpmdW5jdGlvbihhLGIpe3Uuby5hKGIpCnRocm93IEguYihQLmxyKHRoaXMs
+Yi5nV2EoKSxiLmduZCgpLGIuZ1ZtKCkpKX0sCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMu
+Wih0aGlzKX19ClAuT2QucHJvdG90eXBlPXt9ClAuaWIucHJvdG90eXBlPXskaU9kOjF9ClAueHUucHJv
+dG90eXBlPXt9ClAuR3oucHJvdG90eXBlPXt9ClAuWmQucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXty
+ZXR1cm4iIn0sCiRpR3o6MX0KUC5xVS5wcm90b3R5cGU9eyRpdlg6MX0KUC5Sbi5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sClo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
+cy5hCnJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGlCTDoxfQpQLkdELnByb3RvdHlwZT17
+fQpQLm4xLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5mLmEoYSkKSC5j
+KGIpCnQ9Si5yWShiKS5PWShiLCI9IikKaWYodD09PS0xKXtpZihiIT09IiIpYS5ZKDAsUC5rdShiLDAs
+Yi5sZW5ndGgsdGhpcy5hLCEwKSwiIil9ZWxzZSBpZih0IT09MCl7cz1DLnhCLk5qKGIsMCx0KQpyPUMu
+eEIuRyhiLHQrMSkKcT10aGlzLmEKYS5ZKDAsUC5rdShzLDAscy5sZW5ndGgscSwhMCksUC5rdShyLDAs
+ci5sZW5ndGgscSwhMCkpfXJldHVybiBhfSwKJFM6NDR9ClAuY1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
+b24oYSxiKXt0aHJvdyBILmIoUC5ycigiSWxsZWdhbCBJUHY0IGFkZHJlc3MsICIrYSx0aGlzLmEsYikp
+fSwKJFM6MTl9ClAuVkMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aHJvdyBILmIoUC5ycigi
+SWxsZWdhbCBJUHY2IGFkZHJlc3MsICIrYSx0aGlzLmEsYikpfSwKJDE6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuJDIoYSxudWxsKX0sCiRTOjQ4fQpQLkpULnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
+dmFyIHQKaWYoYi1hPjQpdGhpcy5hLiQyKCJhbiBJUHY2IHBhcnQgY2FuIG9ubHkgY29udGFpbiBhIG1h
+eGltdW0gb2YgNCBoZXggZGlnaXRzIixhKQp0PVAuUUEoQy54Qi5Oaih0aGlzLmIsYSxiKSxudWxsLDE2
+KQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PDB8fHQ+NjU1MzUpdGhpcy5h
+LiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2Ugb2YgYDB4MC4uMHhGRkZGYCIsYSkKcmV0
+dXJuIHR9LAokUzo0OX0KUC5Ebi5wcm90b3R5cGU9ewpna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
+fSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiIiCmlmKEMueEIu
+bih0LCJbIikpcmV0dXJuIEMueEIuTmoodCwxLHQubGVuZ3RoLTEpCnJldHVybiB0fSwKZ3RwOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuZAppZih0PT1udWxsKXJldHVybiBQLndLKHRoaXMuYSkKcmV0dXJuIHR9
+LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYKcmV0dXJuIHQ9PW51bGw/IiI6dH0sCmdLYTpmdW5j
+dGlvbigpe3ZhciB0PXRoaXMucgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKbm06ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwp1LlguYShudWxsKQp1LmsuYShiKQp0PWwuYQpzPXQ9PT0i
+ZmlsZSIKcj1sLmIKcT1sLmQKcD1sLmMKaWYoIShwIT1udWxsKSlwPXIubGVuZ3RoIT09MHx8cSE9bnVs
+bHx8cz8iIjpudWxsCm89bC5lCmlmKCFzKW49cCE9bnVsbCYmby5sZW5ndGghPT0wCmVsc2Ugbj0hMApp
+ZihuJiYhQy54Qi5uKG8sIi8iKSlvPSIvIitvCm09UC5sZShudWxsLDAsMCxiKQpyZXR1cm4gbmV3IFAu
+RG4odCxyLHAscSxvLG0sbC5yKX0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcy54CmlmKHMhPW51
+bGwpcmV0dXJuIHMKdD10aGlzLmUKaWYodC5sZW5ndGghPT0wJiZDLnhCLlcodCwwKT09PTQ3KXQ9Qy54
+Qi5HKHQsMSkKcz10PT09IiI/Qy54RDpQLkFGKG5ldyBILmxKKEguVk0odC5zcGxpdCgiLyIpLHUucyks
+dS5kTy5hKFAuUEgoKSksdS5kbyksdS5OKQp0aGlzLnNvNihzKQpyZXR1cm4gc30sCmdoWTpmdW5jdGlv
+bigpe3ZhciB0LHM9dGhpcwppZihzLlE9PW51bGwpe3Q9cy5mCnMuc1JIKG5ldyBQLkdqKFAuV1godD09
+bnVsbD8iIjp0KSx1LnYpKX1yZXR1cm4gcy5RfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxw
+LG8KZm9yKHQ9MCxzPTA7Qy54Qi5RaShiLCIuLi8iLHMpOyl7cys9MzsrK3R9cj1DLnhCLmNuKGEsIi8i
+KQp3aGlsZSghMCl7aWYoIShyPjAmJnQ+MCkpYnJlYWsKcT1DLnhCLlBrKGEsIi8iLHItMSkKaWYocTww
+KWJyZWFrCnA9ci1xCm89cCE9PTIKaWYoIW98fHA9PT0zKWlmKEMueEIubShhLHErMSk9PT00NilvPSFv
+fHxDLnhCLm0oYSxxKzIpPT09NDYKZWxzZSBvPSExCmVsc2Ugbz0hMQppZihvKWJyZWFrOy0tdApyPXF9
+cmV0dXJuIEMueEIuaTcoYSxyKzEsbnVsbCxDLnhCLkcoYixzLTMqdCkpfSwKWkk6ZnVuY3Rpb24oYSl7
+cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsaz10aGlzLGo9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3Q9YS5nRmkoKQppZihhLmdjaigp
+KXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPWEuZ3hBKCk/YS5ndHAoYSk6an1lbHNle3E9agpyPXEKcz0i
+In1wPVAueGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UCgpOmp9ZWxzZXt0PWsuYQppZihhLmdjaigp
+KXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPVAud0IoYS5neEEoKT9hLmd0cChhKTpqLHQpCnA9UC54ZShh
+LmdJaShhKSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3M9ay5iCnI9ay5jCnE9ay5kCmlmKGEuZ0lp
+KGEpPT09IiIpe3A9ay5lCm89YS5nUUQoKT9hLmd0UCgpOmsuZn1lbHNle2lmKGEuZ3RUKCkpcD1QLnhl
+KGEuZ0lpKGEpKQplbHNle249ay5lCmlmKG4ubGVuZ3RoPT09MClpZihyPT1udWxsKXA9dC5sZW5ndGg9
+PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2UgcD1QLnhlKCIvIithLmdJaShhKSkKZWxzZXtt
+PWsuSmgobixhLmdJaShhKSkKbD10Lmxlbmd0aD09PTAKaWYoIWx8fHIhPW51bGx8fEMueEIubihuLCIv
+IikpcD1QLnhlKG0pCmVsc2UgcD1QLndGKG0sIWx8fHIhPW51bGwpfX1vPWEuZ1FEKCk/YS5ndFAoKTpq
+fX19cmV0dXJuIG5ldyBQLkRuKHQscyxyLHEscCxvLGEuZ1o4KCk/YS5nS2EoKTpqKX0sCmdjajpmdW5j
+dGlvbigpe3JldHVybiB0aGlzLmMhPW51bGx9LApneEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kIT1u
+dWxsfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZiE9bnVsbH0sCmdaODpmdW5jdGlvbigpe3Jl
+dHVybiB0aGlzLnIhPW51bGx9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5uKHRoaXMuZSwiLyIp
+fSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYQppZihxIT09IiImJnEhPT0iZmlsZSIp
+dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChxKSsi
+IFVSSSIpKQpxPXIuZgppZigocT09bnVsbD8iIjpxKSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3Qg
+ZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiKSkKcT1y
+LnIKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBm
+aWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IikpCnQ9JC5PeCgpCmlm
+KEgub1QodCkpcT1QLm1uKHIpCmVsc2V7aWYoci5jIT1udWxsJiZyLmdKZihyKSE9PSIiKUgudmgoUC5M
+NCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdp
+dGggYW4gYXV0aG9yaXR5IikpCnM9ci5nRmooKQpQLmtFKHMsITEpCnE9UC52ZyhDLnhCLm4oci5lLCIv
+Iik/Ii8iOiIiLHMsIi8iKQpxPXEuY2hhckNvZGVBdCgwKT09MD9xOnF9cmV0dXJuIHF9LApaOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD1xLnkKaWYocD09bnVsbCl7cD1xLmEKdD1wLmxlbmd0aCE9
+PTA/cCsiOiI6IiIKcz1xLmMKcj1zPT1udWxsCmlmKCFyfHxwPT09ImZpbGUiKXtwPXQrIi8vIgp0PXEu
+YgppZih0Lmxlbmd0aCE9PTApcD1wK3QrIkAiCmlmKCFyKXArPXMKdD1xLmQKaWYodCE9bnVsbClwPXAr
+IjoiK0guZCh0KX1lbHNlIHA9dApwKz1xLmUKdD1xLmYKaWYodCE9bnVsbClwPXArIj8iK3QKdD1xLnIK
+aWYodCE9bnVsbClwPXArIiMiK3QKcD1xLnk9cC5jaGFyQ29kZUF0KDApPT0wP3A6cH1yZXR1cm4gcH0s
+CkROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZihyPT09
+YilyZXR1cm4hMAppZih1LncuYihiKSlpZihyLmE9PWIuZ0ZpKCkpaWYoci5jIT1udWxsPT09Yi5nY2oo
+KSlpZihyLmI9PWIuZ2t1KCkpaWYoci5nSmYocik9PWIuZ0pmKGIpKWlmKHIuZ3RwKHIpPT1iLmd0cChi
+KSlpZihyLmU9PT1iLmdJaShiKSl7dD1yLmYKcz10PT1udWxsCmlmKCFzPT09Yi5nUUQoKSl7aWYocyl0
+PSIiCmlmKHQ9PT1iLmd0UCgpKXt0PXIucgpzPXQ9PW51bGwKaWYoIXM9PT1iLmdaOCgpKXtpZihzKXQ9
+IiIKdD10PT09Yi5nS2EoKX1lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMX1lbHNlIHQ9ITEKZWxz
+ZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKcmV0
+dXJuIHR9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy56CnJldHVybiB0PT1udWxsP3RoaXMuej1D
+LnhCLmdpTyh0aGlzLlooMCkpOnR9LApzbzY6ZnVuY3Rpb24oYSl7dGhpcy54PXUuYS5hKGEpfSwKc1JI
+OmZ1bmN0aW9uKGEpe3RoaXMuUT11LmYuYShhKX0sCiRpaUQ6MSwKZ0ZpOmZ1bmN0aW9uKCl7cmV0dXJu
+IHRoaXMuYX0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lfX0KUC5lMS5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5ycigiSW52YWxpZCBwb3J0Iix0aGlzLmEsdGhpcy5iKzEp
+KX0sCiRTOjEzfQpQLk5ZLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PSJJbGxlZ2FsIHBh
+dGggY2hhcmFjdGVyICIKSC5jKGEpCmlmKEouemwoYSwiLyIpKWlmKHRoaXMuYSl0aHJvdyBILmIoUC54
+WSh0K2EpKQplbHNlIHRocm93IEguYihQLkw0KHQrYSkpfSwKJFM6MTN9ClAuUloucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5aSixILmMoYSksQy54TSwhMSl9LAokUzo1fQpQLk1F
+LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5iLHM9dGhpcy5hCnQuYSs9cy5h
+CnMuYT0iJiIKcz10LmErPUguZChQLmVQKEMuRjMsYSxDLnhNLCEwKSkKaWYoYiE9bnVsbCYmYi5sZW5n
+dGghPT0wKXt0LmE9cysiPSIKdC5hKz1ILmQoUC5lUChDLkYzLGIsQy54TSwhMCkpfX0sCiRTOjIyfQpQ
+Lnk1LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILmMoYSkKaWYoYj09bnVsbHx8
+dHlwZW9mIGI9PSJzdHJpbmciKXRoaXMuYS4kMihhLEguYyhiKSkKZWxzZSBmb3IodD1KLklUKHUuUi5h
+KGIpKSxzPXRoaXMuYTt0LkYoKTspcy4kMihhLEguYyh0LmdsKCkpKX0sCiRTOjEyfQpQLlBFLnByb3Rv
+dHlwZT17CmdsUjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxvPW51bGwsbj1wLmMKaWYobiE9
+bnVsbClyZXR1cm4gbgpuPXAuYgppZigwPj1uLmxlbmd0aClyZXR1cm4gSC5rKG4sMCkKdD1wLmEKbj1u
+WzBdKzEKcz1DLnhCLlhVKHQsIj8iLG4pCnI9dC5sZW5ndGgKaWYocz49MCl7cT1QLlBJKHQscysxLHIs
+Qy5WQywhMSkKcj1zfWVsc2UgcT1vCnJldHVybiBwLmM9bmV3IFAucWUoImRhdGEiLG8sbyxvLFAuUEko
+dCxuLHIsQy5XZCwhMSkscSxvKX0sClo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYoMD49cy5s
+ZW5ndGgpcmV0dXJuIEguayhzLDApCnQ9dGhpcy5hCnJldHVybiBzWzBdPT09LTE/ImRhdGE6Iit0OnR9
+fQpQLnEzLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVWludDhBcnJheSg5Nil9
+LAokUzoyM30KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZihh
+Pj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYSkKdD10W2FdCkouQ00odCwwLDk2LGIpCnJldHVybiB0fSwK
+JFM6MjR9ClAuYzYucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmZvcih0
+PWIubGVuZ3RoLHM9YS5sZW5ndGgscj0wO3I8dDsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49cyly
+ZXR1cm4gSC5rKGEscSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0LHMscixxCmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5XKGIsMSkscj1hLmxlbmd0aDt0PD1z
+OysrdCl7cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguayhhLHEpCmFbcV09Y319fQpQLlVmLnBy
+b3RvdHlwZT17CmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3Zh
+ciB0LHMKaWYodGhpcy5jPjApe3Q9dGhpcy5kCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQu
+aCgpCnM9dGhpcy5lCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIEgucFkocykKcz10KzE8cwp0
+PXN9ZWxzZSB0PSExCnJldHVybiB0fSwKZ1FEOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mCmlmKHR5cGVv
+ZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCnJldHVybiB0PHRoaXMucn0sCmdaODpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9
+PT00JiZDLnhCLm4odGhpcy5hLCJmaWxlIil9LApndmg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09
+NCYmQy54Qi5uKHRoaXMuYSwiaHR0cCIpfSwKZ1JlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTUm
+JkMueEIubih0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlz
+LmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj0icGFja2FnZSIscT1z
+LmIKaWYocTw9MClyZXR1cm4iIgp0PXMueAppZih0IT1udWxsKXJldHVybiB0CmlmKHMuZ3ZoKCkpcT1z
+Lng9Imh0dHAiCmVsc2UgaWYocy5nUmUoKSl7cy54PSJodHRwcyIKcT0iaHR0cHMifWVsc2UgaWYocy5n
+TncoKSl7cy54PSJmaWxlIgpxPSJmaWxlIn1lbHNlIGlmKHE9PT03JiZDLnhCLm4ocy5hLHIpKXtzLng9
+cgpxPXJ9ZWxzZXtxPUMueEIuTmoocy5hLDAscSkKcy54PXF9cmV0dXJuIHF9LApna3U6ZnVuY3Rpb24o
+KXt2YXIgdD10aGlzLmMscz10aGlzLmIrMwpyZXR1cm4gdD5zP0MueEIuTmoodGhpcy5hLHMsdC0xKToi
+In0sCmdKZjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmMKcmV0dXJuIHQ+MD9DLnhCLk5qKHRoaXMuYSx0
+LHRoaXMuZCk6IiJ9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzCmlmKHMuZ3hBKCkpe3Q9cy5k
+CmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCnJldHVybiBQLlFBKEMueEIuTmoocy5h
+LHQrMSxzLmUpLG51bGwsbnVsbCl9aWYocy5ndmgoKSlyZXR1cm4gODAKaWYocy5nUmUoKSlyZXR1cm4g
+NDQzCnJldHVybiAwfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLk5qKHRoaXMuYSx0aGlzLmUs
+dGhpcy5mKX0sCmd0UDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZixzPXRoaXMucgppZih0eXBlb2YgdCE9
+PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDxzP0MueEIuTmoodGhpcy5hLHQrMSxzKToiIn0s
+CmdLYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMucixzPXRoaXMuYQpyZXR1cm4gdDxzLmxlbmd0aD9DLnhC
+Lkcocyx0KzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMuZSxxPXRoaXMuZixwPXRo
+aXMuYQppZihDLnhCLlFpKHAsIi8iLHIpKXtpZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLmgo
+KTsrK3J9aWYocj09cSlyZXR1cm4gQy54RAp0PUguVk0oW10sdS5zKQpzPXIKd2hpbGUoITApe2lmKHR5
+cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSigpCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJu
+IEgucFkocSkKaWYoIShzPHEpKWJyZWFrCmlmKEMueEIubShwLHMpPT09NDcpe0MuTm0uaSh0LEMueEIu
+TmoocCxyLHMpKQpyPXMrMX0rK3N9Qy5ObS5pKHQsQy54Qi5OaihwLHIscSkpCnJldHVybiBQLkFGKHQs
+dS5OKX0sCmdoWTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJl
+dHVybiB0LkooKQppZih0Pj10aGlzLnIpcmV0dXJuIEMuV08KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhp
+cy5ndFAoKSksdS52KX0sCmtYOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5kCmlmKHR5cGVvZiBzIT09
+Im51bWJlciIpcmV0dXJuIHMuaCgpCnQ9cysxCnJldHVybiB0K2EubGVuZ3RoPT09dGhpcy5lJiZDLnhC
+LlFpKHRoaXMuYSxhLHQpfSwKTjk6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5yLHI9dC5hCmlmKHM+
+PXIubGVuZ3RoKXJldHVybiB0CnJldHVybiBuZXcgUC5VZihDLnhCLk5qKHIsMCxzKSx0LmIsdC5jLHQu
+ZCx0LmUsdC5mLHMsdC54KX0sCm5tOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGss
+aj10aGlzLGk9bnVsbAp1LlguYShudWxsKQp1LmsuYShiKQp0PWouZ0ZpKCkKcz10PT09ImZpbGUiCnI9
+ai5jCnE9cj4wP0MueEIuTmooai5hLGouYiszLHIpOiIiCnA9ai5neEEoKT9qLmd0cChqKTppCnI9ai5j
+CmlmKHI+MClvPUMueEIuTmooai5hLHIsai5kKQplbHNlIG89cS5sZW5ndGghPT0wfHxwIT1udWxsfHxz
+PyIiOmkKcj1qLmEKbj1DLnhCLk5qKHIsai5lLGouZikKaWYoIXMpbT1vIT1udWxsJiZuLmxlbmd0aCE9
+PTAKZWxzZSBtPSEwCmlmKG0mJiFDLnhCLm4obiwiLyIpKW49Ii8iK24KbD1QLmxlKGksMCwwLGIpCm09
+ai5yCms9bTxyLmxlbmd0aD9DLnhCLkcocixtKzEpOmkKcmV0dXJuIG5ldyBQLkRuKHQscSxvLHAsbixs
+LGspfSwKWkk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihh
+KXtpZihhIGluc3RhbmNlb2YgUC5VZilyZXR1cm4gdGhpcy51MSh0aGlzLGEpCnJldHVybiB0aGlzLnZz
+KCkubVMoYSl9LAp1MTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcs
+ZixlPWIuYgppZihlPjApcmV0dXJuIGIKdD1iLmMKaWYodD4wKXtzPWEuYgppZihzPD0wKXJldHVybiBi
+CmlmKGEuZ053KCkpcj1iLmUhPWIuZgplbHNlIGlmKGEuZ3ZoKCkpcj0hYi5rWCgiODAiKQplbHNlIHI9
+IWEuZ1JlKCl8fCFiLmtYKCI0NDMiKQppZihyKXtxPXMrMQpwPUMueEIuTmooYS5hLDAscSkrQy54Qi5H
+KGIuYSxlKzEpCmU9Yi5kCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCm89Yi5lCmlm
+KHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8uaCgpCm49Yi5mCmlmKHR5cGVvZiBuIT09Im51bWJl
+ciIpcmV0dXJuIG4uaCgpCnJldHVybiBuZXcgUC5VZihwLHMsdCtxLGUrcSxvK3EsbitxLGIucitxLGEu
+eCl9ZWxzZSByZXR1cm4gdGhpcy52cygpLm1TKGIpfW09Yi5lCmU9Yi5mCmlmKG09PWUpe3Q9Yi5yCmlm
+KHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuSigpCmlmKGU8dCl7cz1hLmYKaWYodHlwZW9mIHMh
+PT0ibnVtYmVyIilyZXR1cm4gcy5ITigpCnE9cy1lCnJldHVybiBuZXcgUC5VZihDLnhCLk5qKGEuYSww
+LHMpK0MueEIuRyhiLmEsZSksYS5iLGEuYyxhLmQsYS5lLGUrcSx0K3EsYS54KX1lPWIuYQppZih0PGUu
+bGVuZ3RoKXtzPWEucgpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLkcoZSx0KSxh
+LmIsYS5jLGEuZCxhLmUsYS5mLHQrKHMtdCksYS54KX1yZXR1cm4gYS5OOSgpfXQ9Yi5hCmlmKEMueEIu
+UWkodCwiLyIsbSkpe3M9YS5lCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSE4oKQppZih0
+eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCnE9cy1tCnA9Qy54Qi5OaihhLmEsMCxzKStD
+LnhCLkcodCxtKQppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpyZXR1cm4gbmV3IFAu
+VWYocCxhLmIsYS5jLGEuZCxzLGUrcSxiLnIrcSxhLngpfWw9YS5lCms9YS5mCmlmKGw9PWsmJmEuYz4w
+KXtmb3IoO0MueEIuUWkodCwiLi4vIixtKTspe2lmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0u
+aCgpCm0rPTN9aWYodHlwZW9mIGwhPT0ibnVtYmVyIilyZXR1cm4gbC5ITigpCmlmKHR5cGVvZiBtIT09
+Im51bWJlciIpcmV0dXJuIEgucFkobSkKcT1sLW0rMQpwPUMueEIuTmooYS5hLDAsbCkrIi8iK0MueEIu
+Ryh0LG0pCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCnJldHVybiBuZXcgUC5VZihw
+LGEuYixhLmMsYS5kLGwsZStxLGIucitxLGEueCl9aj1hLmEKZm9yKGk9bDtDLnhCLlFpKGosIi4uLyIs
+aSk7KXtpZih0eXBlb2YgaSE9PSJudW1iZXIiKXJldHVybiBpLmgoKQppKz0zfWg9MAp3aGlsZSghMCl7
+aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5oKCkKZz1tKzMKaWYodHlwZW9mIGUhPT0ibnVt
+YmVyIilyZXR1cm4gSC5wWShlKQppZighKGc8PWUmJkMueEIuUWkodCwiLi4vIixtKSkpYnJlYWs7Kyto
+Cm09Z31mPSIiCndoaWxlKCEwKXtpZih0eXBlb2YgayE9PSJudW1iZXIiKXJldHVybiBrLm9zKCkKaWYo
+dHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShpKQppZighKGs+aSkpYnJlYWs7LS1rCmlmKEMu
+eEIubShqLGspPT09NDcpe2lmKGg9PT0wKXtmPSIvIgpicmVha30tLWgKZj0iLyJ9fWlmKGs9PT1pJiZh
+LmI8PTAmJiFDLnhCLlFpKGosIi8iLGwpKXttLT1oKjMKZj0iIn1xPWstbStmLmxlbmd0aApyZXR1cm4g
+bmV3IFAuVWYoQy54Qi5OaihqLDAsaykrZitDLnhCLkcodCxtKSxhLmIsYS5jLGEuZCxsLGUrcSxiLnIr
+cSxhLngpfSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMKaWYocC5iPj0wJiYhcC5nTnco
+KSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrSC5kKHAu
+Z0ZpKCkpKyIgVVJJIikpCnQ9cC5mCnM9cC5hCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQu
+SigpCmlmKHQ8cy5sZW5ndGgpe2lmKHQ8cC5yKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBh
+IGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiKSkKdGhyb3cgSC5iKFAu
+TDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNv
+bXBvbmVudCIpKX1yPSQuT3goKQppZihILm9UKHIpKXQ9UC5tbihwKQplbHNle3E9cC5kCmlmKHR5cGVv
+ZiBxIT09Im51bWJlciIpcmV0dXJuIEgucFkocSkKaWYocC5jPHEpSC52aChQLkw0KCJDYW5ub3QgZXh0
+cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBhdXRob3Jp
+dHkiKSkKdD1DLnhCLk5qKHMscC5lLHQpfXJldHVybiB0fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMueQpyZXR1cm4gdD09bnVsbD90aGlzLnk9Qy54Qi5naU8odGhpcy5hKTp0fSwKRE46ZnVuY3Rpb24o
+YSxiKXtpZihiPT1udWxsKXJldHVybiExCmlmKHRoaXM9PT1iKXJldHVybiEwCnJldHVybiB1LncuYihi
+KSYmdGhpcy5hPT09Yi5aKDApfSwKdnM6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9bnVsbCxyPXQuZ0Zp
+KCkscT10LmdrdSgpLHA9dC5jPjA/dC5nSmYodCk6cyxvPXQuZ3hBKCk/dC5ndHAodCk6cyxuPXQuYSxt
+PXQuZixsPUMueEIuTmoobix0LmUsbSksaz10LnIKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4g
+bS5KKCkKbT1tPGs/dC5ndFAoKTpzCnJldHVybiBuZXcgUC5EbihyLHEscCxvLGwsbSxrPG4ubGVuZ3Ro
+P3QuZ0thKCk6cyl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokaWlEOjF9ClAucWUucHJv
+dG90eXBlPXt9ClcucUUucHJvdG90eXBlPXt9ClcuR2gucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXty
+ZXR1cm4gU3RyaW5nKGEpfSwKJGlHaDoxfQpXLmZZLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0
+dXJuIFN0cmluZyhhKX19ClcubkIucHJvdG90eXBlPXskaW5COjF9ClcuQXoucHJvdG90eXBlPXskaUF6
+OjF9ClcuUVAucHJvdG90eXBlPXskaVFQOjF9ClcubngucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
+cmV0dXJuIGEubGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
+ZW5ndGh9fQpXLmlkLnByb3RvdHlwZT17fQpXLlFGLnByb3RvdHlwZT17fQpXLk5oLnByb3RvdHlwZT17
+Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcuSUIucHJvdG90eXBlPXsKWjpmdW5jdGlv
+bihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0gu
+ZChhLndpZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxs
+KXJldHVybiExCnJldHVybiB1LnEuYihiKSYmYS5sZWZ0PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYmYS53
+aWR0aD09Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBX
+LnJFKEouaGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhmKGEud2lkdGgpLEouaGYoYS5oZWlnaHQpKX0s
+CiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
+Lnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKcTpmdW5j
+dGlvbihhLGIpe3ZhciB0CkguV1koYikKdD10aGlzLmEKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4g
+SC5rKHQsYikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0W2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMu
+JHRpLmMuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBsaXN0IikpfX0KVy5jdi5wcm90
+b3R5cGU9ewpnUWc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmk3KGEpfSwKZ1A6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBXLkk0KGEpfSwKc1A6ZnVuY3Rpb24oYSxiKXt2YXIgdAp1LlguYShiKQp0PXRoaXMu
+Z1AoYSkKdC5WMSgwKQp0LkZWKDAsYil9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2FsTmFtZX0s
+CkZGOmZ1bmN0aW9uKGEpe3ZhciB0PSEhYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkCmlmKHQpYS5zY3Jv
+bGxJbnRvVmlld0lmTmVlZGVkKCkKZWxzZSBhLnNjcm9sbEludG9WaWV3KCl9LApuejpmdW5jdGlvbihh
+LGIsYyxkLGUpe3ZhciB0LHM9dGhpcy5yNihhLGMsZCxlKQpzd2l0Y2goYi50b0xvd2VyQ2FzZSgpKXtj
+YXNlImJlZm9yZWJlZ2luIjphLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHMsYSkKYnJlYWsKY2FzZSJh
+ZnRlcmJlZ2luIjp0PWEuY2hpbGROb2RlcwphLmluc2VydEJlZm9yZShzLHQubGVuZ3RoPjA/dFswXTpu
+dWxsKQpicmVhawpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChzKQpicmVhawpjYXNlImFmdGVy
+ZW5kIjphLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHMsYS5uZXh0U2libGluZykKYnJlYWsKZGVmYXVs
+dDpILnZoKFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9fSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7
+dmFyIHQscyxyLHEKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7dD0kLmx0CmlmKHQ9PW51bGwpe3Q9SC5W
+TShbXSx1LmkpCnM9bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQsVy5CbCgp
+KQokLmx0PXMKZD1zfWVsc2UgZD10fXQ9JC5FVQppZih0PT1udWxsKXt0PW5ldyBXLktvKGQpCiQuRVU9
+dApjPXR9ZWxzZXt0LmE9ZApjPXR9fWVsc2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgidmFsaWRh
+dG9yIGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRpemVyIGlzIG51bGwiKSkKaWYoJC54bz09
+bnVsbCl7dD1kb2N1bWVudApzPXQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCIiKQok
+LnhvPXMKJC5CTz1zLmNyZWF0ZVJhbmdlKCkKcz0kLnhvLmNyZWF0ZUVsZW1lbnQoImJhc2UiKQp1LmNS
+LmEocykKcy5ocmVmPXQuYmFzZVVSSQokLnhvLmhlYWQuYXBwZW5kQ2hpbGQocyl9dD0kLnhvCmlmKHQu
+Ym9keT09bnVsbCl7cz10LmNyZWF0ZUVsZW1lbnQoImJvZHkiKQp0LmJvZHk9dS5ZLmEocyl9dD0kLnhv
+CmlmKHUuWS5iKGEpKXI9dC5ib2R5CmVsc2V7cj10LmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhv
+LmJvZHkuYXBwZW5kQ2hpbGQocil9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93
+LlJhbmdlLnByb3RvdHlwZSYmIUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVD
+b250ZW50cyhyKQpxPSQuQk8uY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGIpfWVsc2V7ci5pbm5lckhU
+TUw9YgpxPSQueG8uY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCmZvcig7dD1yLmZpcnN0Q2hpbGQsdCE9
+bnVsbDspcS5hcHBlbmRDaGlsZCh0KX10PSQueG8uYm9keQppZihyPT1udWxsP3QhPW51bGw6ciE9PXQp
+Si5MdChyKQpjLlBuKHEpCmRvY3VtZW50LmFkb3B0Tm9kZShxKQpyZXR1cm4gcX0sCkFIOmZ1bmN0aW9u
+KGEsYixjKXtyZXR1cm4gdGhpcy5yNihhLGIsYyxudWxsKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMu
+WUMoYSxiKX0sCnBrOmZ1bmN0aW9uKGEsYixjKXthLnRleHRDb250ZW50PW51bGwKYS5hcHBlbmRDaGls
+ZCh0aGlzLnI2KGEsYixudWxsLGMpKX0sCllDOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxi
+LG51bGwpfSwKZ25zOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRhZ05hbWV9LApnVmw6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBXLmV1KGEsImNsaWNrIiwhMSx1LlEpfSwKJGljdjoxfQpXLkN2LnByb3RvdHlwZT17
+CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LmguYih1LkEuYShhKSl9LAokUzoyNX0KVy5lYS5wcm90b3R5
+cGU9eyRpZWE6MX0KVy5EMC5wcm90b3R5cGU9ewpPbjpmdW5jdGlvbihhLGIsYyxkKXt1LlUuYShjKQpp
+ZihjIT1udWxsKXRoaXMudihhLGIsYyxkKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9u
+KGEsYixjLG51bGwpfSwKdjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVy
+KGIsSC50Uih1LlUuYShjKSwxKSxkKX0sCiRpRDA6MX0KVy5oSC5wcm90b3R5cGU9eyRpaEg6MX0KVy5o
+NC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmJyLnByb3RvdHlw
+ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuVmIucHJvdG90eXBlPXt9ClcuZkou
+cHJvdG90eXBlPXsKZW86ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIGEub3BlbihiLGMsITApfSwKJGlm
+SjoxfQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnByb3RvdHlwZT17JGlTZzoxfQpXLnU4LnByb3RvdHlw
+ZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2luIiBpbiBhKXJldHVybiBhLm9yaWdpbgpyZXR1cm4g
+SC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9zdCl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBTdHJp
+bmcoYSl9LAokaXU4OjF9ClcuT0sucHJvdG90eXBlPXskaU9LOjF9ClcuZTcucHJvdG90eXBlPXsKZ3I4
+OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5ndGgKaWYocz09PTApdGhy
+b3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIoUC5QVigiTW9yZSB0aGFu
+IG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0Q2hpbGR9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMscixxCnUuZWguYShiKQp0PWIuYQpzPXRoaXMuYQppZih0IT09cylmb3Iocj10LmNoaWxkTm9kZXMu
+bGVuZ3RoLHE9MDtxPHI7KytxKXMuYXBwZW5kQ2hpbGQodC5maXJzdENoaWxkKQpyZXR1cm59LApZOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5hKGMpCnQ9dGhpcy5hCnM9dC5jaGlsZE5vZGVzCmlmKGI8
+MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguayhzLGIpCnQucmVwbGFjZUNoaWxkKGMsc1tiXSl9LApna3o6
+ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmNoaWxkTm9kZXMKcmV0dXJuIG5ldyBXLlc5KHQsdC5sZW5n
+dGgsSC5xKHQpLkMoIlc5PEdtLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jaGls
+ZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILldZKGIpCnQ9dGhpcy5hLmNoaWxk
+Tm9kZXMKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikKcmV0dXJuIHRbYl19fQpXLnVI
+LnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEpe3ZhciB0PWEucGFyZW50Tm9kZQppZih0IT1udWxsKXQu
+cmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlvbihhKXt2YXIgdApmb3IoO3Q9YS5maXJzdENoaWxkLHQh
+PW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LApaOmZ1bmN0aW9uKGEpe3ZhciB0PWEubm9kZVZhbHVlCnJl
+dHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwKJGl1SDoxfQpXLkJILnByb3RvdHlwZT17CmdBOmZ1bmN0
+aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCmlmKGI+Pj4wIT09
+Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAudChiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVti
+XX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWdu
+IGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49
+YS5sZW5ndGgpcmV0dXJuIEguayhhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6
+MSwKJGl6TToxfQpXLlNOLnByb3RvdHlwZT17fQpXLmV3LnByb3RvdHlwZT17JGlldzoxfQpXLmxwLnBy
+b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuVGIucHJvdG90eXBlPXsK
+cjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBp
+biB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9Vy5VOSgiPHRh
+YmxlPiIrSC5kKGIpKyI8L3RhYmxlPiIsYyxkKQpzPWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21l
+bnQoKQpzLnRvU3RyaW5nCnQudG9TdHJpbmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyh0KSkKcmV0
+dXJuIHN9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlm
+KCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJu
+IHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9
+Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9TdHJpbmcKdD1uZXcgVy5l
+Nyh0KQpyPXQuZ3I4KHQpCnIudG9TdHJpbmcKdD1uZXcgVy5lNyhyKQpxPXQuZ3I4KHQpCnMudG9TdHJp
+bmcKcS50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBXLmU3KHEpKQpyZXR1cm4gc319ClcuV1Au
+cHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmlmKCJjcmVhdGVDb250ZXh0
+dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMs
+ZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0
+ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQp
+CnMudG9TdHJpbmcKci50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBXLmU3KHIpKQpyZXR1cm4g
+c319ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKYS50ZXh0Q29udGVu
+dD1udWxsCnQ9YS5jb250ZW50CnQudG9TdHJpbmcKSi5iVCh0KQpzPXRoaXMucjYoYSxiLG51bGwsYykK
+YS5jb250ZW50LmFwcGVuZENoaWxkKHMpfSwKWUM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5wayhh
+LGIsbnVsbCl9LAokaXlZOjF9ClcudzYucHJvdG90eXBlPXt9ClcuSzUucHJvdG90eXBlPXsKUG86ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0PVcuUDEoYS5vcGVuKGIsYykpCnJldHVybiB0fSwKZ21XOmZ1bmN0aW9u
+KGEpe3JldHVybiBhLmxvY2F0aW9ufSwKJGlLNToxLAokaXY2OjF9ClcuQ20ucHJvdG90eXBlPXskaUNt
+OjF9ClcuQ1EucHJvdG90eXBlPXskaUNROjF9ClcudzQucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXty
+ZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0guZChhLndp
+ZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVy
+biExCnJldHVybiB1LnEuYihiKSYmYS5sZWZ0PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYmYS53aWR0aD09
+Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBXLnJFKEou
+aGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhmKGEud2lkdGgpLEouaGYoYS5oZWlnaHQpKX19Clcucmgu
+cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
+e0guV1koYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC50KGIsYSxudWxsLG51
+bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7dS5BLmEoYykKdGhyb3cgSC5i
+KFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApFOmZ1bmN0
+aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5rKGEsYikKcmV0dXJuIGFbYl19LAok
+aWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuY2YucHJvdG90eXBlPXsKSzpmdW5jdGlvbihh
+LGIpe3ZhciB0LHMscixxLHAKdS5lQS5hKGIpCmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhp
+cy5hLHE9MDtxPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4k
+MihwLHIuZ2V0QXR0cmlidXRlKHApKX19LApnVjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5h
+LmF0dHJpYnV0ZXMsbz1ILlZNKFtdLHUucykKZm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9MDtyPHQ7Kyty
+KXtpZihyPj1wLmxlbmd0aClyZXR1cm4gSC5rKHAscikKcT1zLmEocFtyXSkKaWYocS5uYW1lc3BhY2VV
+Ukk9PW51bGwpQy5ObS5pKG8scS5uYW1lKX1yZXR1cm4gb30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4g
+dGhpcy5nVigpLmxlbmd0aD09PTB9fQpXLmk3LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLmEuaGFzQXR0cmlidXRlKGEpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuZ2V0
+QXR0cmlidXRlKEguYyhiKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0cmlidXRlKGIs
+Yyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3kucHJvdG90eXBl
+PXsKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hLmhhc0F0dHJpYnV0ZSgiZGF0YS0iK3RoaXMu
+TyhhKSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5hLmdldEF0dHJpYnV0ZSgiZGF0YS0i
+K3RoaXMuTyhILmMoYikpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgi
+ZGF0YS0iK3RoaXMuTyhiKSxjKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRo
+aXMsdS5lQS5hKGIpKSl9LApnVjpmdW5jdGlvbigpe3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEuSygw
+LG5ldyBXLkEzKHRoaXMsdCkpCnJldHVybiB0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1Yo
+KS5sZW5ndGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGg9PT0wfSwKazpm
+dW5jdGlvbihhKXt2YXIgdCxzLHI9SC5WTShhLnNwbGl0KCItIiksdS5zKQpmb3IodD0xO3Q8ci5sZW5n
+dGg7Kyt0KXtzPXJbdF0KaWYocy5sZW5ndGg+MClDLk5tLlkocix0LHNbMF0udG9VcHBlckNhc2UoKStK
+LktWKHMsMSkpfXJldHVybiBDLk5tLkgociwiIil9LApPOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAK
+Zm9yKHQ9YS5sZW5ndGgscz0wLHI9IiI7czx0Oysrcyl7cT1hW3NdCnA9cS50b0xvd2VyQ2FzZSgpCnI9
+KHEhPT1wJiZzPjA/cisiLSI6cikrcH1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn19ClcuS1Mu
+cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSl0aGlzLmIu
+JDIodGhpcy5hLmsoQy54Qi5HKGEsNSkpLGIpfSwKJFM6MTR9ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVu
+Y3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS5rKEMu
+eEIuRyhhLDUpKSl9LAokUzoxNH0KVy5JNC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKCl7dmFyIHQscyxy
+LHEscD1QLkxzKHUuTikKZm9yKHQ9dGhpcy5hLmNsYXNzTmFtZS5zcGxpdCgiICIpLHM9dC5sZW5ndGgs
+cj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9PTApcC5pKDAscSl9cmV0dXJuIHB9
+LApYOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9dS5DLmEoYSkuSCgwLCIgIil9LApnQTpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGh9LApWMTpmdW5jdGlvbihhKXt0aGlz
+LmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LmNv
+bnRhaW5zKGIpCnJldHVybiB0fSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5jbGFzc0xpc3Qs
+cz10LmNvbnRhaW5zKGIpCnQuYWRkKGIpCnJldHVybiFzfSwKUjpmdW5jdGlvbihhLGIpe3ZhciB0PXRo
+aXMuYS5jbGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQucmVtb3ZlKGIpCnJldHVybiBzfSwKRlY6ZnVu
+Y3Rpb24oYSxiKXtXLlROKHRoaXMuYSx1LlguYShiKSl9fQpXLkZrLnByb3RvdHlwZT17fQpXLlJPLnBy
+b3RvdHlwZT17fQpXLmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3RvdHlwZT17fQpXLnZOLnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodS5CLmEoYSkpfSwKJFM6Mjd9ClcuSlEu
+cHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoJC5vci5hPT09MCl7Zm9yKHQ9MDt0PDI2
+MjsrK3QpJC5vci5ZKDAsQy5jbVt0XSxXLnBTKCkpCmZvcih0PTA7dDwxMjsrK3QpJC5vci5ZKDAsQy5C
+SVt0XSxXLlY0KCkpfX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiAkLkFOKCkudGcoMCxXLnJTKGEpKX0s
+CkViOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD0kLm9yLnEoMCxILmQoVy5yUyhhKSkrIjo6IitiKQppZih0
+PT1udWxsKXQ9JC5vci5xKDAsIio6OiIrYikKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gSC5FOSh0
+LiQ0KGEsYixjLHRoaXMpKX0sCiRpa0Y6MX0KVy5HbS5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBXLlc5KGEsdGhpcy5nQShhKSxILnEoYSkuQygiVzk8R20uRT4iKSl9fQpXLnZELnBy
+b3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5VdihhKSl9
+LApFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLkVnKGEsYixjKSl9
+LAokaWtGOjF9ClcuVXYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuZS5hKGEpLmkw
+KHRoaXMuYSl9LAokUzoxNX0KVy5FZy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5l
+LmEoYSkuRWIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MTV9ClcubTYucHJvdG90eXBlPXsKQ1k6
+ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCnRoaXMuYS5GVigwLGMpCnQ9Yi5ldigwLG5ldyBXLkVv
+KCkpCnM9Yi5ldigwLG5ldyBXLldrKCkpCnRoaXMuYi5GVigwLHQpCnI9dGhpcy5jCnIuRlYoMCxDLnhE
+KQpyLkZWKDAscyl9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLnRnKDAsVy5yUyhhKSl9LApF
+YjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9dGhpcyxzPVcuclMoYSkscj10LmMKaWYoci50ZygwLEguZChz
+KSsiOjoiK2IpKXJldHVybiB0LmQuRHQoYykKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuIHQu
+ZC5EdChjKQplbHNle3I9dC5iCmlmKHIudGcoMCxILmQocykrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlm
+KHIudGcoMCwiKjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCxILmQocykrIjo6KiIpKXJldHVy
+biEwCmVsc2UgaWYoci50ZygwLCIqOjoqIikpcmV0dXJuITB9cmV0dXJuITF9LAokaWtGOjF9ClcuRW8u
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIUMuTm0udGcoQy5CSSxILmMoYSkpfSwKJFM6
+N30KVy5Xay5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJLEguYyhh
+KSl9LAokUzo3fQpXLmN0LnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtpZih0aGlzLmpGKGEs
+YixjKSlyZXR1cm4hMAppZihiPT09InRlbXBsYXRlIiYmYz09PSIiKXJldHVybiEwCmlmKGEuZ2V0QXR0
+cmlidXRlKCJ0ZW1wbGF0ZSIpPT09IiIpcmV0dXJuIHRoaXMuZS50ZygwLGIpCnJldHVybiExfX0KVy5J
+QS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4iVEVNUExBVEU6OiIrSC5kKEguYyhhKSl9
+LAokUzo1fQpXLk93LnByb3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuYU8uYihhKSly
+ZXR1cm4hMQp0PXUuZzcuYihhKQppZih0JiZXLnJTKGEpPT09ImZvcmVpZ25PYmplY3QiKXJldHVybiEx
+CmlmKHQpcmV0dXJuITAKcmV0dXJuITF9LApFYjpmdW5jdGlvbihhLGIsYyl7aWYoYj09PSJpcyJ8fEMu
+eEIubihiLCJvbiIpKXJldHVybiExCnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3Rv
+dHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5jKzEscj10LmIKaWYoczxyKXt0LnNwKEou
+eDkodC5hLHMpKQp0LmM9cwpyZXR1cm4hMH10LnNwKG51bGwpCnQuYz1yCnJldHVybiExfSwKZ2w6ZnVu
+Y3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKc3A6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmMuYShh
+KX0sCiRpQW46MX0KVy5kVy5wcm90b3R5cGU9ewpnbVc6ZnVuY3Rpb24oYSl7cmV0dXJuIFcuSEgodGhp
+cy5hLmxvY2F0aW9uKX0sCiRpRDA6MSwKJGl2NjoxfQpXLkZiLnByb3RvdHlwZT17fQpXLmtGLnByb3Rv
+dHlwZT17fQpXLm1rLnByb3RvdHlwZT17JGl5MDoxfQpXLktvLnByb3RvdHlwZT17ClBuOmZ1bmN0aW9u
+KGEpe3ZhciB0PXRoaXMscz1uZXcgVy5mbSh0KQp0LmI9ITEKcy4kMihhLG51bGwpCmZvcig7dC5iOyl7
+dC5iPSExCnMuJDIoYSxudWxsKX19LApFUDpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYj0hMAppZihi
+IT1udWxsP2IhPT1hLnBhcmVudE5vZGU6dClKLkx0KGEpCmVsc2UgYi5yZW1vdmVDaGlsZChhKX0sCkk0
+OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPSEwLG49bnVsbCxtPW51bGwKdHJ5e249Si5pZyhh
+KQptPW4uYS5nZXRBdHRyaWJ1dGUoImlzIikKdS5oLmEoYSkKdD1mdW5jdGlvbihjKXtpZighKGMuYXR0
+cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkpcmV0dXJuIHRydWUKaWYoYy5pZD09J2xhc3RD
+aGlsZCd8fGMubmFtZT09J2xhc3RDaGlsZCd8fGMuaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxjLm5hbWU9
+PSdwcmV2aW91c1NpYmxpbmcnfHxjLmlkPT0nY2hpbGRyZW4nfHxjLm5hbWU9PSdjaGlsZHJlbicpcmV0
+dXJuIHRydWUKdmFyIGw9Yy5jaGlsZE5vZGVzCmlmKGMubGFzdENoaWxkJiZjLmxhc3RDaGlsZCE9PWxb
+bC5sZW5ndGgtMV0pcmV0dXJuIHRydWUKaWYoYy5jaGlsZHJlbilpZighKGMuY2hpbGRyZW4gaW5zdGFu
+Y2VvZiBIVE1MQ29sbGVjdGlvbnx8Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIE5vZGVMaXN0KSlyZXR1cm4g
+dHJ1ZQp2YXIgaz0wCmlmKGMuY2hpbGRyZW4paz1jLmNoaWxkcmVuLmxlbmd0aApmb3IodmFyIGo9MDtq
+PGs7aisrKXt2YXIgaT1jLmNoaWxkcmVuW2pdCmlmKGkuaWQ9PSdhdHRyaWJ1dGVzJ3x8aS5uYW1lPT0n
+YXR0cmlidXRlcyd8fGkuaWQ9PSdsYXN0Q2hpbGQnfHxpLm5hbWU9PSdsYXN0Q2hpbGQnfHxpLmlkPT0n
+cHJldmlvdXNTaWJsaW5nJ3x8aS5uYW1lPT0ncHJldmlvdXNTaWJsaW5nJ3x8aS5pZD09J2NoaWxkcmVu
+J3x8aS5uYW1lPT0nY2hpbGRyZW4nKXJldHVybiB0cnVlfXJldHVybiBmYWxzZX0oYSkKbz1ILm9UKHQp
+PyEwOiEoYS5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKX1jYXRjaChxKXtILlJ1KHEp
+fXM9ImVsZW1lbnQgdW5wcmludGFibGUiCnRyeXtzPUouQWMoYSl9Y2F0Y2gocSl7SC5SdShxKX10cnl7
+cj1XLnJTKGEpCnRoaXMua1IodS5oLmEoYSksYixvLHMscix1LkcuYShuKSxILmMobSkpfWNhdGNoKHEp
+e2lmKEguUnUocSkgaW5zdGFuY2VvZiBQLkFUKXRocm93IHEKZWxzZXt0aGlzLkVQKGEsYikKd2luZG93
+CnA9IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5kKHMpCmlmKHR5cGVvZiBjb25zb2xlIT0i
+dW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApfX19LAprUjpmdW5jdGlvbihhLGIsYyxkLGUs
+ZixnKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzCmlmKGMpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3Zp
+bmcgZWxlbWVudCBkdWUgdG8gY29ycnVwdGVkIGF0dHJpYnV0ZXMgb24gPCIrZCsiPiIKaWYodHlwZW9m
+IGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufWlmKCFuLmEu
+aTAoYSkpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBlbGVtZW50IDwiK0gu
+ZChlKSsiPiBmcm9tICIrSC5kKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cu
+Y29uc29sZS53YXJuKHQpCnJldHVybn1pZihnIT1udWxsKWlmKCFuLmEuRWIoYSwiaXMiLGcpKXtuLkVQ
+KGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24gPCIrSC5kKGUp
+KycgaXM9IicrZysnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29s
+ZS53YXJuKHQpCnJldHVybn10PWYuZ1YoKQpzPUguVk0odC5zbGljZSgwKSxILnQ2KHQpLkMoImpkPDE+
+IikpCmZvcihyPWYuZ1YoKS5sZW5ndGgtMSx0PWYuYTtyPj0wOy0tcil7aWYocj49cy5sZW5ndGgpcmV0
+dXJuIEguayhzLHIpCnE9c1tyXQpwPW4uYQpvPUouY0gocSkKSC5jKHEpCmlmKCFwLkViKGEsbyx0Lmdl
+dEF0dHJpYnV0ZShxKSkpe3dpbmRvdwpwPSJSZW1vdmluZyBkaXNhbGxvd2VkIGF0dHJpYnV0ZSA8IitI
+LmQoZSkrIiAiK3ErJz0iJytILmQodC5nZXRBdHRyaWJ1dGUocSkpKyciPicKaWYodHlwZW9mIGNvbnNv
+bGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocCkKdC5yZW1vdmVBdHRyaWJ1dGUocSl9
+fWlmKHUuYVcuYihhKSluLlBuKGEuY29udGVudCl9LAokaW9uOjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nh
+c2UgMTpuLkk0KGEsYikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZh
+dWx0Om4uRVAoYSxiKX10PWEubGFzdENoaWxkCmZvcihyPXUuQTtudWxsIT10Oyl7cz1udWxsCnRyeXtz
+PXQucHJldmlvdXNTaWJsaW5nCmlmKHMhPW51bGwpe3E9cy5uZXh0U2libGluZwpwPXQKcD1xPT1udWxs
+P3AhPW51bGw6cSE9PXAKcT1wfWVsc2UgcT0hMQppZihxKXtxPVAuUFYoIkNvcnJ1cHQgSFRNTCIpCnRo
+cm93IEguYihxKX19Y2F0Y2gobyl7SC5SdShvKQpxPXIuYSh0KQpuLmI9ITAKcD1xLnBhcmVudE5vZGUK
+cD1hPT1udWxsP3AhPW51bGw6YSE9PXAKaWYocCl7cD1xLnBhcmVudE5vZGUKaWYocCE9bnVsbClwLnJl
+bW92ZUNoaWxkKHEpfWVsc2UgYS5yZW1vdmVDaGlsZChxKQp0PW51bGwKcz1hLmxhc3RDaGlsZH1pZih0
+IT1udWxsKXRoaXMuJDIodCxhKQp0PXN9fSwKJFM6MzB9ClcuTGUucHJvdG90eXBlPXt9ClcuSzcucHJv
+dG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9ClcuWFcucHJvdG90eXBlPXt9Clcub2EucHJvdG90eXBl
+PXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmEscj1zLmxlbmd0
+aApmb3IodD0wO3Q8cjsrK3QpaWYoc1t0XT09PWEpcmV0dXJuIHQKQy5ObS5pKHMsYSkKQy5ObS5pKHRo
+aXMuYixudWxsKQpyZXR1cm4gcn0sClB2OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD17fQpp
+ZihhPT1udWxsKXJldHVybiBhCmlmKEguclEoYSkpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIi
+KXJldHVybiBhCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5p
+UClyZXR1cm4gbmV3IERhdGUoYS5hKQppZih1LmZ2LmIoYSkpdGhyb3cgSC5iKFAubigic3RydWN0dXJl
+ZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodS5jOC5iKGEpKXJldHVybiBhCmlmKHUuZC5iKGEpKXJldHVy
+biBhCmlmKHUuSS5iKGEpKXJldHVybiBhCnQ9dS5kRC5iKGEpfHwhMQppZih0KXJldHVybiBhCmlmKHUu
+Ry5iKGEpKXtzPXEuVkgoYSkKdD1xLmIKaWYocz49dC5sZW5ndGgpcmV0dXJuIEguayh0LHMpCnI9cC5h
+PXRbc10KaWYociE9bnVsbClyZXR1cm4gcgpyPXt9CnAuYT1yCkMuTm0uWSh0LHMscikKYS5LKDAsbmV3
+IFAuamcocCxxKSkKcmV0dXJuIHAuYX1pZih1LmouYihhKSl7cz1xLlZIKGEpCnA9cS5iCmlmKHM+PXAu
+bGVuZ3RoKXJldHVybiBILmsocCxzKQpyPXBbc10KaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gcS5l
+ayhhLHMpfWlmKHUuZUguYihhKSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBI
+LmsodCxzKQpyPXAuYj10W3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17fQpwLmI9cgpDLk5tLlkodCxz
+LHIpCnEuaW0oYSxuZXcgUC5UYShwLHEpKQpyZXR1cm4gcC5ifXRocm93IEguYihQLm4oInN0cnVjdHVy
+ZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVrOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1KLlU2KGEp
+LHI9cy5nQShhKSxxPW5ldyBBcnJheShyKQpDLk5tLlkodGhpcy5iLGIscSkKZm9yKHQ9MDt0PHI7Kyt0
+KUMuTm0uWShxLHQsdGhpcy5QdihzLnEoYSx0KSkpCnJldHVybiBxfX0KUC5qZy5wcm90b3R5cGU9ewok
+MjpmdW5jdGlvbihhLGIpe3RoaXMuYS5hW2FdPXRoaXMuYi5QdihiKX0sCiRTOjR9ClAuVGEucHJvdG90
+eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYlthXT10aGlzLmIuUHYoYil9LAokUzo0fQpQLkJm
+LnByb3RvdHlwZT17CmltOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5iOC5hKGIpCmZvcih0PU9i
+amVjdC5rZXlzKGEpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9dFtyXQpiLiQyKHEsYVtxXSl9fX0K
+UC5Bcy5wcm90b3R5cGU9ewpUOmZ1bmN0aW9uKGEpe3ZhciB0CkguYyhhKQp0PSQuaEcoKS5iCmlmKHR5
+cGVvZiBhIT0ic3RyaW5nIilILnZoKEguSShhKSkKaWYodC50ZXN0KGEpKXJldHVybiBhCnRocm93IEgu
+YihQLkwzKGEsInZhbHVlIiwiTm90IGEgdmFsaWQgY2xhc3MgdG9rZW4iKSl9LApaOmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLncoKS5IKDAsIiAiKX0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLncoKQpy
+ZXR1cm4gUC5yaih0LHQucixILkxoKHQpLmMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudygp
+LmF9LAp0ZzpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gdGhpcy53KCkudGcoMCxiKX0sCmk6
+ZnVuY3Rpb24oYSxiKXt0aGlzLlQoYikKcmV0dXJuIEguRTkodGhpcy5PUyhuZXcgUC5HRShiKSkpfSwK
+UjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKdGhpcy5UKGIpCnQ9dGhpcy53KCkKcz10LlIoMCxiKQp0aGlz
+LlgodCkKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuT1MobmV3IFAuTjcodGhpcyx1Llgu
+YShiKSkpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1bmN0aW9uKGEp
+e3ZhciB0LHMKdS5iVS5hKGEpCnQ9dGhpcy53KCkKcz1hLiQxKHQpCnRoaXMuWCh0KQpyZXR1cm4gc319
+ClAuR0UucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuQy5hKGEpLmkoMCx0aGlzLmEp
+fSwKJFM6MzF9ClAuTjcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5iLHM9SC50
+Nih0KQpyZXR1cm4gdS5DLmEoYSkuRlYoMCxuZXcgSC5sSih0LHMuQygicVUoMSkiKS5hKHRoaXMuYS5n
+dU0oKSkscy5DKCJsSjwxLHFVPiIpKSl9LAokUzoxNn0KUC51US5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXt1LkMuYShhKQppZihhLmE+MCl7YS5iPWEuYz1hLmQ9YS5lPWEuZj1udWxsCmEuYT0wCmEuUygp
+fXJldHVybiBudWxsfSwKJFM6MTZ9ClAuaEYucHJvdG90eXBlPXskaWhGOjF9ClAuUEMucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5aLmEoYSkKdD1mdW5jdGlvbihiLGMsZCl7cmV0dXJuIGZ1
+bmN0aW9uKCl7cmV0dXJuIGIoYyxkLHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3Vt
+ZW50cykpfX0oUC5SNCxhLCExKQpQLkRtKHQsJC53USgpLGEpCnJldHVybiB0fSwKJFM6MX0KUC5tdC5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRTOjF9ClAuTnou
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6NDJ9ClAuUVMu
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlR6KGEsdS5hbSl9LAokUzozNH0K
+UC5ucC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9LAokUzozNX0K
+UC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciJiZ0eXBl
+b2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlzIG5vdCBhIFN0cmluZyBvciBu
+dW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBi
+IT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBu
+b3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24oYSxiKXtp
+ZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09Yi5hfSwK
+WjpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0PVN0cmluZyh0aGlzLmEpCnJldHVybiB0fWNhdGNoKHMp
+e0guUnUocykKdD10aGlzLnhiKDApCnJldHVybiB0fX0sClY3OmZ1bmN0aW9uKGEsYil7dmFyIHQscz10
+aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxzZXt0PUgudDYoYikKdD1QLkNIKG5ldyBILmxKKGIsdC5D
+KCJAKDEpIikuYShQLmlHKCkpLHQuQygibEo8MSxAPiIpKSwhMCx1LnopfXJldHVybiBQLkw3KHNbYV0u
+YXBwbHkocyx0KSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlwZT17fQpQ
+LlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hPDB8fGE+PXQuZ0EodCkK
+aWYocyl0aHJvdyBILmIoUC5URShhLDAsdC5nQSh0KSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rpb24oYSxi
+KXtpZih0eXBlb2YgYj09Im51bWJlciImJmI9PT1DLmpuLnl1KGIpKXRoaXMuY1AoSC5XWShiKSkKcmV0
+dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdGhp
+cy4kdGkuYy5hKGMpCnQ9Qy5qbi55dShiKQppZihiPT09dCl0aGlzLmNQKGIpCnRoaXMuZTQoMCxiLGMp
+fSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmxlbmd0aAppZih0eXBlb2YgdD09PSJudW1iZXIi
+JiZ0Pj4+MD09PXQpcmV0dXJuIHQKdGhyb3cgSC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0aCIpKX0s
+CiRpYlE6MSwKJGljWDoxLAokaXpNOjF9ClAuY28ucHJvdG90eXBlPXt9ClAubmQucHJvdG90eXBlPXsk
+aW5kOjF9ClAuS2UucHJvdG90eXBlPXsKdzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmdl
+dEF0dHJpYnV0ZSgiY2xhc3MiKSxvPVAuTHModS5OKQppZihwPT1udWxsKXJldHVybiBvCmZvcih0PXAu
+c3BsaXQoIiAiKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAodFtyXSkKaWYocS5sZW5ndGgh
+PT0wKW8uaSgwLHEpfXJldHVybiBvfSwKWDpmdW5jdGlvbihhKXt0aGlzLmEuc2V0QXR0cmlidXRlKCJj
+bGFzcyIsYS5IKDAsIiAiKSl9fQpQLmQ1LnByb3RvdHlwZT17CmdQOmZ1bmN0aW9uKGEpe3JldHVybiBu
+ZXcgUC5LZShhKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnI2OmZ1bmN0aW9uKGEs
+YixjLGQpe3ZhciB0LHMscixxLHAsbwppZihkPT1udWxsKXt0PUguVk0oW10sdS5pKQpkPW5ldyBXLnZE
+KHQpCkMuTm0uaSh0LFcuVHcobnVsbCkpCkMuTm0uaSh0LFcuQmwoKSkKQy5ObS5pKHQsbmV3IFcuT3co
+KSl9Yz1uZXcgVy5LbyhkKQpzPSc8c3ZnIHZlcnNpb249IjEuMSI+JytILmQoYikrIjwvc3ZnPiIKdD1k
+b2N1bWVudApyPXQuYm9keQpxPShyJiZDLlJZKS5BSChyLHMsYykKcD10LmNyZWF0ZURvY3VtZW50RnJh
+Z21lbnQoKQpxLnRvU3RyaW5nCnQ9bmV3IFcuZTcocSkKbz10LmdyOCh0KQpmb3IoO3Q9by5maXJzdENo
+aWxkLHQhPW51bGw7KXAuYXBwZW5kQ2hpbGQodCkKcmV0dXJuIHB9LApuejpmdW5jdGlvbihhLGIsYyxk
+LGUpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgaW52b2tlIGluc2VydEFkamFjZW50SHRtbCBvbiBTVkcu
+IikpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdS5RKX0sCiRp
+ZDU6MX0KUC5uNi5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxLCRpZXE6MX0KTS5INy5wcm90
+b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpVLkxMLnByb3RvdHlwZT17Ckx0OmZ1
+bmN0aW9uKCl7cmV0dXJuIFAuRUYoWyJub2RlSWQiLHRoaXMuYiwia2luZCIsdGhpcy5hLmFdLHUuTix1
+LkspfX0KVS5NRC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5ncC5hKGEpLmE9PT10
+aGlzLmEucSgwLCJraW5kIil9LAokUzozNn0KVS5kMi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3Zh
+ciB0LHMscixxLHA9dGhpcyxvPXUuTixuPXUuSyxtPVAuRmwobyxuKSxsPXAuYQppZihsIT1udWxsKXt0
+PUguVk0oW10sdS5KKQpmb3Iocz1sLmxlbmd0aCxyPTA7cjxsLmxlbmd0aDtsLmxlbmd0aD09PXN8fCgw
+LEgubGspKGwpLCsrcil7cT1sW3JdCkMuTm0uaSh0LFAuRUYoWyJkZXNjcmlwdGlvbiIscS5hLCJocmVm
+IixxLmJdLG8sbikpfW0uWSgwLCJlZGl0cyIsdCl9bS5ZKDAsImV4cGxhbmF0aW9uIixwLmIpCm0uWSgw
+LCJsaW5lIixwLmMpCm0uWSgwLCJkaXNwbGF5UGF0aCIscC5kKQptLlkoMCwidXJpUGF0aCIscC5lKQpv
+PXAuZgppZihvIT1udWxsKXtuPUguVk0oW10sdS5KKQpmb3IobD1vLmxlbmd0aCxyPTA7cjxvLmxlbmd0
+aDtvLmxlbmd0aD09PWx8fCgwLEgubGspKG8pLCsrcilDLk5tLmkobixvW3JdLkx0KCkpCm0uWSgwLCJ0
+cmFjZXMiLG4pfXJldHVybiBtfX0KVS5TZS5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQ
+LkVGKFsiZGVzY3JpcHRpb24iLHRoaXMuYSwiaHJlZiIsdGhpcy5iXSx1Lk4sdS5LKX19ClUuTWwucHJv
+dG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC5FRihbImhyZWYiLHRoaXMuYSwibGluZSIsdGhp
+cy5iLCJwYXRoIix0aGlzLmNdLHUuTix1LkspfX0KVS55RC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigp
+e3ZhciB0LHMscixxPUguVk0oW10sdS5KKQpmb3IodD10aGlzLmIscz10Lmxlbmd0aCxyPTA7cjx0Lmxl
+bmd0aDt0Lmxlbmd0aD09PXN8fCgwLEgubGspKHQpLCsrcilDLk5tLmkocSx0W3JdLkx0KCkpCnJldHVy
+biBQLkVGKFsiZGVzY3JpcHRpb24iLHRoaXMuYSwiZW50cmllcyIscV0sdS5OLHUuSyl9fQpVLndiLnBy
+b3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMscT1QLkZsKHUuTix1LkspCnEuWSgw
+LCJkZXNjcmlwdGlvbiIsci5hKQp0PXIuYgppZih0IT1udWxsKXEuWSgwLCJmdW5jdGlvbiIsdCkKdD1y
+LmMKaWYodCE9bnVsbClxLlkoMCwibGluayIsdC5MdCgpKQp0PXIuZAppZih0Lmxlbmd0aCE9PTApe3M9
+SC50Nih0KQpxLlkoMCwiaGludEFjdGlvbnMiLG5ldyBILmxKKHQscy5DKCJaMDxxVSxNaD4oMSkiKS5h
+KG5ldyBVLmIwKCkpLHMuQygibEo8MSxaMDxxVSxNaD4+IikpLmJyKDApKX1yZXR1cm4gcX19ClUuYU4u
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFUubnoodS5TLmEoYSkpfSwKJFM6Mzd9ClUu
+YjAucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuRS5hKGEpLkx0KCl9LAokUzozOH0K
+Qi5qOC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsibGluZSIsdGhpcy5hLCJl
+eHBsYW5hdGlvbiIsdGhpcy5iLCJvZmZzZXQiLHRoaXMuY10sdS5OLHUuSyl9fQpCLnFwLnByb3RvdHlw
+ZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlzLGw9dS5OLGs9UC5GbChsLHUu
+ZDMpCmZvcih0PW0uZCx0PXQuZ1B1KHQpLHQ9dC5na3oodCkscz11Lksscj11Lko7dC5GKCk7KXtxPXQu
+Z2woKQpwPXEuYQpvPUguVk0oW10scikKZm9yKHE9Si5JVChxLmIpO3EuRigpOyl7bj1xLmdsKCkKQy5O
+bS5pKG8sUC5FRihbImxpbmUiLG4uYSwiZXhwbGFuYXRpb24iLG4uYiwib2Zmc2V0IixuLmNdLGwscykp
+fWsuWSgwLHAsbyl9cmV0dXJuIFAuRUYoWyJyZWdpb25zIixtLmEsIm5hdmlnYXRpb25Db250ZW50Iixt
+LmIsInNvdXJjZUNvZGUiLG0uYywiZWRpdHMiLGtdLGwscyl9fQpULm1RLnByb3RvdHlwZT17fQpMLmUu
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4KdS5CLmEoYSkKdD13aW5k
+b3cubG9jYXRpb24ucGF0aG5hbWUKcz1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpyPUwuYUsod2lu
+ZG93LmxvY2F0aW9uLmhyZWYpCkwuR2UoKQppZih0IT09Ii8iJiZ0IT09Si5UMChkb2N1bWVudC5xdWVy
+eVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSlMLkc3KHQscyxyLCEwLG5ldyBMLlZXKHQscyxy
+KSkKcT1kb2N1bWVudApwPUoucUYocS5xdWVyeVNlbGVjdG9yKCIuYXBwbHktbWlncmF0aW9uIikpCm89
+cC4kdGkKbj1vLkMoIn4oMSkiKS5hKG5ldyBMLm9aKCkpCnUuTS5hKG51bGwpClcuSkUocC5hLHAuYixu
+LCExLG8uYykKbz1KLnFGKHEucXVlcnlTZWxlY3RvcigiLnJlcnVuLW1pZ3JhdGlvbiIpKQpuPW8uJHRp
+ClcuSkUoby5hLG8uYixuLkMoIn4oMSkiKS5hKG5ldyBMLnk4KCkpLCExLG4uYykKbj1KLnFGKHEucXVl
+cnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm89bi4kdGkKVy5KRShuLmEsbi5iLG8uQygifigx
+KSIpLmEobmV3IEwuSGkoKSksITEsby5jKQpxPUoucUYocS5xdWVyeVNlbGVjdG9yKCIucG9wdXAtcGFu
+ZSAuY2xvc2UiKSkKbz1xLiR0aQpXLkpFKHEuYSxxLmIsby5DKCJ+KDEpIikuYShuZXcgTC5CVCgpKSwh
+MSxvLmMpfSwKJFM6MTd9CkwuVlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSx0
+aGlzLmIsdGhpcy5jKX0sCiRTOjB9Ckwub1oucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQs
+cyxyLHEKdS5WLmEoYSkKaWYoSC5vVCh3aW5kb3cuY29uZmlybSgiVGhpcyB3aWxsIGFwcGx5IHRoZSBj
+aGFuZ2VzIHlvdSd2ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVjdG9yeS4gSXQgaXMgcmVj
+b21tZW5kZWQgeW91IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZvcmUgZG9pbmcgdGhpcy4i
+KSkpe3Q9TC50eSgiL2FwcGx5LW1pZ3JhdGlvbiIsbnVsbCkuVzcobmV3IEwuanIoKSx1LlApCnM9bmV3
+IEwucWwoKQp1LmJmLmEobnVsbCkKcj10LiR0aQpxPSQuWDMKaWYocSE9PUMuTlUpcz1QLlZIKHMscSkK
+dC54ZihuZXcgUC5GZShuZXcgUC52cyhxLHIpLDIsbnVsbCxzLHIuQygiQDwxPiIpLktxKHIuYykuQygi
+RmU8MSwyPiIpKSl9fSwKJFM6M30KTC5qci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1
+LlMuYShhKQp0PWRvY3VtZW50LmJvZHkKdC5jbGFzc0xpc3QucmVtb3ZlKCJwcm9wb3NlZCIpCnQuY2xh
+c3NMaXN0LmFkZCgiYXBwbGllZCIpfSwKJFM6NDF9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
+YSxiKXtMLkMyKCJDb3VsZCBub3QgYXBwbHkgbWlncmF0aW9uIixhLGIpfSwKJEM6IiQyIiwKJFI6MiwK
+JFM6NH0KTC55OC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54bih1LlYuYShh
+KSl9LAp4bjpmdW5jdGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LlApLHI9MSxxLHA9W10sbyxuLG0sbAp2
+YXIgJGFzeW5jJCQxPVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGlsZSh0cnVl
+KXN3aXRjaCh0KXtjYXNlIDA6cj0zCmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgicmVydW5uaW5n
+IikKdD02CnJldHVybiBQLmpRKEwudHkoIi9yZXJ1bi1taWdyYXRpb24iLG51bGwpLCRhc3luYyQkMSkK
+Y2FzZSA2OndpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKQpwLnB1c2goNSkKdD00CmJyZWFrCmNhc2UgMzpy
+PTIKbD1xCm89SC5SdShsKQpuPUgudHMobCkKTC5DMigiRmFpbGVkIHRvIHJlcnVuIG1pZ3JhdGlvbiIs
+byxuKQpwLnB1c2goNSkKdD00CmJyZWFrCmNhc2UgMjpwPVsxXQpjYXNlIDQ6cj0xCmRvY3VtZW50LmJv
+ZHkuY2xhc3NMaXN0LnJlbW92ZSgicmVydW5uaW5nIikKdD1wLnBvcCgpCmJyZWFrCmNhc2UgNTpyZXR1
+cm4gUC55QyhudWxsLHMpCmNhc2UgMTpyZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRhc3lu
+YyQkMSxzKX0sCiRTOjExfQpMLkhpLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5h
+KGEpCnQ9dS5OCkMub2wuUG8od2luZG93LFAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFu
+Zy9zZGsvaXNzdWVzL25ldyIsUC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVwb3J0ZWQgaXNzdWUgd2l0
+aCBOTkJEIG1pZ3JhdGlvbiB0b29sIiwibGFiZWxzIiwiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJk
+LW1pZ3JhdGlvbix0eXBlLWJ1ZyIsImJvZHkiLCIjIyMjIFN0ZXBzIHRvIHJlcHJvZHVjZVxuXG4jIyMj
+IFdoYXQgZGlkIHlvdSBleHBlY3QgdG8gaGFwcGVuP1xuXG4jIyMjIFdoYXQgYWN0dWFsbHkgaGFwcGVu
+ZWQ/XG5cbl9TY3JlZW5zaG90cyBhcmUgYXBwcmVjaWF0ZWRfXG5cbioqRGFydCBTREsgdmVyc2lvbioq
+OiAiK0guZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkr
+IlxuXG5UaGFua3MgZm9yIGZpbGluZyFcbiJdLHQsdCkpLlooMCksInJlcG9ydC1wcm9ibGVtIil9LAok
+UzozfQpMLkJULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5hKGEpCnQ9ZG9jdW1l
+bnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKS5zdHlsZQp0LmRpc3BsYXk9Im5vbmUiCnJldHVy
+biJub25lIn0sCiRTOjQzfQpMLkwucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUu
+Qi5hKGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24uaHJl
+ZikKcj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZih0Lmxlbmd0aD4xKUwuRzcodCxzLHIsITEs
+bnVsbCkKZWxzZXtMLkJFKHQsbmV3IEIucXAoIiIsIiIsIiIsQy5DTSksITApCkwuQlgoIiZuYnNwOyIs
+bnVsbCl9fSwKJFM6MTd9CkwuV3gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9
+ImNvbGxhcHNlZCIKdS5WLmEoYSkKdD10aGlzLmEKcz1KLlJFKHQpCnI9dGhpcy5iCmlmKCFzLmdQKHQp
+LnRnKDAscSkpe3MuZ1AodCkuaSgwLHEpCkouZFIocikuaSgwLHEpfWVsc2V7cy5nUCh0KS5SKDAscSkK
+Si5kUihyKS5SKDAscSl9fSwKJFM6M30KTC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
+dD1KLnFGKHUuaC5hKGEpKSxzPXQuJHRpLHI9cy5DKCJ+KDEpIikuYShuZXcgTC5kTih0aGlzLmEpKQp1
+Lk0uYShudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmMpfSwKJFM6Nn0KTC5kTi5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXt2YXIgdAp1LlYuYShhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInRhYmxl
+W2RhdGEtcGF0aF0iKQp0LnRvU3RyaW5nCkwudDIoYSx0aGlzLmEsdC5nZXRBdHRyaWJ1dGUoImRhdGEt
+IituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygicGF0aCIpKSl9LAokUzozfQpMLkhvLnByb3RvdHlwZT17
+CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LmguYShhKQp0PUoucUYoYSkKcz10LiR0aQpyPXMuQygi
+figxKSIpLmEobmV3IEwueHooYSx0aGlzLmEpKQp1Lk0uYShudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxz
+LmMpfSwKJFM6Nn0KTC54ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPW51bGwKdS5W
+LmEoYSkKdD10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBX
+LlN5KG5ldyBXLmk3KHQpKS5PKCJvZmZzZXQiKSkscyxzKSxQLlFBKHQuZ2V0QXR0cmlidXRlKCJkYXRh
+LSIrbmV3IFcuU3kobmV3IFcuaTcodCkpLk8oImxpbmUiKSkscyxzKSl9LAokUzozfQpMLklDLnByb3Rv
+dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PUoucUYodS5oLmEoYSkpLHM9dC4kdGkKcy5DKCJ+KDEp
+IikuYShMLmlTKCkpCnUuTS5hKG51bGwpClcuSkUodC5hLHQuYixMLmlTKCksITEscy5jKX0sCiRTOjZ9
+CkwuZkMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5GLmEoYSkKdGhpcy5hLmFNKDAsdGhpcy5i
+KX0sCiRTOjQ1fQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEuYSx0aGlz
+LmIsdGhpcy5jKX0sCiRTOjB9CkwuQloucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMu
+YS5hLG51bGwsbnVsbCl9LAokUzowfQpMLkdILnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3UuaC5h
+KGEpCiQuekIoKS50b1N0cmluZwp1Lm0uYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJoaWdobGlnaHRC
+bG9jayIsW2FdKX0sCiRTOjZ9CkwuRUUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp1
LlYuYShhKQp0PXRoaXMuYQpzPXRoaXMuYgpMLmFmKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSx0LHMs
-ITAsbmV3IEwuUUwodCxzKSkKTC5oWCh0aGlzLmMsdCxzKX0sCiRTOjR9CkwuUUwucHJvdG90eXBlPXsK
+ITAsbmV3IEwuUUwodCxzKSkKTC5oWCh0aGlzLmMsdCxzKX0sCiRTOjN9CkwuUUwucHJvdG90eXBlPXsK
JDA6ZnVuY3Rpb24oKXtMLkZyKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSx0aGlzLmEsdGhpcy5iKX0s
CiRTOjB9CkwuVlMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscz0ic2VsZWN0ZWQtZmls
ZSIKdS5oLmEoYSkKYS50b1N0cmluZwp0PUouUkUoYSkKaWYoYS5nZXRBdHRyaWJ1dGUoImRhdGEtIitu
ZXcgVy5TeShuZXcgVy5pNyhhKSkuTygibmFtZSIpKT09PXRoaXMuYS5hKXQuZ1AoYSkuaSgwLHMpCmVs
c2UgdC5nUChhKS5SKDAscyl9LAokUzo2fQpMLlRELnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBMLnQyKHUuVi5hKGEpLCEwLG51bGwpfSwKJFM6MTJ9CkwuQVMucHJvdG90eXBlPXsKJDE6ZnVu
+dHVybiBMLnQyKHUuVi5hKGEpLCEwLG51bGwpfSwKJFM6MTh9CkwuQVMucHJvdG90eXBlPXsKJDE6ZnVu
Y3Rpb24oYSl7cmV0dXJuIHRoaXMuUEwodS5WLmEoYSkpfSwKUEw6ZnVuY3Rpb24oYSl7dmFyIHQ9MCxz
PVAuRlgodS5QKSxyPTEscSxwPVtdLG89dGhpcyxuLG0sbCxrLGoKdmFyICRhc3luYyQkMT1QLmx6KGZ1
bmN0aW9uKGIsYyl7aWYoYj09PTEpe3E9Ywp0PXJ9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOnI9
@@ -3638,7 +3630,7 @@
ayhxLHQpCnE9cytILmQocVt0XSl9cSs9SC5kKEMuTm0uZ3JaKHIuZSkpCnJldHVybiBxLmNoYXJDb2Rl
QXQoMCk9PTA/cTpxfSwKc25KOmZ1bmN0aW9uKGEpe3RoaXMuZD11LmEuYShhKX0sCnNQaDpmdW5jdGlv
bihhKXt0aGlzLmU9dS5hLmEoYSl9fQpYLnFSLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLmEuYS5nbUkoKX0sCiRTOjQ4fQpYLmR2LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0
+biB0aGlzLmEuYS5nbUkoKX0sCiRTOjQ3fQpYLmR2LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0
dXJuIlBhdGhFeGNlcHRpb246ICIrdGhpcy5hfSwKJGlSejoxfQpPLnpMLnByb3RvdHlwZT17Clo6ZnVu
Y3Rpb24oYSl7cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90b3R5cGU9ewpVZDpmdW5jdGlv
bihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwK
@@ -3681,668 +3673,671 @@
YXJPZmZzKCl7dmFyIHQ9aHVua0hlbHBlcnMuX3N0YXRpY18xLHM9aHVua0hlbHBlcnMuX3N0YXRpY18w
LHI9aHVua0hlbHBlcnMuaW5zdGFsbEluc3RhbmNlVGVhck9mZixxPWh1bmtIZWxwZXJzLmluc3RhbGxT
dGF0aWNUZWFyT2ZmLHA9aHVua0hlbHBlcnMuX2luc3RhbmNlXzF1CnQoUCwiRVgiLCJaViIsOCkKdChQ
-LCJ5dCIsIm9BIiw4KQp0KFAsInFXIiwiQnoiLDgpCnMoUCwiVjkiLCJlTiIsMykKcihQLlBmLnByb3Rv
-dHlwZSwiZ1lKIiwwLDEsbnVsbCxbIiQyIiwiJDEiXSxbIncwIiwicG0iXSw0OSwwKQp0KFAsIkN5Iiwi
-TkMiLDIpCnQoUCwiUEgiLCJNdCIsNSkKcShXLCJwUyIsNCxudWxsLFsiJDQiXSxbInlXIl0sMTgsMCkK
-cShXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0sMTgsMCkKcChQLkFzLnByb3RvdHlwZSwiZ3VNIiwi
-VCIsNSkKdChQLCJpRyIsIndZIiwyKQp0KFAsIncwIiwiTDciLDMzKQp0KEwsImlTIiwiaTYiLDEyKX0p
-KCk7KGZ1bmN0aW9uIGluaGVyaXRhbmNlKCl7dmFyIHQ9aHVua0hlbHBlcnMubWl4aW4scz1odW5rSGVs
-cGVycy5pbmhlcml0LHI9aHVua0hlbHBlcnMuaW5oZXJpdE1hbnkKcyhQLk1oLG51bGwpCnIoUC5NaCxb
-SC5GSyxKLnZCLEoubTEsUC5uWSxQLmNYLEguYTcsUC5BbixILlNVLEguUmUsSC53dixQLlBuLEguV1Us
-SC5MSSxILlRwLEguZjksUC5YUyxILmJxLEguWE8sUC5ZayxILmRiLEguTjYsSC5WUixILkVLLEguUGIs
-SC50USxILlNkLEguSmMsSC5FVCxQLlczLFAuaWgsUC5GeSxQLkdWLFAuYjgsUC5QZixQLkZlLFAudnMs
-UC5PTSxQLnFoLFAuTU8sUC5rVCxQLnhJLFAuT0gsUC5tMCxQLlh2LFAuYm4sUC5sbSxQLmxELFAuS1As
-UC5NYSxQLlRDLFAuVWssUC5TaCxQLlJ3LFAuYnosUC5hMixQLmlQLFAubGYsUC5rNSxQLktZLFAuQ0Qs
-UC5hRSxQLkVILFAuek0sUC5aMCxQLk4zLFAuYzgsUC5PZCxQLmliLFAuR3osUC5aZCxQLnFVLFAuUm4s
-UC5HRCxQLkRuLFAuUEUsUC5VZixXLmlkLFcuRmssVy5KUSxXLkdtLFcudkQsVy5tNixXLk93LFcuVzks
-Vy5kVyxXLkZiLFcua0YsVy5tayxXLktvLFAuaUosUC5FNCxQLm42LE0uSDcsVS5MTCxVLmQyLFUuU2Us
-VS5NbCxVLnlELFUud2IsQi5qOCxCLnFwLFQubVEsTC5YQSxMLlpaLEwuTzksTS5sSSxPLnpMLFguV0Qs
-WC5kdl0pCnIoSi52QixbSi55RSxKLllFLEouTUYsSi5qZCxKLnFJLEouRHIsSC5wRixXLkQwLFcuQXos
-Vy5MZSxXLk5oLFcuSUIsVy5uNyxXLmVhLFcuYnIsVy5TZyxXLnU4LFcuSzcsVy5YVyxQLmhGXSkKcihK
-Lk1GLFtKLmlDLEoua2QsSi5jNV0pCnMoSi5QbyxKLmpkKQpyKEoucUksW0oudXIsSi5WQV0pCnMoUC5M
-VSxQLm5ZKQpyKFAuTFUsW0gudzIsVy53eixXLmU3XSkKcyhILnFqLEgudzIpCnIoUC5jWCxbSC5iUSxI
-LmkxLEguVTUsSC5YUixQLm1XLEguTkZdKQpyKEguYlEsW0guYUwsSC5pNSxQLnh1XSkKcihILmFMLFtI
-Lm5ILEgubEosUC5pOF0pCnMoSC54eSxILmkxKQpyKFAuQW4sW0guTUgsSC52R10pCnMoUC5SVSxQLlBu
-KQpzKFAuR2osUC5SVSkKcyhILlBELFAuR2opCnMoSC5MUCxILldVKQpyKEguVHAsW0guQ2osSC5BbSxI
-LmxjLEgucixILmRDLEgud04sUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdzLFAu
-ZGEsUC5vUSxQLnBWLFAuVTcsUC52cixQLnJILFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAu
-QjUsUC51TyxQLnBLLFAuaGosUC5WcCxQLk9SLFAucmEsUC55USxQLnRpLFAuV0YsUC5uMSxQLmNTLFAu
-VkMsUC5KVCxQLmUxLFAuTlksUC5SWixQLk1FLFAueTUsUC5xMyxQLnlJLFAuYzYsUC5xZCxXLkN2LFcu
-YlUsVy5oSCxXLktTLFcuQTMsVy52TixXLlV2LFcuRWcsVy5FbyxXLldrLFcuSUEsVy5mbSxQLmpnLFAu
-VGEsUC5HRSxQLk43LFAudVEsUC5QQyxQLm10LFAuTnosUC5RUyxQLm5wLFUuTUQsVS5hTixVLmIwLEwu
-ZSxMLlZXLEwub1osTC5qcixMLnFsLEwueTgsTC5IaSxMLkJULEwuTCxMLld4LEwuQU8sTC5kTixMLkhv
-LEwueHosTC5JQyxMLkwxLEwublQsTC5CWixMLkdILEwuRFQsTC5lSCxMLnl1LEwuekQsTC5UVyxMLnhy
-LEwuRUUsTC5RTCxMLlZTLEwuVEQsTC5BUyxNLk1pLE0ucTcsTS5ObyxYLnFSXSkKcihQLlhTLFtILlcw
-LEguYXosSC52VixILkVxLFAuQzYsSC51OSxQLlVkLFAuTEssUC5BVCxQLm1wLFAudWIsUC5kcyxQLmxq
-LFAuVVYsUC50N10pCnIoSC5sYyxbSC56eCxILmp5XSkKcyhILmtZLFAuQzYpCnMoUC5pbCxQLllrKQpy
-KFAuaWwsW0guTjUsUC51dyxXLmNmLFcuU3ldKQpyKFAubVcsW0guS1csUC5xNF0pCnMoSC5MWixILnBG
-KQpyKEguTFosW0guUkcsSC5XQl0pCnMoSC5WUCxILlJHKQpzKEguRGcsSC5WUCkKcyhILlpHLEguV0Ip
-CnMoSC5QZyxILlpHKQpyKEguUGcsW0gueGosSC5kRSxILlpBLEgud2YsSC5QcSxILmVFLEguVjZdKQpz
-KEgueCxILnU5KQpzKFAuWmYsUC5QZikKcyhQLkppLFAubTApCnMoUC5iNixQLlh2KQpzKFAuVmosUC5U
-QykKcihQLlVrLFtQLkNWLFAuWmksUC5ieV0pCnMoUC53SSxQLmtUKQpyKFAud0ksW1AuVTgsUC5vaixQ
-Lk14LFAuRTMsUC5HWV0pCnMoUC5LOCxQLlVkKQpzKFAudHUsUC5TaCkKcyhQLnU1LFAuWmkpCnIoUC5s
-ZixbUC5DUCxQLklmXSkKcihQLkFULFtQLmJKLFAuZVldKQpzKFAucWUsUC5EbikKcihXLkQwLFtXLnVI
-LFcud2EsVy5LNSxXLkNtXSkKcihXLnVILFtXLmN2LFcubngsVy5RRixXLkNRXSkKcihXLmN2LFtXLnFF
-LFAuZDVdKQpyKFcucUUsW1cuR2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixXLkl2
-LFcuV1AsVy55WV0pCnMoVy5vSixXLkxlKQpzKFcuVDUsVy5BeikKcyhXLlZiLFcuUUYpCnMoVy5mSixX
-LndhKQpyKFcuZWEsW1cudzYsVy5ld10pCnMoVy5PSyxXLnc2KQpzKFcuckIsVy5LNykKcyhXLkJILFcu
-ckIpCnMoVy53NCxXLklCKQpzKFcub2EsVy5YVykKcyhXLnJoLFcub2EpCnMoVy5pNyxXLmNmKQpzKFAu
-QXMsUC5WaikKcihQLkFzLFtXLkk0LFAuS2VdKQpzKFcuUk8sUC5xaCkKcyhXLmV1LFcuUk8pCnMoVy54
-QyxQLk1PKQpzKFcuY3QsVy5tNikKcyhQLkJmLFAuaUopCnIoUC5FNCxbUC5yNyxQLmNvXSkKcyhQLlR6
-LFAuY28pCnMoUC5uZCxQLmQ1KQpzKEIuZnYsTy56TCkKcihCLmZ2LFtFLk9GLEYucnUsTC5JVl0pCnQo
-SC53MixILlJlKQp0KEguUkcsUC5sRCkKdChILlZQLEguU1UpCnQoSC5XQixQLmxEKQp0KEguWkcsSC5T
-VSkKdChQLm5ZLFAubEQpCnQoUC5UQyxQLk1hKQp0KFAuUlUsUC5LUCkKdChXLkxlLFcuaWQpCnQoVy5L
-NyxQLmxEKQp0KFcuckIsVy5HbSkKdChXLlhXLFAubEQpCnQoVy5vYSxXLkdtKQp0KFAuY28sUC5sRCl9
-KSgpCnZhciB2PXt0eXBlVW5pdmVyc2U6e2VDOm5ldyBNYXAoKSx0Ujp7fSxlVDp7fSx0UFY6e30sc0VB
-OltdfSxtYW5nbGVkR2xvYmFsTmFtZXM6e0lmOiJpbnQiLENQOiJkb3VibGUiLGxmOiJudW0iLHFVOiJT
-dHJpbmciLGEyOiJib29sIixjODoiTnVsbCIsek06Ikxpc3QifSxtYW5nbGVkTmFtZXM6e30sZ2V0VHlw
-ZUZyb21OYW1lOmdldEdsb2JhbEZyb21OYW1lLG1ldGFkYXRhOltdLHR5cGVzOlsiYzgoKSIsImM4KEAs
-QCkiLCJAKEApIiwifigpIiwiYzgoT0spIiwicVUocVUpIiwiYzgoY3YpIiwiYTIocVUpIiwifih+KCkp
-IiwiYzgocVUscVUpIiwiYzgoZkopIiwiYjg8Yzg+KE9LKSIsIn4oT0spIiwiYzgoQCkiLCJjOChxVSxA
-KSIsImM4KHFVKSIsImM4KGV3KSIsImEyKGtGKSIsImEyKGN2LHFVLHFVLEpRKSIsImM4KGVhKSIsIn4o
-eHU8cVU+KSIsImEyKHVIKSIsIn4ocVUscVUpIiwibjYoSWYpIiwibjYoQCxAKSIsImM4KEBbR3pdKSIs
-IkAoQCxxVSkiLCJaMDxxVSxxVT4oWjA8cVUscVU+LHFVKSIsIkAoZWEpIiwidnM8QD4oQCkiLCJAKHFV
-KSIsIn4odUgsdUgpIiwiYTIoeHU8cVU+KSIsIk1oKEApIiwicjcoQCkiLCJUejxAPihAKSIsIkU0KEAp
-IiwifihxVVtAXSkiLCJMTChAKSIsIlowPHFVLE1oPihMTCkiLCJJZihJZixJZikiLCJjOChHRCxAKSIs
-ImM4KFowPHFVLE1oPikiLCJ+KHFVLElmKSIsInFVKE9LKSIsImM4KEAsR3opIiwiYzgoSWYsQCkiLCJj
-OCh+KCkpIiwicVUoSWYpIiwifihNaFtHel0pIiwiYTIoSDcpIiwifihAKSJdLGludGVyY2VwdG9yc0J5
-VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0aTp0eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZ0
-eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJvbCgiJHRpIik6IiR0aSJ9CkgueGIodi50eXBlVW5p
-dmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYiLCJyeCI6ImVhIiwi
-ZTUiOiJlYSIsIlkwIjoiZDUiLCJ0cCI6ImQ1IiwiRzgiOiJldyIsIk1yIjoicUUiLCJlTCI6InFFIiwi
-STAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwieWMiOiJPSyIsInk0IjoidzYiLCJhUCI6IkNtIiwi
-eGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJwRiIsInlFIjp7ImEyIjpbXX0sIllFIjp7
-ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJdLCJiUSI6WyIxIl0s
-ImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEi
-XX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwibGYiOltdfSwidXIiOnsiSWYiOltdLCJD
-UCI6W10sImxmIjpbXX0sIlZBIjp7IkNQIjpbXSwibGYiOltdfSwiRHIiOnsicVUiOltdLCJ2WCI6W119
-LCJxaiI6eyJSZSI6WyJJZiJdLCJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJdLCJjWCI6
-WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiYlEiOnsiY1giOlsiMSJdfSwiYUwiOnsiYlEi
-OlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJh
-TC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpbIjIiXSwiY1gu
-RSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIy
-In0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0s
-ImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJ2RyI6eyJB
-biI6WyIxIl19LCJ3MiI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0s
-ImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJVIjpbIjEiLCIy
-Il0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJXVSI6eyJaMCI6
-WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlhSIjp7ImNYIjpb
-IjEiXSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwiYXoiOnsiWFMiOltd
-fSwidlYiOnsiWFMiOltdfSwiWE8iOnsiR3oiOltdfSwiVHAiOnsiRUgiOltdfSwibGMiOnsiRUgiOltd
-fSwiengiOnsiRUgiOltdfSwiankiOnsiRUgiOltdfSwiRXEiOnsiWFMiOltdfSwia1kiOnsiWFMiOltd
-fSwiTjUiOnsiRm8iOlsiMSIsIjIiXSwiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXSwiWWsuSyI6
-IjEiLCJZay5WIjoiMiJ9LCJpNSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXSwiY1guRSI6IjEifSwiTjYi
-OnsiQW4iOlsiMSJdfSwiVlIiOnsid0wiOltdLCJ2WCI6W119LCJFSyI6eyJpYiI6W10sIk9kIjpbXX0s
-IktXIjp7ImNYIjpbImliIl0sImNYLkUiOiJpYiJ9LCJQYiI6eyJBbiI6WyJpYiJdfSwidFEiOnsiT2Qi
-OltdfSwiTkYiOnsiY1giOlsiT2QiXSwiY1guRSI6Ik9kIn0sIlNkIjp7IkFuIjpbIk9kIl19LCJwRiI6
-eyJlcSI6W119LCJMWiI6eyJYaiI6WyJAIl0sInBGIjpbXSwiZXEiOltdfSwiRGciOnsibEQiOlsiQ1Ai
-XSwiWGoiOlsiQCJdLCJ6TSI6WyJDUCJdLCJwRiI6W10sImJRIjpbIkNQIl0sIlNVIjpbIkNQIl0sImVx
-IjpbXSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0s
-IlhqIjpbIkAiXSwicEYiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJlcSI6W10sImNYIjpbIklm
-Il19LCJ4aiI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJAIl0sInBGIjpbXSwiYlEiOlsi
-SWYiXSwiU1UiOlsiSWYiXSwiZXEiOltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZEUiOnsibEQi
-OlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiQCJdLCJwRiI6W10sImJRIjpbIklmIl0sIlNVIjpbIklm
-Il0sImVxIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklmIl0sInpNIjpb
-IklmIl0sIlhqIjpbIkAiXSwicEYiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJlcSI6W10sImNY
-IjpbIklmIl0sImxELkUiOiJJZiJ9LCJ3ZiI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJA
-Il0sInBGIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiZXEiOltdLCJjWCI6WyJJZiJdLCJsRC5F
-IjoiSWYifSwiUHEiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiQCJdLCJwRiI6W10sImJR
-IjpbIklmIl0sIlNVIjpbIklmIl0sImVxIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sImVFIjp7
-ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwicEYiOltdLCJiUSI6WyJJZiJdLCJTVSI6
-WyJJZiJdLCJlcSI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJWNiI6eyJuNiI6W10sImxEIjpb
-IklmIl0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwicEYiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJd
-LCJlcSI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJ1OSI6eyJYUyI6W119LCJ4Ijp7IlhTIjpb
-XX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiWmYiOnsiUGYi
-OlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiT0giOnsiWFMiOltdfSwibTAiOnsiSkIiOltdfSwiSmki
-OnsiSkIiOltdfSwiYjYiOnsiWHYiOlsiMSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJd
-fSwibG0iOnsiQW4iOlsiMSJdfSwibVciOnsiY1giOlsiMSJdfSwiTFUiOnsibEQiOlsiMSJdLCJ6TSI6
-WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWwiOnsiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIs
-IjIiXX0sIllrIjp7IlowIjpbIjEiLCIyIl19LCJQbiI6eyJaMCI6WyIxIiwiMiJdfSwiR2oiOnsiUlUi
-OlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlZq
-Ijp7Ik1hIjpbIjEiXSwieHUiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlh2Ijp7Inh1Ijpb
-IjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUi
-LCJAIl0sIllrLksiOiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0s
-ImNYIjpbInFVIl0sImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJx
-VSJdLCJVay5TIjoiek08SWY+In0sIlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6
-WyJxVSIsInpNPElmPiJdfSwiVWQiOnsiWFMiOltdfSwiSzgiOnsiWFMiOltdfSwiYnkiOnsiVWsiOlsi
-TWgiLCJxVSJdLCJVay5TIjoiTWgifSwib2oiOnsid0kiOlsiTWgiLCJxVSJdfSwiTXgiOnsid0kiOlsi
-cVUiLCJNaCJdfSwidTUiOnsiVWsiOlsicVUiLCJ6TTxJZj4iXSwiVWsuUyI6InFVIn0sIkUzIjp7IndJ
-IjpbInFVIiwiek08SWY+Il19LCJHWSI6eyJ3SSI6WyJ6TTxJZj4iLCJxVSJdfSwiQ1AiOnsibGYiOltd
-fSwiQzYiOnsiWFMiOltdfSwiTEsiOnsiWFMiOltdfSwiQVQiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltd
-fSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltd
-fSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltd
-fSwidDciOnsiWFMiOltdfSwiQ0QiOnsiUnoiOltdfSwiYUUiOnsiUnoiOltdfSwiSWYiOnsibGYiOltd
-fSwiek0iOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpYiI6eyJPZCI6W119LCJ4dSI6eyJiUSI6WyIx
-Il0sImNYIjpbIjEiXX0sIlpkIjp7Ikd6IjpbXX0sInFVIjp7InZYIjpbXX0sIlJuIjp7IkJMIjpbXX0s
-IkRuIjp7ImlEIjpbXX0sIlVmIjp7ImlEIjpbXX0sInFlIjp7ImlEIjpbXX0sInFFIjp7ImN2IjpbXSwi
-dUgiOltdLCJEMCI6W119LCJHaCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZlkiOnsiY3YiOltd
-LCJ1SCI6W10sIkQwIjpbXX0sIm5CIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJRUCI6eyJjdiI6
-W10sInVIIjpbXSwiRDAiOltdfSwibngiOnsidUgiOltdLCJEMCI6W119LCJRRiI6eyJ1SCI6W10sIkQw
-IjpbXX0sIklCIjp7InRuIjpbImxmIl19LCJ3eiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsi
-MSJdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sImN2Ijp7InVIIjpbXSwiRDAiOltdfSwiVDUiOnsiQXoi
-OltdfSwiaDQiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlZiIjp7InVIIjpbXSwiRDAiOltdfSwi
-ZkoiOnsiRDAiOltdfSwid2EiOnsiRDAiOltdfSwiT0siOnsiZWEiOltdfSwiZTciOnsibEQiOlsidUgi
-XSwiek0iOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIn0sInVIIjp7IkQw
-IjpbXX0sIkJIIjp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVIIl0s
-ImJRIjpbInVIIl0sImNYIjpbInVIIl0sIkdtLkUiOiJ1SCIsImxELkUiOiJ1SCJ9LCJTTiI6eyJjdiI6
-W10sInVIIjpbXSwiRDAiOltdfSwiZXciOnsiZWEiOltdfSwibHAiOnsiY3YiOltdLCJ1SCI6W10sIkQw
-IjpbXX0sIlRiIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJJdiI6eyJjdiI6W10sInVIIjpbXSwi
-RDAiOltdfSwiV1AiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sInlZIjp7ImN2IjpbXSwidUgiOltd
-LCJEMCI6W119LCJ3NiI6eyJlYSI6W119LCJLNSI6eyJ2NiI6W10sIkQwIjpbXX0sIkNtIjp7IkQwIjpb
-XX0sIkNRIjp7InVIIjpbXSwiRDAiOltdfSwidzQiOnsidG4iOlsibGYiXX0sInJoIjp7IkdtIjpbInVI
-Il0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVI
-Il0sIkdtLkUiOiJ1SCIsImxELkUiOiJ1SCJ9LCJjZiI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFV
-IiwicVUiXX0sImk3Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUi
-LCJZay5WIjoicVUifSwiU3kiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl0sIllrLksi
-OiJxVSIsIllrLlYiOiJxVSJ9LCJJNCI6eyJNYSI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJd
-LCJjWCI6WyJxVSJdfSwiUk8iOnsicWgiOlsiMSJdfSwiZXUiOnsiUk8iOlsiMSJdLCJxaCI6WyIxIl19
-LCJ4QyI6eyJNTyI6WyIxIl19LCJKUSI6eyJrRiI6W119LCJ2RCI6eyJrRiI6W119LCJtNiI6eyJrRiI6
-W119LCJjdCI6eyJrRiI6W119LCJPdyI6eyJrRiI6W119LCJXOSI6eyJBbiI6WyIxIl19LCJkVyI6eyJ2
-NiI6W10sIkQwIjpbXX0sIm1rIjp7InkwIjpbXX0sIktvIjp7Im9uIjpbXX0sIkFzIjp7Ik1hIjpbInFV
-Il0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl19LCJyNyI6eyJFNCI6W119LCJUeiI6
-eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJFNCI6W10sImNYIjpbIjEiXSwibEQuRSI6
-IjEifSwibmQiOnsiZDUiOltdLCJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiS2UiOnsiTWEiOlsicVUi
-XSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXX0sImQ1Ijp7ImN2IjpbXSwidUgiOltd
-LCJEMCI6W119LCJuNiI6eyJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJdLCJlcSI6W10sImNYIjpbIklmIl19
-LCJYQSI6eyJrRiI6W119LCJkdiI6eyJSeiI6W119LCJPRiI6eyJmdiI6W119LCJydSI6eyJmdiI6W119
-LCJJViI6eyJmdiI6W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYlEiOjEs
-IncyIjoxLCJNTyI6MSwia1QiOjIsIm1XIjoxLCJMVSI6MSwiaWwiOjIsIlZqIjoxLCJuWSI6MSwiVEMi
-OjEsImNvIjoxfScpKQp2YXIgdT0oZnVuY3Rpb24gcnRpaSgpe3ZhciB0PUguTjAKcmV0dXJue2JxOnQo
-IkdoIiksbjp0KCJPSCIpLGNSOnQoIm5CIiksZDp0KCJBeiIpLGk6dCgiUVAiKSxnRjp0KCJQRDxHRCxA
-PiIpLGd3OnQoImJRPEA+IiksaDp0KCJjdiIpLFc6dCgiWFMiKSxCOnQoImVhIiksdTp0KCJEMCIpLGc4
-OnQoIlJ6IiksYzg6dCgiVDUiKSxaOnQoIkVIIiksYVE6dCgiYjg8Yzg+IiksYzp0KCJiODxAPiIpLEY6
-dCgiTEwiKSxncDp0KCJINyIpLHI6dCgiZkoiKSxJOnQoIlNnIiksbzp0KCJ2USIpLGVoOnQoImNYPHVI
-PiIpLFg6dCgiY1g8cVU+IiksUjp0KCJjWDxAPiIpLGZBOnQoImpkPFNlPiIpLGdpOnQoImpkPGo4PiIp
-LEo6dCgiamQ8WjA8cVUsTWg+PiIpLGZoOnQoImpkPFpaPiIpLGs6dCgiamQ8a0Y+Iiksczp0KCJqZDxx
-VT4iKSxoaDp0KCJqZDx5RD4iKSxhSjp0KCJqZDx3Yj4iKSxtOnQoImpkPEA+IiksdDp0KCJqZDxJZj4i
-KSxlSDp0KCJ2bSIpLGc6dCgiYzUiKSxhVTp0KCJYajxAPiIpLGFtOnQoIlR6PEA+IiksZW86dCgiTjU8
-R0QsQD4iKSx2OnQoIkU0IiksZHo6dCgiaEYiKSxmNDp0KCJ6TTxqOD4iKSxkMzp0KCJ6TTxaMDxxVSxN
-aD4+IiksYTp0KCJ6TTxxVT4iKSxqOnQoInpNPEA+IiksTDp0KCJ6TTxJZj4iKSxhXzp0KCJ1OCIpLFM6
-dCgiWjA8cVUsTWg+IiksZjp0KCJaMDxxVSxxVT4iKSxiOnQoIlowPHFVLEA+IiksRzp0KCJaMDxALEA+
-IiksZHY6dCgibEo8cVUscVU+IiksZG86dCgibEo8cVUsQD4iKSxWOnQoIk9LIiksZEU6dCgicEYiKSxi
-bTp0KCJWNiIpLEE6dCgidUgiKSxlOnQoImtGIiksUDp0KCJjOCIpLEs6dCgiTWgiKSxwOnQoImV3Iiks
-Tzp0KCJ0bjxsZj4iKSxmdjp0KCJ3TCIpLGF2OnQoIkpjIiksZXc6dCgibmQiKSxDOnQoInh1PHFVPiIp
-LGw6dCgiR3oiKSxOOnQoInFVIiksZEc6dCgicVUocVUpIiksZzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFX
-OnQoInlZIiksdzp0KCJlcSIpLGdjOnQoIm42IiksYWs6dCgia2QiKSxkdzp0KCJHajxxVSxxVT4iKSxk
-RDp0KCJpRCIpLGNjOnQoIlU1PHFVPiIpLGc0OnQoIks1IiksY2k6dCgidjYiKSxnMjp0KCJDbSIpLEU6
-dCgiWmY8Zko+IiksaDk6dCgiQ1EiKSxhYzp0KCJlNyIpLFE6dCgiZXU8T0s+IiksVDp0KCJ3ejxjdj4i
-KSx4OnQoIkZlPEAsQD4iKSxZOnQoInZzPGZKPiIpLF86dCgidnM8QD4iKSxmSjp0KCJ2czxJZj4iKSxj
-cjp0KCJKUSIpLEQ6dCgiYm4iKSx5OnQoImEyIiksYWw6dCgiYTIoTWgpIiksYkI6dCgiYTIocVUpIiks
-YmY6dCgiYTIoQCkiKSxnUjp0KCJDUCIpLHo6dCgiQCIpLGZPOnQoIkAoKSIpLFU6dCgiQChlYSkiKSxi
-STp0KCJAKE1oKSIpLGVwOnQoIkAoTWgsTWgpIiksYWc6dCgiQChNaCxHeikiKSxiVTp0KCJAKHh1PHFV
-PikiKSxkTzp0KCJAKHFVKSIpLGJjOnQoIkAoQCkiKSxiODp0KCJAKEAsQCkiKSxxOnQoIklmIiksZGk6
-dCgibGYiKSxIOnQoIn4iKSxNOnQoIn4oKSIpLGFuOnQoIn4oZXcpIiksZUE6dCgifihxVSxxVSkiKSxj
-QTp0KCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24gY29uc3RhbnRzKCl7dmFyIHQ9aHVua0hlbHBlcnMu
-bWFrZUNvbnN0TGlzdApDLlJZPVcuUVAucHJvdG90eXBlCkMuQlo9Vy5WYi5wcm90b3R5cGUKQy5EdD1X
-LmZKLnByb3RvdHlwZQpDLk9rPUoudkIucHJvdG90eXBlCkMuTm09Si5qZC5wcm90b3R5cGUKQy5qbj1K
-LnVyLnByb3RvdHlwZQpDLkNEPUoucUkucHJvdG90eXBlCkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1K
-LmM1LnByb3RvdHlwZQpDLkV4PVcudTgucHJvdG90eXBlCkMuTHQ9Vy5TTi5wcm90b3R5cGUKQy5aUT1K
-LmlDLnByb3RvdHlwZQpDLkllPVcuVGIucHJvdG90eXBlCkMudkI9Si5rZC5wcm90b3R5cGUKQy5vbD1X
-Lks1LnByb3RvdHlwZQpDLnk4PW5ldyBQLlU4KCkKQy5oOT1uZXcgUC5DVigpCkMud2I9ZnVuY3Rpb24g
-Z2V0VGFnRmFsbGJhY2sobykgewogIHZhciBzID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxs
-KG8pOwogIHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAtIDEpOwp9CkMuTzQ9ZnVuY3Rpb24o
-KSB7CiAgdmFyIHRvU3RyaW5nRnVuY3Rpb24gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOwogIGZ1
-bmN0aW9uIGdldFRhZyhvKSB7CiAgICB2YXIgcyA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvKTsKICAg
-IHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAtIDEpOwogIH0KICBmdW5jdGlvbiBnZXRVbmtu
-b3duVGFnKG9iamVjdCwgdGFnKSB7CiAgICBpZiAoL15IVE1MW0EtWl0uKkVsZW1lbnQkLy50ZXN0KHRh
-ZykpIHsKICAgICAgdmFyIG5hbWUgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwob2JqZWN0KTsKICAgICAg
-aWYgKG5hbWUgPT0gIltvYmplY3QgT2JqZWN0XSIpIHJldHVybiBudWxsOwogICAgICByZXR1cm4gIkhU
-TUxFbGVtZW50IjsKICAgIH0KICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2Vy
-KG9iamVjdCwgdGFnKSB7CiAgICBpZiAoc2VsZi5IVE1MRWxlbWVudCAmJiBvYmplY3QgaW5zdGFuY2Vv
-ZiBIVE1MRWxlbWVudCkgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICByZXR1cm4gZ2V0VW5rbm93blRh
-ZyhvYmplY3QsIHRhZyk7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZyh0YWcpIHsKICAgIGlm
-ICh0eXBlb2Ygd2luZG93ID09ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIGlmICh0eXBlb2Yg
-d2luZG93W3RhZ10gPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgdmFyIGNvbnN0cnVjdG9y
-ID0gd2luZG93W3RhZ107CiAgICBpZiAodHlwZW9mIGNvbnN0cnVjdG9yICE9ICJmdW5jdGlvbiIpIHJl
-dHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9CiAgZnVuY3Rpb24g
-ZGlzY3JpbWluYXRvcih0YWcpIHsgcmV0dXJuIG51bGw7IH0KICB2YXIgaXNCcm93c2VyID0gdHlwZW9m
-IG5hdmlnYXRvciA9PSAib2JqZWN0IjsKICByZXR1cm4gewogICAgZ2V0VGFnOiBnZXRUYWcsCiAgICBn
-ZXRVbmtub3duVGFnOiBpc0Jyb3dzZXIgPyBnZXRVbmtub3duVGFnR2VuZXJpY0Jyb3dzZXIgOiBnZXRV
-bmtub3duVGFnLAogICAgcHJvdG90eXBlRm9yVGFnOiBwcm90b3R5cGVGb3JUYWcsCiAgICBkaXNjcmlt
-aW5hdG9yOiBkaXNjcmltaW5hdG9yIH07Cn0KQy5kaz1mdW5jdGlvbihnZXRUYWdGYWxsYmFjaykgewog
-IHJldHVybiBmdW5jdGlvbihob29rcykgewogICAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT0gIm9iamVj
-dCIpIHJldHVybiBob29rczsKICAgIHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7CiAgICBpZiAo
-dWEuaW5kZXhPZigiRHVtcFJlbmRlclRyZWUiKSA+PSAwKSByZXR1cm4gaG9va3M7CiAgICBpZiAodWEu
-aW5kZXhPZigiQ2hyb21lIikgPj0gMCkgewogICAgICBmdW5jdGlvbiBjb25maXJtKHApIHsKICAgICAg
-ICByZXR1cm4gdHlwZW9mIHdpbmRvdyA9PSAib2JqZWN0IiAmJiB3aW5kb3dbcF0gJiYgd2luZG93W3Bd
-Lm5hbWUgPT0gcDsKICAgICAgfQogICAgICBpZiAoY29uZmlybSgiV2luZG93IikgJiYgY29uZmlybSgi
-SFRNTEVsZW1lbnQiKSkgcmV0dXJuIGhvb2tzOwogICAgfQogICAgaG9va3MuZ2V0VGFnID0gZ2V0VGFn
-RmFsbGJhY2s7CiAgfTsKfQpDLllxPWZ1bmN0aW9uKGhvb2tzKSB7CiAgaWYgKHR5cGVvZiBkYXJ0RXhw
-ZXJpbWVudGFsRml4dXBHZXRUYWcgIT0gImZ1bmN0aW9uIikgcmV0dXJuIGhvb2tzOwogIGhvb2tzLmdl
-dFRhZyA9IGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyhob29rcy5nZXRUYWcpOwp9CkMuS1U9ZnVu
-Y3Rpb24oaG9va3MpIHsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBwcm90b3R5cGVG
-b3JUYWcgPSBob29rcy5wcm90b3R5cGVGb3JUYWc7CiAgZnVuY3Rpb24gZ2V0VGFnRml4ZWQobykgewog
-ICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIGlmICh0YWcgPT0gIkRvY3VtZW50IikgewogICAgICBp
-ZiAoISFvLnhtbFZlcnNpb24pIHJldHVybiAiIURvY3VtZW50IjsKICAgICAgcmV0dXJuICIhSFRNTERv
-Y3VtZW50IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRh
-Z0ZpeGVkKHRhZykgewogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSByZXR1cm4gbnVsbDsKICAgIHJl
-dHVybiBwcm90b3R5cGVGb3JUYWcodGFnKTsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRml4ZWQ7
-CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBlRm9yVGFnRml4ZWQ7Cn0KQy54aT1mdW5j
-dGlvbihob29rcykgewogIHZhciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3Qi
-ID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiRmlyZWZv
-eCIpID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIg
-cXVpY2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQiOiAiRXZlbnQiLAogICAgIkRhdGFUcmFu
-c2ZlciI6ICJDbGlwYm9hcmQiLAogICAgIkdlb0dlb2xvY2F0aW9uIjogIkdlb2xvY2F0aW9uIiwKICAg
-ICJMb2NhdGlvbiI6ICIhTG9jYXRpb24iLAogICAgIldvcmtlck1lc3NhZ2VFdmVudCI6ICJNZXNzYWdl
-RXZlbnQiLAogICAgIlhNTERvY3VtZW50IjogIiFEb2N1bWVudCJ9OwogIGZ1bmN0aW9uIGdldFRhZ0Zp
-cmVmb3gobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHJldHVybiBxdWlja01hcFt0YWdd
-IHx8IHRhZzsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRmlyZWZveDsKfQpDLmk3PWZ1bmN0aW9u
-KGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBu
-YXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50LyIp
-ID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcXVp
-Y2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQiOiAiRXZlbnQiLAogICAgIkRhdGFUcmFuc2Zl
-ciI6ICJDbGlwYm9hcmQiLAogICAgIkhUTUxEREVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhU
-TUxEVEVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhUTUxQaHJhc2VFbGVtZW50IjogIkhUTUxF
-bGVtZW50IiwKICAgICJQb3NpdGlvbiI6ICJHZW9wb3NpdGlvbiIKICB9OwogIGZ1bmN0aW9uIGdldFRh
-Z0lFKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICB2YXIgbmV3VGFnID0gcXVpY2tNYXBb
-dGFnXTsKICAgIGlmIChuZXdUYWcpIHJldHVybiBuZXdUYWc7CiAgICBpZiAodGFnID09ICJPYmplY3Qi
-KSB7CiAgICAgIGlmICh3aW5kb3cuRGF0YVZpZXcgJiYgKG8gaW5zdGFuY2VvZiB3aW5kb3cuRGF0YVZp
-ZXcpKSByZXR1cm4gIkRhdGFWaWV3IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAgfQogIGZ1bmN0aW9u
-IHByb3RvdHlwZUZvclRhZ0lFKHRhZykgewogICAgdmFyIGNvbnN0cnVjdG9yID0gd2luZG93W3RhZ107
-CiAgICBpZiAoY29uc3RydWN0b3IgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3Ry
-dWN0b3IucHJvdG90eXBlOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdJRTsKICBob29rcy5wcm90
-b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdJRTsKfQpDLmZRPWZ1bmN0aW9uKGhvb2tzKSB7IHJl
-dHVybiBob29rczsgfQoKQy5DdD1uZXcgUC5ieSgpCkMuRXE9bmV3IFAuazUoKQpDLnhNPW5ldyBQLnU1
-KCkKQy5Raz1uZXcgUC5FMygpCkMuTlU9bmV3IFAuSmkoKQpDLnBkPW5ldyBQLlpkKCkKQy5BZD1uZXcg
-TS5INygwLCJIaW50QWN0aW9uS2luZC5hZGROdWxsYWJsZUhpbnQiKQpDLm5lPW5ldyBNLkg3KDEsIkhp
-bnRBY3Rpb25LaW5kLmFkZE5vbk51bGxhYmxlSGludCIpCkMuQTM9bmV3IFAuTXgobnVsbCkKQy5uWD1u
-ZXcgUC5vaihudWxsKQpDLkdiPUguVk0odChbMTI3LDIwNDcsNjU1MzUsMTExNDExMV0pLHUudCkKQy5h
-az1ILlZNKHQoWzAsMCwzMjc3NiwzMzc5MiwxLDEwMjQwLDAsMF0pLHUudCkKQy5jbT1ILlZNKHQoWyIq
-OjpjbGFzcyIsIio6OmRpciIsIio6OmRyYWdnYWJsZSIsIio6OmhpZGRlbiIsIio6OmlkIiwiKjo6aW5l
-cnQiLCIqOjppdGVtcHJvcCIsIio6Oml0ZW1yZWYiLCIqOjppdGVtc2NvcGUiLCIqOjpsYW5nIiwiKjo6
-c3BlbGxjaGVjayIsIio6OnRpdGxlIiwiKjo6dHJhbnNsYXRlIiwiQTo6YWNjZXNza2V5IiwiQTo6Y29v
-cmRzIiwiQTo6aHJlZmxhbmciLCJBOjpuYW1lIiwiQTo6c2hhcGUiLCJBOjp0YWJpbmRleCIsIkE6OnRh
-cmdldCIsIkE6OnR5cGUiLCJBUkVBOjphY2Nlc3NrZXkiLCJBUkVBOjphbHQiLCJBUkVBOjpjb29yZHMi
-LCJBUkVBOjpub2hyZWYiLCJBUkVBOjpzaGFwZSIsIkFSRUE6OnRhYmluZGV4IiwiQVJFQTo6dGFyZ2V0
-IiwiQVVESU86OmNvbnRyb2xzIiwiQVVESU86Omxvb3AiLCJBVURJTzo6bWVkaWFncm91cCIsIkFVRElP
-OjptdXRlZCIsIkFVRElPOjpwcmVsb2FkIiwiQkRPOjpkaXIiLCJCT0RZOjphbGluayIsIkJPRFk6OmJn
-Y29sb3IiLCJCT0RZOjpsaW5rIiwiQk9EWTo6dGV4dCIsIkJPRFk6OnZsaW5rIiwiQlI6OmNsZWFyIiwi
-QlVUVE9OOjphY2Nlc3NrZXkiLCJCVVRUT046OmRpc2FibGVkIiwiQlVUVE9OOjpuYW1lIiwiQlVUVE9O
-Ojp0YWJpbmRleCIsIkJVVFRPTjo6dHlwZSIsIkJVVFRPTjo6dmFsdWUiLCJDQU5WQVM6OmhlaWdodCIs
-IkNBTlZBUzo6d2lkdGgiLCJDQVBUSU9OOjphbGlnbiIsIkNPTDo6YWxpZ24iLCJDT0w6OmNoYXIiLCJD
-T0w6OmNoYXJvZmYiLCJDT0w6OnNwYW4iLCJDT0w6OnZhbGlnbiIsIkNPTDo6d2lkdGgiLCJDT0xHUk9V
-UDo6YWxpZ24iLCJDT0xHUk9VUDo6Y2hhciIsIkNPTEdST1VQOjpjaGFyb2ZmIiwiQ09MR1JPVVA6OnNw
-YW4iLCJDT0xHUk9VUDo6dmFsaWduIiwiQ09MR1JPVVA6OndpZHRoIiwiQ09NTUFORDo6Y2hlY2tlZCIs
-IkNPTU1BTkQ6OmNvbW1hbmQiLCJDT01NQU5EOjpkaXNhYmxlZCIsIkNPTU1BTkQ6OmxhYmVsIiwiQ09N
-TUFORDo6cmFkaW9ncm91cCIsIkNPTU1BTkQ6OnR5cGUiLCJEQVRBOjp2YWx1ZSIsIkRFTDo6ZGF0ZXRp
-bWUiLCJERVRBSUxTOjpvcGVuIiwiRElSOjpjb21wYWN0IiwiRElWOjphbGlnbiIsIkRMOjpjb21wYWN0
-IiwiRklFTERTRVQ6OmRpc2FibGVkIiwiRk9OVDo6Y29sb3IiLCJGT05UOjpmYWNlIiwiRk9OVDo6c2l6
-ZSIsIkZPUk06OmFjY2VwdCIsIkZPUk06OmF1dG9jb21wbGV0ZSIsIkZPUk06OmVuY3R5cGUiLCJGT1JN
-OjptZXRob2QiLCJGT1JNOjpuYW1lIiwiRk9STTo6bm92YWxpZGF0ZSIsIkZPUk06OnRhcmdldCIsIkZS
-QU1FOjpuYW1lIiwiSDE6OmFsaWduIiwiSDI6OmFsaWduIiwiSDM6OmFsaWduIiwiSDQ6OmFsaWduIiwi
-SDU6OmFsaWduIiwiSDY6OmFsaWduIiwiSFI6OmFsaWduIiwiSFI6Om5vc2hhZGUiLCJIUjo6c2l6ZSIs
-IkhSOjp3aWR0aCIsIkhUTUw6OnZlcnNpb24iLCJJRlJBTUU6OmFsaWduIiwiSUZSQU1FOjpmcmFtZWJv
-cmRlciIsIklGUkFNRTo6aGVpZ2h0IiwiSUZSQU1FOjptYXJnaW5oZWlnaHQiLCJJRlJBTUU6Om1hcmdp
-bndpZHRoIiwiSUZSQU1FOjp3aWR0aCIsIklNRzo6YWxpZ24iLCJJTUc6OmFsdCIsIklNRzo6Ym9yZGVy
-IiwiSU1HOjpoZWlnaHQiLCJJTUc6OmhzcGFjZSIsIklNRzo6aXNtYXAiLCJJTUc6Om5hbWUiLCJJTUc6
-OnVzZW1hcCIsIklNRzo6dnNwYWNlIiwiSU1HOjp3aWR0aCIsIklOUFVUOjphY2NlcHQiLCJJTlBVVDo6
-YWNjZXNza2V5IiwiSU5QVVQ6OmFsaWduIiwiSU5QVVQ6OmFsdCIsIklOUFVUOjphdXRvY29tcGxldGUi
-LCJJTlBVVDo6YXV0b2ZvY3VzIiwiSU5QVVQ6OmNoZWNrZWQiLCJJTlBVVDo6ZGlzYWJsZWQiLCJJTlBV
-VDo6aW5wdXRtb2RlIiwiSU5QVVQ6OmlzbWFwIiwiSU5QVVQ6Omxpc3QiLCJJTlBVVDo6bWF4IiwiSU5Q
-VVQ6Om1heGxlbmd0aCIsIklOUFVUOjptaW4iLCJJTlBVVDo6bXVsdGlwbGUiLCJJTlBVVDo6bmFtZSIs
-IklOUFVUOjpwbGFjZWhvbGRlciIsIklOUFVUOjpyZWFkb25seSIsIklOUFVUOjpyZXF1aXJlZCIsIklO
-UFVUOjpzaXplIiwiSU5QVVQ6OnN0ZXAiLCJJTlBVVDo6dGFiaW5kZXgiLCJJTlBVVDo6dHlwZSIsIklO
-UFVUOjp1c2VtYXAiLCJJTlBVVDo6dmFsdWUiLCJJTlM6OmRhdGV0aW1lIiwiS0VZR0VOOjpkaXNhYmxl
-ZCIsIktFWUdFTjo6a2V5dHlwZSIsIktFWUdFTjo6bmFtZSIsIkxBQkVMOjphY2Nlc3NrZXkiLCJMQUJF
-TDo6Zm9yIiwiTEVHRU5EOjphY2Nlc3NrZXkiLCJMRUdFTkQ6OmFsaWduIiwiTEk6OnR5cGUiLCJMSTo6
-dmFsdWUiLCJMSU5LOjpzaXplcyIsIk1BUDo6bmFtZSIsIk1FTlU6OmNvbXBhY3QiLCJNRU5VOjpsYWJl
-bCIsIk1FTlU6OnR5cGUiLCJNRVRFUjo6aGlnaCIsIk1FVEVSOjpsb3ciLCJNRVRFUjo6bWF4IiwiTUVU
-RVI6Om1pbiIsIk1FVEVSOjp2YWx1ZSIsIk9CSkVDVDo6dHlwZW11c3RtYXRjaCIsIk9MOjpjb21wYWN0
-IiwiT0w6OnJldmVyc2VkIiwiT0w6OnN0YXJ0IiwiT0w6OnR5cGUiLCJPUFRHUk9VUDo6ZGlzYWJsZWQi
-LCJPUFRHUk9VUDo6bGFiZWwiLCJPUFRJT046OmRpc2FibGVkIiwiT1BUSU9OOjpsYWJlbCIsIk9QVElP
-Tjo6c2VsZWN0ZWQiLCJPUFRJT046OnZhbHVlIiwiT1VUUFVUOjpmb3IiLCJPVVRQVVQ6Om5hbWUiLCJQ
-OjphbGlnbiIsIlBSRTo6d2lkdGgiLCJQUk9HUkVTUzo6bWF4IiwiUFJPR1JFU1M6Om1pbiIsIlBST0dS
-RVNTOjp2YWx1ZSIsIlNFTEVDVDo6YXV0b2NvbXBsZXRlIiwiU0VMRUNUOjpkaXNhYmxlZCIsIlNFTEVD
-VDo6bXVsdGlwbGUiLCJTRUxFQ1Q6Om5hbWUiLCJTRUxFQ1Q6OnJlcXVpcmVkIiwiU0VMRUNUOjpzaXpl
-IiwiU0VMRUNUOjp0YWJpbmRleCIsIlNPVVJDRTo6dHlwZSIsIlRBQkxFOjphbGlnbiIsIlRBQkxFOjpi
-Z2NvbG9yIiwiVEFCTEU6OmJvcmRlciIsIlRBQkxFOjpjZWxscGFkZGluZyIsIlRBQkxFOjpjZWxsc3Bh
-Y2luZyIsIlRBQkxFOjpmcmFtZSIsIlRBQkxFOjpydWxlcyIsIlRBQkxFOjpzdW1tYXJ5IiwiVEFCTEU6
-OndpZHRoIiwiVEJPRFk6OmFsaWduIiwiVEJPRFk6OmNoYXIiLCJUQk9EWTo6Y2hhcm9mZiIsIlRCT0RZ
-Ojp2YWxpZ24iLCJURDo6YWJiciIsIlREOjphbGlnbiIsIlREOjpheGlzIiwiVEQ6OmJnY29sb3IiLCJU
-RDo6Y2hhciIsIlREOjpjaGFyb2ZmIiwiVEQ6OmNvbHNwYW4iLCJURDo6aGVhZGVycyIsIlREOjpoZWln
-aHQiLCJURDo6bm93cmFwIiwiVEQ6OnJvd3NwYW4iLCJURDo6c2NvcGUiLCJURDo6dmFsaWduIiwiVEQ6
-OndpZHRoIiwiVEVYVEFSRUE6OmFjY2Vzc2tleSIsIlRFWFRBUkVBOjphdXRvY29tcGxldGUiLCJURVhU
-QVJFQTo6Y29scyIsIlRFWFRBUkVBOjpkaXNhYmxlZCIsIlRFWFRBUkVBOjppbnB1dG1vZGUiLCJURVhU
-QVJFQTo6bmFtZSIsIlRFWFRBUkVBOjpwbGFjZWhvbGRlciIsIlRFWFRBUkVBOjpyZWFkb25seSIsIlRF
-WFRBUkVBOjpyZXF1aXJlZCIsIlRFWFRBUkVBOjpyb3dzIiwiVEVYVEFSRUE6OnRhYmluZGV4IiwiVEVY
-VEFSRUE6OndyYXAiLCJURk9PVDo6YWxpZ24iLCJURk9PVDo6Y2hhciIsIlRGT09UOjpjaGFyb2ZmIiwi
-VEZPT1Q6OnZhbGlnbiIsIlRIOjphYmJyIiwiVEg6OmFsaWduIiwiVEg6OmF4aXMiLCJUSDo6Ymdjb2xv
-ciIsIlRIOjpjaGFyIiwiVEg6OmNoYXJvZmYiLCJUSDo6Y29sc3BhbiIsIlRIOjpoZWFkZXJzIiwiVEg6
-OmhlaWdodCIsIlRIOjpub3dyYXAiLCJUSDo6cm93c3BhbiIsIlRIOjpzY29wZSIsIlRIOjp2YWxpZ24i
-LCJUSDo6d2lkdGgiLCJUSEVBRDo6YWxpZ24iLCJUSEVBRDo6Y2hhciIsIlRIRUFEOjpjaGFyb2ZmIiwi
-VEhFQUQ6OnZhbGlnbiIsIlRSOjphbGlnbiIsIlRSOjpiZ2NvbG9yIiwiVFI6OmNoYXIiLCJUUjo6Y2hh
-cm9mZiIsIlRSOjp2YWxpZ24iLCJUUkFDSzo6ZGVmYXVsdCIsIlRSQUNLOjpraW5kIiwiVFJBQ0s6Omxh
-YmVsIiwiVFJBQ0s6OnNyY2xhbmciLCJVTDo6Y29tcGFjdCIsIlVMOjp0eXBlIiwiVklERU86OmNvbnRy
-b2xzIiwiVklERU86OmhlaWdodCIsIlZJREVPOjpsb29wIiwiVklERU86Om1lZGlhZ3JvdXAiLCJWSURF
-Tzo6bXV0ZWQiLCJWSURFTzo6cHJlbG9hZCIsIlZJREVPOjp3aWR0aCJdKSx1LnMpCkMuVkM9SC5WTSh0
-KFswLDAsNjU0OTAsNDUwNTUsNjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMubHI9SC5WTSh0
-KFtDLkFkLEMubmVdKSxILk4wKCJqZDxINz4iKSkKQy5tSz1ILlZNKHQoWzAsMCwyNjYyNCwxMDIzLDY1
-NTM0LDIwNDcsNjU1MzQsMjA0N10pLHUudCkKQy5TcT1ILlZNKHQoWyJIRUFEIiwiQVJFQSIsIkJBU0Ui
-LCJCQVNFRk9OVCIsIkJSIiwiQ09MIiwiQ09MR1JPVVAiLCJFTUJFRCIsIkZSQU1FIiwiRlJBTUVTRVQi
-LCJIUiIsIklNQUdFIiwiSU1HIiwiSU5QVVQiLCJJU0lOREVYIiwiTElOSyIsIk1FVEEiLCJQQVJBTSIs
-IlNPVVJDRSIsIlNUWUxFIiwiVElUTEUiLCJXQlIiXSksdS5zKQpDLmRuPUguVk0odChbXSksSC5OMCgi
-amQ8TEw+IikpCkMueEQ9SC5WTSh0KFtdKSx1LnMpCkMuaFU9SC5WTSh0KFtdKSx1Lm0pCkMudG89SC5W
-TSh0KFswLDAsMzI3MjIsMTIyODcsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuRjM9SC5W
-TSh0KFswLDAsMjQ1NzYsMTAyMyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5lYT1ILlZN
-KHQoWzAsMCwzMjc1NCwxMTI2Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5aSj1ILlZN
-KHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5XZD1ILlZN
-KHQoWzAsMCw2NTQ5MCwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5ReD1ILlZN
-KHQoWyJiaW5kIiwiaWYiLCJyZWYiLCJyZXBlYXQiLCJzeW50YXgiXSksdS5zKQpDLkJJPUguVk0odChb
-IkE6OmhyZWYiLCJBUkVBOjpocmVmIiwiQkxPQ0tRVU9URTo6Y2l0ZSIsIkJPRFk6OmJhY2tncm91bmQi
-LCJDT01NQU5EOjppY29uIiwiREVMOjpjaXRlIiwiRk9STTo6YWN0aW9uIiwiSU1HOjpzcmMiLCJJTlBV
-VDo6c3JjIiwiSU5TOjpjaXRlIiwiUTo6Y2l0ZSIsIlZJREVPOjpwb3N0ZXIiXSksdS5zKQpDLkNNPW5l
-dyBILkxQKDAse30sQy54RCxILk4wKCJMUDxxVSx6TTxqOD4+IikpCkMuV089bmV3IEguTFAoMCx7fSxD
-LnhELEguTjAoIkxQPHFVLHFVPiIpKQpDLmlIPUguVk0odChbXSksSC5OMCgiamQ8R0Q+IikpCkMuRHg9
-bmV3IEguTFAoMCx7fSxDLmlILEguTjAoIkxQPEdELEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRp
-b25UcmVlTm9kZVR5cGUuZGlyZWN0b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2Rl
-VHlwZS5maWxlIikKQy5UZT1uZXcgSC53digiY2FsbCIpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7
-KGZ1bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQueWo9MAokLm1KPW51bGwKJC5QND1udWxsCiQueT1udWxs
-CiQudT1udWxsCiQueDc9bnVsbAokLmo9bnVsbAokLnY9bnVsbAokLks9bnVsbAokLlM2PW51bGwKJC5r
-OD1udWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQokLnhnPVtdCiQueG89bnVsbAokLkJPPW51
-bGwKJC5sdD1udWxsCiQuRVU9bnVsbAokLm9yPVAuRmwodS5OLHUuWikKJC5JNj1udWxsCiQuRmY9bnVs
-bH0pKCk7KGZ1bmN0aW9uIGxhenlJbml0aWFsaXplcnMoKXt2YXIgdD1odW5rSGVscGVycy5sYXp5CnQo
-JCwiZmEiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRDbG9zdXJlIil9KQp0
-KCQsIlkyIiwiQSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2pzIil9KQp0KCQsIlUyIiwi
-U24iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh7CnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJu
-IiRyZWNlaXZlciQifX0pKX0pCnQoJCwieHEiLCJscSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3
-KHskbWV0aG9kJDpudWxsLAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiIkcmVjZWl2ZXIkIn19KSl9
-KQp0KCQsIlIxIiwiTjkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyhudWxsKSl9KQp0KCQsImZO
-IiwiaUkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2YXIgJGFyZ3VtZW50c0V4cHIk
-PSckYXJndW1lbnRzJCcKdHJ5e251bGwuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChzKXty
-ZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsInFpIiwiVU4iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00o
-SC5TNyh2b2lkIDApKX0pCnQoJCwicloiLCJaaCIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlv
-bigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7KHZvaWQgMCkuJG1ldGhvZCQo
-JGFyZ3VtZW50c0V4cHIkKX1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsImtxIiwi
-ck4iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5NaihudWxsKSl9KQp0KCQsInR0IiwiYzMiLGZ1bmN0
-aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt0cnl7bnVsbC4kbWV0aG9kJH1jYXRjaChzKXtyZXR1
-cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsImR0IiwiSEsiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5N
-aih2b2lkIDApKX0pCnQoJCwiQTciLCJyMSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigp
-e3RyeXsodm9pZCAwKS4kbWV0aG9kJH1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQs
-IldjIiwidXQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuT2ooKX0pCnQoJCwia2giLCJ0TCIsZnVuY3Rpb24o
-KXtyZXR1cm4gUC5XSSgpfSkKdCgkLCJidCIsIlY3IixmdW5jdGlvbigpe3JldHVybiBILkRRKEguWEYo
-SC5WTShbLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIs
-LTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTEs
-LTIsLTIsLTIsLTIsLTIsNjIsLTIsNjIsLTIsNjMsNTIsNTMsNTQsNTUsNTYsNTcsNTgsNTksNjAsNjEs
-LTIsLTIsLTIsLTEsLTIsLTIsLTIsMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwx
-NiwxNywxOCwxOSwyMCwyMSwyMiwyMywyNCwyNSwtMiwtMiwtMiwtMiw2MywtMiwyNiwyNywyOCwyOSwz
-MCwzMSwzMiwzMywzNCwzNSwzNiwzNywzOCwzOSw0MCw0MSw0Miw0Myw0NCw0NSw0Niw0Nyw0OCw0OSw1
-MCw1MSwtMiwtMiwtMiwtMiwtMl0sdS50KSkpfSkKdCgkLCJNNSIsIk94IixmdW5jdGlvbigpe3JldHVy
-biB0eXBlb2YgcHJvY2VzcyE9InVuZGVmaW5lZCImJk9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2Fs
-bChwcm9jZXNzKT09IltvYmplY3QgcHJvY2Vzc10iJiZwcm9jZXNzLnBsYXRmb3JtPT0id2luMzIifSkK
-dCgkLCJtZiIsIno0IixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeW1xcLVxcLjAtOUEtWl9hLXp+XSok
-Iil9KQp0KCQsIkF2IiwicDYiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBFcnJvcigpLnN0YWNrIT12b2lk
-IDB9KQp0KCQsIkpHIiwidloiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuS04oKX0pCnQoJCwiU0MiLCJBTiIs
-ZnVuY3Rpb24oKXtyZXR1cm4gUC50TShbIkEiLCJBQkJSIiwiQUNST05ZTSIsIkFERFJFU1MiLCJBUkVB
-IiwiQVJUSUNMRSIsIkFTSURFIiwiQVVESU8iLCJCIiwiQkRJIiwiQkRPIiwiQklHIiwiQkxPQ0tRVU9U
-RSIsIkJSIiwiQlVUVE9OIiwiQ0FOVkFTIiwiQ0FQVElPTiIsIkNFTlRFUiIsIkNJVEUiLCJDT0RFIiwi
-Q09MIiwiQ09MR1JPVVAiLCJDT01NQU5EIiwiREFUQSIsIkRBVEFMSVNUIiwiREQiLCJERUwiLCJERVRB
-SUxTIiwiREZOIiwiRElSIiwiRElWIiwiREwiLCJEVCIsIkVNIiwiRklFTERTRVQiLCJGSUdDQVBUSU9O
-IiwiRklHVVJFIiwiRk9OVCIsIkZPT1RFUiIsIkZPUk0iLCJIMSIsIkgyIiwiSDMiLCJINCIsIkg1Iiwi
-SDYiLCJIRUFERVIiLCJIR1JPVVAiLCJIUiIsIkkiLCJJRlJBTUUiLCJJTUciLCJJTlBVVCIsIklOUyIs
-IktCRCIsIkxBQkVMIiwiTEVHRU5EIiwiTEkiLCJNQVAiLCJNQVJLIiwiTUVOVSIsIk1FVEVSIiwiTkFW
-IiwiTk9CUiIsIk9MIiwiT1BUR1JPVVAiLCJPUFRJT04iLCJPVVRQVVQiLCJQIiwiUFJFIiwiUFJPR1JF
-U1MiLCJRIiwiUyIsIlNBTVAiLCJTRUNUSU9OIiwiU0VMRUNUIiwiU01BTEwiLCJTT1VSQ0UiLCJTUEFO
-IiwiU1RSSUtFIiwiU1RST05HIiwiU1VCIiwiU1VNTUFSWSIsIlNVUCIsIlRBQkxFIiwiVEJPRFkiLCJU
-RCIsIlRFWFRBUkVBIiwiVEZPT1QiLCJUSCIsIlRIRUFEIiwiVElNRSIsIlRSIiwiVFJBQ0siLCJUVCIs
-IlUiLCJVTCIsIlZBUiIsIlZJREVPIiwiV0JSIl0sdS5OKX0pCnQoJCwiWDQiLCJoRyIsZnVuY3Rpb24o
-KXtyZXR1cm4gUC5udSgiXlxcUyskIil9KQp0KCQsIndPIiwib3ciLGZ1bmN0aW9uKCl7cmV0dXJuIHUu
-di5hKFAuTkQoc2VsZikpfSkKdCgkLCJrdCIsIkNyIixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRh
-cnRfZGFydE9iamVjdCIpfSkKdCgkLCJmSyIsImtJIixmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbiBE
-YXJ0T2JqZWN0KGEpe3RoaXMubz1hfX0pCnQoJCwicXQiLCJ6QiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3
-IFQubVEoKX0pCnQoJCwiT2wiLCJVRSIsZnVuY3Rpb24oKXtyZXR1cm4gUC5oSyhDLm9sLmdtVyhXLngz
-KCkpLmhyZWYpLmdoWSgpLnEoMCwiYXV0aFRva2VuIil9KQp0KCQsImhUIiwieVAiLGZ1bmN0aW9uKCl7
-cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0IC5wYW5lbC1jb250ZW50Iil9KQp0
-KCQsIlc2IiwiaEwiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1w
-YW5lbCAucGFuZWwtY29udGVudCIpfSkKdCgkLCJUUiIsIkRXIixmdW5jdGlvbigpe3JldHVybiBXLlpy
-KCkucXVlcnlTZWxlY3RvcigiZm9vdGVyIil9KQp0KCQsIkVZIiwiZmkiLGZ1bmN0aW9uKCl7cmV0dXJu
-IFcuWnIoKS5xdWVyeVNlbGVjdG9yKCJoZWFkZXIiKX0pCnQoJCwiYXYiLCJEOSIsZnVuY3Rpb24oKXty
-ZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIiN1bml0LW5hbWUiKX0pCnQoJCwiZmUiLCJLRyIsZnVu
-Y3Rpb24oKXtyZXR1cm4gbmV3IEwuWEEoKX0pCnQoJCwiZW8iLCJuVSIsZnVuY3Rpb24oKXtyZXR1cm4g
-bmV3IE0ubEkoJC5IaygpKX0pCnQoJCwieXIiLCJiRCIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEUuT0Yo
-UC5udSgiLyIpLFAubnUoIlteL10kIiksUC5udSgiXi8iKSl9KQp0KCQsIk1rIiwiS2siLGZ1bmN0aW9u
-KCl7cmV0dXJuIG5ldyBMLklWKFAubnUoIlsvXFxcXF0iKSxQLm51KCJbXi9cXFxcXSQiKSxQLm51KCJe
-KFxcXFxcXFxcW15cXFxcXStcXFxcW15cXFxcL10rfFthLXpBLVpdOlsvXFxcXF0pIiksUC5udSgiXlsv
-XFxcXF0oPyFbL1xcXFxdKSIpKX0pCnQoJCwiYWsiLCJFYiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEYu
-cnUoUC5udSgiLyIpLFAubnUoIiheW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly98W14vXSkkIiksUC5u
-dSgiW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly9bXi9dKiIpLFAubnUoIl4vIikpfSkKdCgkLCJscyIs
-IkhrIixmdW5jdGlvbigpe3JldHVybiBPLlJoKCl9KX0pKCk7KGZ1bmN0aW9uIG5hdGl2ZVN1cHBvcnQo
-KXshZnVuY3Rpb24oKXt2YXIgdD1mdW5jdGlvbihhKXt2YXIgbj17fQpuW2FdPTEKcmV0dXJuIE9iamVj
-dC5rZXlzKGh1bmtIZWxwZXJzLmNvbnZlcnRUb0Zhc3RPYmplY3QobikpWzBdfQp2LmdldElzb2xhdGVU
-YWc9ZnVuY3Rpb24oYSl7cmV0dXJuIHQoIl9fX2RhcnRfIithK3YuaXNvbGF0ZVRhZyl9CnZhciBzPSJf
-X19kYXJ0X2lzb2xhdGVfdGFnc18iCnZhciByPU9iamVjdFtzXXx8KE9iamVjdFtzXT1PYmplY3QuY3Jl
-YXRlKG51bGwpKQp2YXIgcT0iX1p4WXhYIgpmb3IodmFyIHA9MDs7cCsrKXt2YXIgbz10KHErIl8iK3Ar
-Il8iKQppZighKG8gaW4gcikpe3Jbb109MQp2Lmlzb2xhdGVUYWc9bwpicmVha319di5kaXNwYXRjaFBy
-b3BlcnR5TmFtZT12LmdldElzb2xhdGVUYWcoImRpc3BhdGNoX3JlY29yZCIpfSgpCmh1bmtIZWxwZXJz
-LnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcoe0RPTUVycm9yOkoudkIsRE9NSW1wbGVtZW50YXRp
-b246Si52QixNZWRpYUVycm9yOkoudkIsTmF2aWdhdG9yOkoudkIsTmF2aWdhdG9yQ29uY3VycmVudEhh
-cmR3YXJlOkoudkIsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6Si52QixPdmVyY29uc3RyYWluZWRFcnJv
-cjpKLnZCLFBvc2l0aW9uRXJyb3I6Si52QixSYW5nZTpKLnZCLFNRTEVycm9yOkoudkIsRGF0YVZpZXc6
-SC5wRixBcnJheUJ1ZmZlclZpZXc6SC5wRixGbG9hdDMyQXJyYXk6SC5EZyxGbG9hdDY0QXJyYXk6SC5E
-ZyxJbnQxNkFycmF5OkgueGosSW50MzJBcnJheTpILmRFLEludDhBcnJheTpILlpBLFVpbnQxNkFycmF5
-Okgud2YsVWludDMyQXJyYXk6SC5QcSxVaW50OENsYW1wZWRBcnJheTpILmVFLENhbnZhc1BpeGVsQXJy
-YXk6SC5lRSxVaW50OEFycmF5OkguVjYsSFRNTEF1ZGlvRWxlbWVudDpXLnFFLEhUTUxCUkVsZW1lbnQ6
-Vy5xRSxIVE1MQnV0dG9uRWxlbWVudDpXLnFFLEhUTUxDYW52YXNFbGVtZW50OlcucUUsSFRNTENvbnRl
-bnRFbGVtZW50OlcucUUsSFRNTERMaXN0RWxlbWVudDpXLnFFLEhUTUxEYXRhRWxlbWVudDpXLnFFLEhU
-TUxEYXRhTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGV0YWlsc0VsZW1lbnQ6Vy5xRSxIVE1MRGlhbG9nRWxl
-bWVudDpXLnFFLEhUTUxEaXZFbGVtZW50OlcucUUsSFRNTEVtYmVkRWxlbWVudDpXLnFFLEhUTUxGaWVs
-ZFNldEVsZW1lbnQ6Vy5xRSxIVE1MSFJFbGVtZW50OlcucUUsSFRNTEhlYWRFbGVtZW50OlcucUUsSFRN
-TEhlYWRpbmdFbGVtZW50OlcucUUsSFRNTEh0bWxFbGVtZW50OlcucUUsSFRNTElGcmFtZUVsZW1lbnQ6
-Vy5xRSxIVE1MSW1hZ2VFbGVtZW50OlcucUUsSFRNTElucHV0RWxlbWVudDpXLnFFLEhUTUxMSUVsZW1l
-bnQ6Vy5xRSxIVE1MTGFiZWxFbGVtZW50OlcucUUsSFRNTExlZ2VuZEVsZW1lbnQ6Vy5xRSxIVE1MTGlu
-a0VsZW1lbnQ6Vy5xRSxIVE1MTWFwRWxlbWVudDpXLnFFLEhUTUxNZWRpYUVsZW1lbnQ6Vy5xRSxIVE1M
-TWVudUVsZW1lbnQ6Vy5xRSxIVE1MTWV0YUVsZW1lbnQ6Vy5xRSxIVE1MTWV0ZXJFbGVtZW50OlcucUUs
-SFRNTE1vZEVsZW1lbnQ6Vy5xRSxIVE1MT0xpc3RFbGVtZW50OlcucUUsSFRNTE9iamVjdEVsZW1lbnQ6
-Vy5xRSxIVE1MT3B0R3JvdXBFbGVtZW50OlcucUUsSFRNTE9wdGlvbkVsZW1lbnQ6Vy5xRSxIVE1MT3V0
-cHV0RWxlbWVudDpXLnFFLEhUTUxQYXJhbUVsZW1lbnQ6Vy5xRSxIVE1MUGljdHVyZUVsZW1lbnQ6Vy5x
-RSxIVE1MUHJlRWxlbWVudDpXLnFFLEhUTUxQcm9ncmVzc0VsZW1lbnQ6Vy5xRSxIVE1MUXVvdGVFbGVt
-ZW50OlcucUUsSFRNTFNjcmlwdEVsZW1lbnQ6Vy5xRSxIVE1MU2hhZG93RWxlbWVudDpXLnFFLEhUTUxT
-bG90RWxlbWVudDpXLnFFLEhUTUxTb3VyY2VFbGVtZW50OlcucUUsSFRNTFNwYW5FbGVtZW50OlcucUUs
-SFRNTFN0eWxlRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OlcucUUsSFRNTFRhYmxl
-Q2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVIZWFk
-ZXJDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNvbEVsZW1lbnQ6Vy5xRSxIVE1MVGV4dEFyZWFFbGVt
-ZW50OlcucUUsSFRNTFRpbWVFbGVtZW50OlcucUUsSFRNTFRpdGxlRWxlbWVudDpXLnFFLEhUTUxUcmFj
-a0VsZW1lbnQ6Vy5xRSxIVE1MVUxpc3RFbGVtZW50OlcucUUsSFRNTFVua25vd25FbGVtZW50OlcucUUs
-SFRNTFZpZGVvRWxlbWVudDpXLnFFLEhUTUxEaXJlY3RvcnlFbGVtZW50OlcucUUsSFRNTEZvbnRFbGVt
-ZW50OlcucUUsSFRNTEZyYW1lRWxlbWVudDpXLnFFLEhUTUxGcmFtZVNldEVsZW1lbnQ6Vy5xRSxIVE1M
-TWFycXVlZUVsZW1lbnQ6Vy5xRSxIVE1MRWxlbWVudDpXLnFFLEhUTUxBbmNob3JFbGVtZW50OlcuR2gs
-SFRNTEFyZWFFbGVtZW50OlcuZlksSFRNTEJhc2VFbGVtZW50OlcubkIsQmxvYjpXLkF6LEhUTUxCb2R5
-RWxlbWVudDpXLlFQLENEQVRBU2VjdGlvbjpXLm54LENoYXJhY3RlckRhdGE6Vy5ueCxDb21tZW50Olcu
-bngsUHJvY2Vzc2luZ0luc3RydWN0aW9uOlcubngsVGV4dDpXLm54LENTU1N0eWxlRGVjbGFyYXRpb246
-Vy5vSixNU1N0eWxlQ1NTUHJvcGVydGllczpXLm9KLENTUzJQcm9wZXJ0aWVzOlcub0osWE1MRG9jdW1l
-bnQ6Vy5RRixEb2N1bWVudDpXLlFGLERPTUV4Y2VwdGlvbjpXLk5oLERPTVJlY3RSZWFkT25seTpXLklC
-LERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5jdixBYm9ydFBheW1lbnRFdmVudDpXLmVhLEFuaW1h
-dGlvbkV2ZW50OlcuZWEsQW5pbWF0aW9uUGxheWJhY2tFdmVudDpXLmVhLEFwcGxpY2F0aW9uQ2FjaGVF
-cnJvckV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVudDpXLmVhLEJhY2tncm91bmRGZXRj
-aEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoZWRF
-dmVudDpXLmVhLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDpXLmVhLEJlZm9yZVVubG9hZEV2ZW50Olcu
-ZWEsQmxvYkV2ZW50OlcuZWEsQ2FuTWFrZVBheW1lbnRFdmVudDpXLmVhLENsaXBib2FyZEV2ZW50Olcu
-ZWEsQ2xvc2VFdmVudDpXLmVhLEN1c3RvbUV2ZW50OlcuZWEsRGV2aWNlTW90aW9uRXZlbnQ6Vy5lYSxE
-ZXZpY2VPcmllbnRhdGlvbkV2ZW50OlcuZWEsRXJyb3JFdmVudDpXLmVhLEV4dGVuZGFibGVFdmVudDpX
-LmVhLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6Vy5lYSxGZXRjaEV2ZW50OlcuZWEsRm9udEZhY2VTZXRM
-b2FkRXZlbnQ6Vy5lYSxGb3JlaWduRmV0Y2hFdmVudDpXLmVhLEdhbWVwYWRFdmVudDpXLmVhLEhhc2hD
-aGFuZ2VFdmVudDpXLmVhLEluc3RhbGxFdmVudDpXLmVhLE1lZGlhRW5jcnlwdGVkRXZlbnQ6Vy5lYSxN
-ZWRpYUtleU1lc3NhZ2VFdmVudDpXLmVhLE1lZGlhUXVlcnlMaXN0RXZlbnQ6Vy5lYSxNZWRpYVN0cmVh
-bUV2ZW50OlcuZWEsTWVkaWFTdHJlYW1UcmFja0V2ZW50OlcuZWEsTWVzc2FnZUV2ZW50OlcuZWEsTUlE
-SUNvbm5lY3Rpb25FdmVudDpXLmVhLE1JRElNZXNzYWdlRXZlbnQ6Vy5lYSxNdXRhdGlvbkV2ZW50Olcu
-ZWEsTm90aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQYWdlVHJhbnNpdGlvbkV2ZW50OlcuZWEsUGF5bWVudFJl
-cXVlc3RFdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6Vy5lYSxQb3BTdGF0ZUV2ZW50
-OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9u
-Q29ubmVjdGlvbkNsb3NlRXZlbnQ6Vy5lYSxQcm9taXNlUmVqZWN0aW9uRXZlbnQ6Vy5lYSxQdXNoRXZl
-bnQ6Vy5lYSxSVENEYXRhQ2hhbm5lbEV2ZW50OlcuZWEsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDpXLmVh
-LFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6Vy5lYSxSVENUcmFja0V2ZW50OlcuZWEsU2VjdXJpdHlQ
-b2xpY3lWaW9sYXRpb25FdmVudDpXLmVhLFNlbnNvckVycm9yRXZlbnQ6Vy5lYSxTcGVlY2hSZWNvZ25p
-dGlvbkVycm9yOlcuZWEsU3BlZWNoUmVjb2duaXRpb25FdmVudDpXLmVhLFNwZWVjaFN5bnRoZXNpc0V2
-ZW50OlcuZWEsU3RvcmFnZUV2ZW50OlcuZWEsU3luY0V2ZW50OlcuZWEsVHJhY2tFdmVudDpXLmVhLFRy
-YW5zaXRpb25FdmVudDpXLmVhLFdlYktpdFRyYW5zaXRpb25FdmVudDpXLmVhLFZSRGV2aWNlRXZlbnQ6
-Vy5lYSxWUkRpc3BsYXlFdmVudDpXLmVhLFZSU2Vzc2lvbkV2ZW50OlcuZWEsTW9qb0ludGVyZmFjZVJl
-cXVlc3RFdmVudDpXLmVhLFVTQkNvbm5lY3Rpb25FdmVudDpXLmVhLElEQlZlcnNpb25DaGFuZ2VFdmVu
-dDpXLmVhLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OlcuZWEsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50
-OlcuZWEsV2ViR0xDb250ZXh0RXZlbnQ6Vy5lYSxFdmVudDpXLmVhLElucHV0RXZlbnQ6Vy5lYSxFdmVu
-dFRhcmdldDpXLkQwLEZpbGU6Vy5UNSxIVE1MRm9ybUVsZW1lbnQ6Vy5oNCxIaXN0b3J5OlcuYnIsSFRN
-TERvY3VtZW50OlcuVmIsWE1MSHR0cFJlcXVlc3Q6Vy5mSixYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0
-Olcud2EsSW1hZ2VEYXRhOlcuU2csTG9jYXRpb246Vy51OCxNb3VzZUV2ZW50OlcuT0ssRHJhZ0V2ZW50
-OlcuT0ssUG9pbnRlckV2ZW50OlcuT0ssV2hlZWxFdmVudDpXLk9LLERvY3VtZW50RnJhZ21lbnQ6Vy51
-SCxTaGFkb3dSb290OlcudUgsRG9jdW1lbnRUeXBlOlcudUgsTm9kZTpXLnVILE5vZGVMaXN0OlcuQkgs
-UmFkaW9Ob2RlTGlzdDpXLkJILEhUTUxQYXJhZ3JhcGhFbGVtZW50OlcuU04sUHJvZ3Jlc3NFdmVudDpX
-LmV3LFJlc291cmNlUHJvZ3Jlc3NFdmVudDpXLmV3LEhUTUxTZWxlY3RFbGVtZW50OlcubHAsSFRNTFRh
-YmxlRWxlbWVudDpXLlRiLEhUTUxUYWJsZVJvd0VsZW1lbnQ6Vy5JdixIVE1MVGFibGVTZWN0aW9uRWxl
-bWVudDpXLldQLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6Vy55WSxDb21wb3NpdGlvbkV2ZW50OlcudzYsRm9j
-dXNFdmVudDpXLnc2LEtleWJvYXJkRXZlbnQ6Vy53NixUZXh0RXZlbnQ6Vy53NixUb3VjaEV2ZW50Olcu
-dzYsVUlFdmVudDpXLnc2LFdpbmRvdzpXLks1LERPTVdpbmRvdzpXLks1LERlZGljYXRlZFdvcmtlckds
-b2JhbFNjb3BlOlcuQ20sU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOlcuQ20sU2hhcmVkV29ya2VyR2xv
-YmFsU2NvcGU6Vy5DbSxXb3JrZXJHbG9iYWxTY29wZTpXLkNtLEF0dHI6Vy5DUSxDbGllbnRSZWN0Olcu
-dzQsRE9NUmVjdDpXLnc0LE5hbWVkTm9kZU1hcDpXLnJoLE1vek5hbWVkQXR0ck1hcDpXLnJoLElEQktl
-eVJhbmdlOlAuaEYsU1ZHU2NyaXB0RWxlbWVudDpQLm5kLFNWR0FFbGVtZW50OlAuZDUsU1ZHQW5pbWF0
-ZUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVUcmFuc2Zv
-cm1FbGVtZW50OlAuZDUsU1ZHQW5pbWF0aW9uRWxlbWVudDpQLmQ1LFNWR0NpcmNsZUVsZW1lbnQ6UC5k
-NSxTVkdDbGlwUGF0aEVsZW1lbnQ6UC5kNSxTVkdEZWZzRWxlbWVudDpQLmQ1LFNWR0Rlc2NFbGVtZW50
-OlAuZDUsU1ZHRGlzY2FyZEVsZW1lbnQ6UC5kNSxTVkdFbGxpcHNlRWxlbWVudDpQLmQ1LFNWR0ZFQmxl
-bmRFbGVtZW50OlAuZDUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6UC5kNSxTVkdGRUNvbXBvbmVudFRy
-YW5zZmVyRWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9zaXRlRWxlbWVudDpQLmQ1LFNWR0ZFQ29udm9sdmVN
-YXRyaXhFbGVtZW50OlAuZDUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OlAuZDUsU1ZHRkVEaXNw
-bGFjZW1lbnRNYXBFbGVtZW50OlAuZDUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVG
-bG9vZEVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNBRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0JFbGVtZW50OlAu
-ZDUsU1ZHRkVGdW5jR0VsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNSRWxlbWVudDpQLmQ1LFNWR0ZFR2F1c3Np
-YW5CbHVyRWxlbWVudDpQLmQ1LFNWR0ZFSW1hZ2VFbGVtZW50OlAuZDUsU1ZHRkVNZXJnZUVsZW1lbnQ6
-UC5kNSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6UC5kNSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OlAuZDUs
-U1ZHRkVPZmZzZXRFbGVtZW50OlAuZDUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFU3Bl
-Y3VsYXJMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRVRp
-bGVFbGVtZW50OlAuZDUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDpQLmQ1LFNWR0ZpbHRlckVsZW1lbnQ6
-UC5kNSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDpQLmQ1LFNWR0dFbGVtZW50OlAuZDUsU1ZHR2VvbWV0
-cnlFbGVtZW50OlAuZDUsU1ZHR3JhcGhpY3NFbGVtZW50OlAuZDUsU1ZHSW1hZ2VFbGVtZW50OlAuZDUs
-U1ZHTGluZUVsZW1lbnQ6UC5kNSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6UC5kNSxTVkdNYXJrZXJF
-bGVtZW50OlAuZDUsU1ZHTWFza0VsZW1lbnQ6UC5kNSxTVkdNZXRhZGF0YUVsZW1lbnQ6UC5kNSxTVkdQ
-YXRoRWxlbWVudDpQLmQ1LFNWR1BhdHRlcm5FbGVtZW50OlAuZDUsU1ZHUG9seWdvbkVsZW1lbnQ6UC5k
-NSxTVkdQb2x5bGluZUVsZW1lbnQ6UC5kNSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6UC5kNSxTVkdS
-ZWN0RWxlbWVudDpQLmQ1LFNWR1NldEVsZW1lbnQ6UC5kNSxTVkdTdG9wRWxlbWVudDpQLmQ1LFNWR1N0
-eWxlRWxlbWVudDpQLmQ1LFNWR1NWR0VsZW1lbnQ6UC5kNSxTVkdTd2l0Y2hFbGVtZW50OlAuZDUsU1ZH
-U3ltYm9sRWxlbWVudDpQLmQ1LFNWR1RTcGFuRWxlbWVudDpQLmQ1LFNWR1RleHRDb250ZW50RWxlbWVu
-dDpQLmQ1LFNWR1RleHRFbGVtZW50OlAuZDUsU1ZHVGV4dFBhdGhFbGVtZW50OlAuZDUsU1ZHVGV4dFBv
-c2l0aW9uaW5nRWxlbWVudDpQLmQ1LFNWR1RpdGxlRWxlbWVudDpQLmQ1LFNWR1VzZUVsZW1lbnQ6UC5k
-NSxTVkdWaWV3RWxlbWVudDpQLmQ1LFNWR0dyYWRpZW50RWxlbWVudDpQLmQ1LFNWR0NvbXBvbmVudFRy
-YW5zZmVyRnVuY3Rpb25FbGVtZW50OlAuZDUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDpQLmQ1LFNWR01Q
-YXRoRWxlbWVudDpQLmQ1LFNWR0VsZW1lbnQ6UC5kNX0pCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlTGVh
-ZlRhZ3Moe0RPTUVycm9yOnRydWUsRE9NSW1wbGVtZW50YXRpb246dHJ1ZSxNZWRpYUVycm9yOnRydWUs
-TmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQ29uY3VycmVudEhhcmR3YXJlOnRydWUsTmF2aWdhdG9yVXNl
-ck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29uc3RyYWluZWRFcnJvcjp0cnVlLFBvc2l0aW9uRXJyb3I6dHJ1
-ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRydWUsRGF0YVZpZXc6dHJ1ZSxBcnJheUJ1ZmZlclZpZXc6ZmFs
-c2UsRmxvYXQzMkFycmF5OnRydWUsRmxvYXQ2NEFycmF5OnRydWUsSW50MTZBcnJheTp0cnVlLEludDMy
-QXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1ZSxVaW50MTZBcnJheTp0cnVlLFVpbnQzMkFycmF5OnRydWUs
-VWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxDYW52YXNQaXhlbEFycmF5OnRydWUsVWludDhBcnJheTpmYWxz
-ZSxIVE1MQXVkaW9FbGVtZW50OnRydWUsSFRNTEJSRWxlbWVudDp0cnVlLEhUTUxCdXR0b25FbGVtZW50
-OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6dHJ1ZSxIVE1MQ29udGVudEVsZW1lbnQ6dHJ1ZSxIVE1MRExp
-c3RFbGVtZW50OnRydWUsSFRNTERhdGFFbGVtZW50OnRydWUsSFRNTERhdGFMaXN0RWxlbWVudDp0cnVl
-LEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFsb2dFbGVtZW50OnRydWUsSFRNTERpdkVsZW1l
-bnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRNTEZpZWxkU2V0RWxlbWVudDp0cnVlLEhUTUxI
-UkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZGluZ0VsZW1lbnQ6dHJ1ZSxI
-VE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVudDp0cnVlLEhUTUxJbWFnZUVsZW1lbnQ6
-dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRydWUsSFRNTExJRWxlbWVudDp0cnVlLEhUTUxMYWJlbEVsZW1l
-bnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVudDp0cnVlLEhUTUxMaW5rRWxlbWVudDp0cnVlLEhUTUxNYXBF
-bGVtZW50OnRydWUsSFRNTE1lZGlhRWxlbWVudDp0cnVlLEhUTUxNZW51RWxlbWVudDp0cnVlLEhUTUxN
-ZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRlckVsZW1lbnQ6dHJ1ZSxIVE1MTW9kRWxlbWVudDp0cnVlLEhU
-TUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVudDp0cnVlLEhUTUxPcHRHcm91cEVsZW1l
-bnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVudDp0cnVlLEhUTUxPdXRwdXRFbGVtZW50OnRydWUsSFRNTFBh
-cmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0dXJlRWxlbWVudDp0cnVlLEhUTUxQcmVFbGVtZW50OnRydWUs
-SFRNTFByb2dyZXNzRWxlbWVudDp0cnVlLEhUTUxRdW90ZUVsZW1lbnQ6dHJ1ZSxIVE1MU2NyaXB0RWxl
-bWVudDp0cnVlLEhUTUxTaGFkb3dFbGVtZW50OnRydWUsSFRNTFNsb3RFbGVtZW50OnRydWUsSFRNTFNv
-dXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5bGVFbGVtZW50OnRydWUs
-SFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDZWxsRWxlbWVudDp0cnVlLEhUTUxU
-YWJsZURhdGFDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50OnRydWUsSFRN
-TFRhYmxlQ29sRWxlbWVudDp0cnVlLEhUTUxUZXh0QXJlYUVsZW1lbnQ6dHJ1ZSxIVE1MVGltZUVsZW1l
-bnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50OnRydWUsSFRNTFRyYWNrRWxlbWVudDp0cnVlLEhUTUxVTGlz
-dEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlkZW9FbGVtZW50OnRydWUs
-SFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1ZSxIVE1MRnJhbWVFbGVt
-ZW50OnRydWUsSFRNTEZyYW1lU2V0RWxlbWVudDp0cnVlLEhUTUxNYXJxdWVlRWxlbWVudDp0cnVlLEhU
-TUxFbGVtZW50OmZhbHNlLEhUTUxBbmNob3JFbGVtZW50OnRydWUsSFRNTEFyZWFFbGVtZW50OnRydWUs
-SFRNTEJhc2VFbGVtZW50OnRydWUsQmxvYjpmYWxzZSxIVE1MQm9keUVsZW1lbnQ6dHJ1ZSxDREFUQVNl
-Y3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRhOnRydWUsQ29tbWVudDp0cnVlLFByb2Nlc3NpbmdJbnN0cnVj
-dGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NTdHlsZURlY2xhcmF0aW9uOnRydWUsTVNTdHlsZUNTU1Byb3Bl
-cnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGllczp0cnVlLFhNTERvY3VtZW50OnRydWUsRG9jdW1lbnQ6ZmFs
-c2UsRE9NRXhjZXB0aW9uOnRydWUsRE9NUmVjdFJlYWRPbmx5OmZhbHNlLERPTVRva2VuTGlzdDp0cnVl
-LEVsZW1lbnQ6ZmFsc2UsQWJvcnRQYXltZW50RXZlbnQ6dHJ1ZSxBbmltYXRpb25FdmVudDp0cnVlLEFu
-aW1hdGlvblBsYXliYWNrRXZlbnQ6dHJ1ZSxBcHBsaWNhdGlvbkNhY2hlRXJyb3JFdmVudDp0cnVlLEJh
-Y2tncm91bmRGZXRjaENsaWNrRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hFdmVudDp0cnVlLEJhY2tn
-cm91bmRGZXRjaEZhaWxFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaGVkRXZlbnQ6dHJ1ZSxCZWZvcmVJ
-bnN0YWxsUHJvbXB0RXZlbnQ6dHJ1ZSxCZWZvcmVVbmxvYWRFdmVudDp0cnVlLEJsb2JFdmVudDp0cnVl
-LENhbk1ha2VQYXltZW50RXZlbnQ6dHJ1ZSxDbGlwYm9hcmRFdmVudDp0cnVlLENsb3NlRXZlbnQ6dHJ1
-ZSxDdXN0b21FdmVudDp0cnVlLERldmljZU1vdGlvbkV2ZW50OnRydWUsRGV2aWNlT3JpZW50YXRpb25F
-dmVudDp0cnVlLEVycm9yRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlTWVz
-c2FnZUV2ZW50OnRydWUsRmV0Y2hFdmVudDp0cnVlLEZvbnRGYWNlU2V0TG9hZEV2ZW50OnRydWUsRm9y
-ZWlnbkZldGNoRXZlbnQ6dHJ1ZSxHYW1lcGFkRXZlbnQ6dHJ1ZSxIYXNoQ2hhbmdlRXZlbnQ6dHJ1ZSxJ
-bnN0YWxsRXZlbnQ6dHJ1ZSxNZWRpYUVuY3J5cHRlZEV2ZW50OnRydWUsTWVkaWFLZXlNZXNzYWdlRXZl
-bnQ6dHJ1ZSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OnRydWUsTWVkaWFTdHJlYW1FdmVudDp0cnVlLE1lZGlh
-U3RyZWFtVHJhY2tFdmVudDp0cnVlLE1lc3NhZ2VFdmVudDp0cnVlLE1JRElDb25uZWN0aW9uRXZlbnQ6
-dHJ1ZSxNSURJTWVzc2FnZUV2ZW50OnRydWUsTXV0YXRpb25FdmVudDp0cnVlLE5vdGlmaWNhdGlvbkV2
-ZW50OnRydWUsUGFnZVRyYW5zaXRpb25FdmVudDp0cnVlLFBheW1lbnRSZXF1ZXN0RXZlbnQ6dHJ1ZSxQ
-YXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OnRydWUsUG9wU3RhdGVFdmVudDp0cnVlLFByZXNlbnRhdGlv
-bkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDp0cnVlLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2
-ZW50OnRydWUsUHJvbWlzZVJlamVjdGlvbkV2ZW50OnRydWUsUHVzaEV2ZW50OnRydWUsUlRDRGF0YUNo
-YW5uZWxFdmVudDp0cnVlLFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6dHJ1ZSxSVENQZWVyQ29ubmVjdGlv
-bkljZUV2ZW50OnRydWUsUlRDVHJhY2tFdmVudDp0cnVlLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZl
-bnQ6dHJ1ZSxTZW5zb3JFcnJvckV2ZW50OnRydWUsU3BlZWNoUmVjb2duaXRpb25FcnJvcjp0cnVlLFNw
-ZWVjaFJlY29nbml0aW9uRXZlbnQ6dHJ1ZSxTcGVlY2hTeW50aGVzaXNFdmVudDp0cnVlLFN0b3JhZ2VF
-dmVudDp0cnVlLFN5bmNFdmVudDp0cnVlLFRyYWNrRXZlbnQ6dHJ1ZSxUcmFuc2l0aW9uRXZlbnQ6dHJ1
-ZSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxWUkRldmljZUV2ZW50OnRydWUsVlJEaXNwbGF5RXZl
-bnQ6dHJ1ZSxWUlNlc3Npb25FdmVudDp0cnVlLE1vam9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6dHJ1ZSxV
-U0JDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6dHJ1ZSxBdWRpb1Byb2Nl
-c3NpbmdFdmVudDp0cnVlLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDp0cnVlLFdlYkdMQ29udGV4
-dEV2ZW50OnRydWUsRXZlbnQ6ZmFsc2UsSW5wdXRFdmVudDpmYWxzZSxFdmVudFRhcmdldDpmYWxzZSxG
-aWxlOnRydWUsSFRNTEZvcm1FbGVtZW50OnRydWUsSGlzdG9yeTp0cnVlLEhUTUxEb2N1bWVudDp0cnVl
-LFhNTEh0dHBSZXF1ZXN0OnRydWUsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpmYWxzZSxJbWFnZURh
-dGE6dHJ1ZSxMb2NhdGlvbjp0cnVlLE1vdXNlRXZlbnQ6dHJ1ZSxEcmFnRXZlbnQ6dHJ1ZSxQb2ludGVy
-RXZlbnQ6dHJ1ZSxXaGVlbEV2ZW50OnRydWUsRG9jdW1lbnRGcmFnbWVudDp0cnVlLFNoYWRvd1Jvb3Q6
-dHJ1ZSxEb2N1bWVudFR5cGU6dHJ1ZSxOb2RlOmZhbHNlLE5vZGVMaXN0OnRydWUsUmFkaW9Ob2RlTGlz
-dDp0cnVlLEhUTUxQYXJhZ3JhcGhFbGVtZW50OnRydWUsUHJvZ3Jlc3NFdmVudDp0cnVlLFJlc291cmNl
-UHJvZ3Jlc3NFdmVudDp0cnVlLEhUTUxTZWxlY3RFbGVtZW50OnRydWUsSFRNTFRhYmxlRWxlbWVudDp0
-cnVlLEhUTUxUYWJsZVJvd0VsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVTZWN0aW9uRWxlbWVudDp0cnVlLEhU
-TUxUZW1wbGF0ZUVsZW1lbnQ6dHJ1ZSxDb21wb3NpdGlvbkV2ZW50OnRydWUsRm9jdXNFdmVudDp0cnVl
-LEtleWJvYXJkRXZlbnQ6dHJ1ZSxUZXh0RXZlbnQ6dHJ1ZSxUb3VjaEV2ZW50OnRydWUsVUlFdmVudDpm
-YWxzZSxXaW5kb3c6dHJ1ZSxET01XaW5kb3c6dHJ1ZSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTp0
-cnVlLFNlcnZpY2VXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFNoYXJlZFdvcmtlckdsb2JhbFNjb3BlOnRy
-dWUsV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxBdHRyOnRydWUsQ2xpZW50UmVjdDp0cnVlLERPTVJlY3Q6
-dHJ1ZSxOYW1lZE5vZGVNYXA6dHJ1ZSxNb3pOYW1lZEF0dHJNYXA6dHJ1ZSxJREJLZXlSYW5nZTp0cnVl
-LFNWR1NjcmlwdEVsZW1lbnQ6dHJ1ZSxTVkdBRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVFbGVtZW50OnRy
-dWUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlVHJhbnNmb3JtRWxlbWVudDp0
-cnVlLFNWR0FuaW1hdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdDaXJjbGVFbGVtZW50OnRydWUsU1ZHQ2xpcFBh
-dGhFbGVtZW50OnRydWUsU1ZHRGVmc0VsZW1lbnQ6dHJ1ZSxTVkdEZXNjRWxlbWVudDp0cnVlLFNWR0Rp
-c2NhcmRFbGVtZW50OnRydWUsU1ZHRWxsaXBzZUVsZW1lbnQ6dHJ1ZSxTVkdGRUJsZW5kRWxlbWVudDp0
-cnVlLFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVDb21wb25lbnRUcmFuc2ZlckVsZW1l
-bnQ6dHJ1ZSxTVkdGRUNvbXBvc2l0ZUVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbnZvbHZlTWF0cml4RWxlbWVu
-dDp0cnVlLFNWR0ZFRGlmZnVzZUxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFRGlzcGxhY2VtZW50TWFw
-RWxlbWVudDp0cnVlLFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFRmxvb2RFbGVtZW50
-OnRydWUsU1ZHRkVGdW5jQUVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNCRWxlbWVudDp0cnVlLFNWR0ZFRnVu
-Y0dFbGVtZW50OnRydWUsU1ZHRkVGdW5jUkVsZW1lbnQ6dHJ1ZSxTVkdGRUdhdXNzaWFuQmx1ckVsZW1l
-bnQ6dHJ1ZSxTVkdGRUltYWdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VFbGVtZW50OnRydWUsU1ZHRkVN
-ZXJnZU5vZGVFbGVtZW50OnRydWUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDp0cnVlLFNWR0ZFT2Zmc2V0
-RWxlbWVudDp0cnVlLFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVNwZWN1bGFyTGlnaHRp
-bmdFbGVtZW50OnRydWUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVUaWxlRWxlbWVudDp0
-cnVlLFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6dHJ1ZSxTVkdGaWx0ZXJFbGVtZW50OnRydWUsU1ZHRm9y
-ZWlnbk9iamVjdEVsZW1lbnQ6dHJ1ZSxTVkdHRWxlbWVudDp0cnVlLFNWR0dlb21ldHJ5RWxlbWVudDp0
-cnVlLFNWR0dyYXBoaWNzRWxlbWVudDp0cnVlLFNWR0ltYWdlRWxlbWVudDp0cnVlLFNWR0xpbmVFbGVt
-ZW50OnRydWUsU1ZHTGluZWFyR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHTWFya2VyRWxlbWVudDp0cnVl
-LFNWR01hc2tFbGVtZW50OnRydWUsU1ZHTWV0YWRhdGFFbGVtZW50OnRydWUsU1ZHUGF0aEVsZW1lbnQ6
-dHJ1ZSxTVkdQYXR0ZXJuRWxlbWVudDp0cnVlLFNWR1BvbHlnb25FbGVtZW50OnRydWUsU1ZHUG9seWxp
-bmVFbGVtZW50OnRydWUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHUmVjdEVsZW1lbnQ6
-dHJ1ZSxTVkdTZXRFbGVtZW50OnRydWUsU1ZHU3RvcEVsZW1lbnQ6dHJ1ZSxTVkdTdHlsZUVsZW1lbnQ6
-dHJ1ZSxTVkdTVkdFbGVtZW50OnRydWUsU1ZHU3dpdGNoRWxlbWVudDp0cnVlLFNWR1N5bWJvbEVsZW1l
-bnQ6dHJ1ZSxTVkdUU3BhbkVsZW1lbnQ6dHJ1ZSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6dHJ1ZSxTVkdU
-ZXh0RWxlbWVudDp0cnVlLFNWR1RleHRQYXRoRWxlbWVudDp0cnVlLFNWR1RleHRQb3NpdGlvbmluZ0Vs
-ZW1lbnQ6dHJ1ZSxTVkdUaXRsZUVsZW1lbnQ6dHJ1ZSxTVkdVc2VFbGVtZW50OnRydWUsU1ZHVmlld0Vs
-ZW1lbnQ6dHJ1ZSxTVkdHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdDb21wb25lbnRUcmFuc2ZlckZ1bmN0
-aW9uRWxlbWVudDp0cnVlLFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6dHJ1ZSxTVkdNUGF0aEVsZW1lbnQ6
-dHJ1ZSxTVkdFbGVtZW50OmZhbHNlfSkKSC5MWi4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZm
-ZXJWaWV3IgpILlJHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguVlAuJG5h
-dGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5EZy4kbmF0aXZlU3VwZXJjbGFzc1Rh
-Zz0iQXJyYXlCdWZmZXJWaWV3IgpILldCLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZp
-ZXciCkguWkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5QZy4kbmF0aXZl
-U3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3In0pKCkKY29udmVydEFsbFRvRmFzdE9iamVjdCh3
-KQpjb252ZXJ0VG9GYXN0T2JqZWN0KCQpOyhmdW5jdGlvbihhKXtpZih0eXBlb2YgZG9jdW1lbnQ9PT0i
-dW5kZWZpbmVkIil7YShudWxsKQpyZXR1cm59aWYodHlwZW9mIGRvY3VtZW50LmN1cnJlbnRTY3JpcHQh
-PSd1bmRlZmluZWQnKXthKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQpCnJldHVybn12YXIgdD1kb2N1bWVu
-dC5zY3JpcHRzCmZ1bmN0aW9uIG9uTG9hZChiKXtmb3IodmFyIHI9MDtyPHQubGVuZ3RoOysrcil0W3Jd
-LnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSkKYShiLnRhcmdldCl9Zm9yKHZh
-ciBzPTA7czx0Lmxlbmd0aDsrK3MpdFtzXS5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFs
-c2UpfSkoZnVuY3Rpb24oYSl7di5jdXJyZW50U2NyaXB0PWEKaWYodHlwZW9mIGRhcnRNYWluUnVubmVy
-PT09ImZ1bmN0aW9uIilkYXJ0TWFpblJ1bm5lcihMLklxLFtdKQplbHNlIEwuSXEoW10pfSl9KSgpCi8v
-IyBzb3VyY2VNYXBwaW5nVVJMPW1pZ3JhdGlvbi5qcy5tYXAK
+LCJ5dCIsIm9BIiw4KQp0KFAsInFXIiwiQnoiLDgpCnMoUCwiVjkiLCJlTiIsMikKcihQLlBmLnByb3Rv
+dHlwZSwiZ1lKIiwwLDEsbnVsbCxbIiQyIiwiJDEiXSxbIncwIiwicG0iXSwyOCwwKQp0KFAsIkN5Iiwi
+TkMiLDEpCnQoUCwiUEgiLCJNdCIsNSkKcShXLCJwUyIsNCxudWxsLFsiJDQiXSxbInFEIl0sOSwwKQpx
+KFcsIlY0Iiw0LG51bGwsWyIkNCJdLFsiUVciXSw5LDApCnAoUC5Bcy5wcm90b3R5cGUsImd1TSIsIlQi
+LDUpCnQoUCwiaUciLCJ3WSIsMSkKdChQLCJ3MCIsIkw3IiwzMykKdChMLCJpUyIsImk2IiwxOCl9KSgp
+OyhmdW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciB0PWh1bmtIZWxwZXJzLm1peGluLHM9aHVua0hlbHBl
+cnMuaW5oZXJpdCxyPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnMoUC5NaCxudWxsKQpyKFAuTWgsW0gu
+RkssSi52QixKLm0xLFAublksUC5jWCxILmE3LFAuQW4sSC5TVSxILlJlLEgud3YsUC5QbixILldVLEgu
+TEksSC5UcCxILmY5LFAuWFMsSC5icSxILlhPLFAuWWssSC5kYixILk42LEguVlIsSC5FSyxILlBiLEgu
+dFEsSC5TZCxILkpjLEguRVQsUC5XMyxQLmloLFAuRnksUC5HVixQLmI4LFAuUGYsUC5GZSxQLnZzLFAu
+T00sUC5xaCxQLk1PLFAua1QsUC54SSxQLk9ILFAubTAsUC5YdixQLmJuLFAubG0sUC5sRCxQLktQLFAu
+TWEsUC5UQyxQLlVrLFAuU2gsUC5SdyxQLmJ6LFAuYTIsUC5pUCxQLmxmLFAuazUsUC5LWSxQLkNELFAu
+YUUsUC5FSCxQLnpNLFAuWjAsUC5OMyxQLmM4LFAuT2QsUC5pYixQLkd6LFAuWmQsUC5xVSxQLlJuLFAu
+R0QsUC5EbixQLlBFLFAuVWYsVy5pZCxXLkZrLFcuSlEsVy5HbSxXLnZELFcubTYsVy5PdyxXLlc5LFcu
+ZFcsVy5GYixXLmtGLFcubWssVy5LbyxQLmlKLFAuRTQsUC5uNixNLkg3LFUuTEwsVS5kMixVLlNlLFUu
+TWwsVS55RCxVLndiLEIuajgsQi5xcCxULm1RLEwuWEEsTC5aWixMLk85LE0ubEksTy56TCxYLldELFgu
+ZHZdKQpyKEoudkIsW0oueUUsSi5ZRSxKLk1GLEouamQsSi5xSSxKLkRyLEguZUgsVy5EMCxXLkF6LFcu
+TGUsVy5OaCxXLklCLFcubjcsVy5lYSxXLmJyLFcuU2csVy51OCxXLks3LFcuWFcsUC5oRl0pCnIoSi5N
+RixbSi5pQyxKLmtkLEouYzVdKQpzKEouUG8sSi5qZCkKcihKLnFJLFtKLmJVLEouVkFdKQpzKFAudXks
+UC5uWSkKcihQLnV5LFtILncyLFcud3osVy5lN10pCnMoSC5xaixILncyKQpyKFAuY1gsW0guYlEsSC5p
+MSxILlU1LEguWFIsUC5tVyxILk5GXSkKcihILmJRLFtILmFMLEguaTUsUC54dV0pCnIoSC5hTCxbSC5u
+SCxILmxKLFAuaThdKQpzKEgueHksSC5pMSkKcihQLkFuLFtILk1ILEgudkddKQpzKFAuUlUsUC5QbikK
+cyhQLkdqLFAuUlUpCnMoSC5QRCxQLkdqKQpzKEguTFAsSC5XVSkKcihILlRwLFtILkNqLEguQW0sSC5s
+YyxILnIsSC5kQyxILndOLFAudGgsUC5oYSxQLlZzLFAuRnQsUC55SCxQLldNLFAuU1gsUC5HcyxQLmRh
+LFAub1EsUC5wVixQLlU3LFAudnIsUC5ySCxQLktGLFAuWkwsUC5SVCxQLmpaLFAucnEsUC5SVyxQLkI1
+LFAudU8sUC5wSyxQLmhqLFAuVnAsUC5PUixQLnJhLFAueVEsUC50aSxQLldGLFAubjEsUC5jUyxQLlZD
+LFAuSlQsUC5lMSxQLk5ZLFAuUlosUC5NRSxQLnk1LFAucTMsUC55SSxQLmM2LFAucWQsVy5DdixXLktT
+LFcuQTMsVy52TixXLlV2LFcuRWcsVy5FbyxXLldrLFcuSUEsVy5mbSxQLmpnLFAuVGEsUC5HRSxQLk43
+LFAudVEsUC5QQyxQLm10LFAuTnosUC5RUyxQLm5wLFUuTUQsVS5hTixVLmIwLEwuZSxMLlZXLEwub1os
+TC5qcixMLnFsLEwueTgsTC5IaSxMLkJULEwuTCxMLld4LEwuQU8sTC5kTixMLkhvLEwueHosTC5JQyxM
+LmZDLEwublQsTC5CWixMLkdILEwuRUUsTC5RTCxMLlZTLEwuVEQsTC5BUyxNLk1pLE0ucTcsTS5ObyxY
+LnFSXSkKcihQLlhTLFtILlcwLEguYXosSC52VixILkVxLFAuQzYsSC51OSxQLlVkLFAuTEssUC5BVCxQ
+Lm1wLFAudWIsUC5kcyxQLmxqLFAuVVYsUC50N10pCnIoSC5sYyxbSC56eCxILmp5XSkKcyhILmtZLFAu
+QzYpCnMoUC5pbCxQLllrKQpyKFAuaWwsW0guTjUsUC51dyxXLmNmLFcuU3ldKQpyKFAubVcsW0guS1cs
+UC5xNF0pCnMoSC5MWixILmVIKQpyKEguTFosW0guUkcsSC5XQl0pCnMoSC5WUCxILlJHKQpzKEguRGcs
+SC5WUCkKcyhILlpHLEguV0IpCnMoSC5QZyxILlpHKQpyKEguUGcsW0gueGosSC5kRSxILlpBLEgud2Ys
+SC5QcSxILmVFLEguVjZdKQpzKEgueCxILnU5KQpzKFAuWmYsUC5QZikKcyhQLkppLFAubTApCnMoUC5i
+NixQLlh2KQpzKFAuVmosUC5UQykKcihQLlVrLFtQLkNWLFAuWmksUC5ieV0pCnMoUC53SSxQLmtUKQpy
+KFAud0ksW1AuVTgsUC5vaixQLk14LFAuRTMsUC5HWV0pCnMoUC5LOCxQLlVkKQpzKFAudHUsUC5TaCkK
+cyhQLnU1LFAuWmkpCnIoUC5sZixbUC5DUCxQLklmXSkKcihQLkFULFtQLmJKLFAuZVldKQpzKFAucWUs
+UC5EbikKcihXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkKcihXLnVILFtXLmN2LFcubngsVy5RRixX
+LkNRXSkKcihXLmN2LFtXLnFFLFAuZDVdKQpyKFcucUUsW1cuR2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxX
+LlNOLFcubHAsVy5UYixXLkl2LFcuV1AsVy55WV0pCnMoVy5vSixXLkxlKQpzKFcuaEgsVy5BeikKcyhX
+LlZiLFcuUUYpCnMoVy5mSixXLndhKQpyKFcuZWEsW1cudzYsVy5ld10pCnMoVy5PSyxXLnc2KQpzKFcu
+ckIsVy5LNykKcyhXLkJILFcuckIpCnMoVy53NCxXLklCKQpzKFcub2EsVy5YVykKcyhXLnJoLFcub2Ep
+CnMoVy5pNyxXLmNmKQpzKFAuQXMsUC5WaikKcihQLkFzLFtXLkk0LFAuS2VdKQpzKFcuUk8sUC5xaCkK
+cyhXLmV1LFcuUk8pCnMoVy54QyxQLk1PKQpzKFcuY3QsVy5tNikKcyhQLkJmLFAuaUopCnIoUC5FNCxb
+UC5yNyxQLmNvXSkKcyhQLlR6LFAuY28pCnMoUC5uZCxQLmQ1KQpzKEIuZnYsTy56TCkKcihCLmZ2LFtF
+Lk9GLEYucnUsTC5JVl0pCnQoSC53MixILlJlKQp0KEguUkcsUC5sRCkKdChILlZQLEguU1UpCnQoSC5X
+QixQLmxEKQp0KEguWkcsSC5TVSkKdChQLm5ZLFAubEQpCnQoUC5UQyxQLk1hKQp0KFAuUlUsUC5LUCkK
+dChXLkxlLFcuaWQpCnQoVy5LNyxQLmxEKQp0KFcuckIsVy5HbSkKdChXLlhXLFAubEQpCnQoVy5vYSxX
+LkdtKQp0KFAuY28sUC5sRCl9KSgpCnZhciB2PXt0eXBlVW5pdmVyc2U6e2VDOm5ldyBNYXAoKSx0Ujp7
+fSxlVDp7fSx0UFY6e30sc0VBOltdfSxtYW5nbGVkR2xvYmFsTmFtZXM6e0lmOiJpbnQiLENQOiJkb3Vi
+bGUiLGxmOiJudW0iLHFVOiJTdHJpbmciLGEyOiJib29sIixjODoiTnVsbCIsek06Ikxpc3QifSxtYW5n
+bGVkTmFtZXM6e30sZ2V0VHlwZUZyb21OYW1lOmdldEdsb2JhbEZyb21OYW1lLG1ldGFkYXRhOltdLHR5
+cGVzOlsiYzgoKSIsIkAoQCkiLCJ+KCkiLCJjOChPSykiLCJjOChALEApIiwicVUocVUpIiwiYzgoY3Yp
+IiwiYTIocVUpIiwifih+KCkpIiwiYTIoY3YscVUscVUsSlEpIiwiYzgoQCkiLCJiODxjOD4oT0spIiwi
+YzgocVUsQCkiLCJjOChxVSkiLCJjOChxVSxxVSkiLCJhMihrRikiLCJ+KHh1PHFVPikiLCJjOChlYSki
+LCJ+KE9LKSIsIn4ocVUsSWYpIiwiYzgofigpKSIsImM4KEAsR3opIiwifihxVSxxVSkiLCJuNihJZiki
+LCJuNihALEApIiwiYTIodUgpIiwiYzgoSWYsQCkiLCJAKGVhKSIsIn4oTWhbR3pdKSIsImM4KEBbR3pd
+KSIsIn4odUgsdUgpIiwiYTIoeHU8cVU+KSIsInZzPEA+KEApIiwiTWgoQCkiLCJUejxAPihAKSIsIkU0
+KEApIiwiYTIoSDcpIiwiTEwoQCkiLCJaMDxxVSxNaD4oTEwpIiwiQChxVSkiLCJjOChHRCxAKSIsImM4
+KFowPHFVLE1oPikiLCJyNyhAKSIsInFVKE9LKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwiYzgo
+ZXcpIiwiQChALHFVKSIsInFVKElmKSIsIn4ocVVbQF0pIiwiSWYoSWYsSWYpIiwifihAKSJdLGludGVy
+Y2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0aTp0eXBlb2YgU3ltYm9sPT0iZnVu
+Y3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJvbCgiJHRpIik6IiR0aSJ9CkgueGIo
+di50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYiLCJy
+eCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiZDUiLCJ0cCI6ImQ1IiwiRzgiOiJldyIsIk1yIjoicUUiLCJl
+TCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwibnIiOiJPSyIsInk0IjoidzYiLCJh
+UCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJlSCIsInlFIjp7ImEyIjpb
+XX0sIllFIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJdLCJi
+USI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0s
+ImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwibGYiOltdfSwiYlUiOnsi
+SWYiOltdLCJDUCI6W10sImxmIjpbXX0sIlZBIjp7IkNQIjpbXSwibGYiOltdfSwiRHIiOnsicVUiOltd
+LCJ2WCI6W119LCJxaiI6eyJSZSI6WyJJZiJdLCJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJ
+ZiJdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiYlEiOnsiY1giOlsiMSJdfSwi
+YUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwiY1gi
+OlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpb
+IjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0s
+ImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJj
+WCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9
+LCJ2RyI6eyJBbiI6WyIxIl19LCJ3MiI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0iOlsiMSJdLCJi
+USI6WyIxIl0sImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJV
+IjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJX
+VSI6eyJaMCI6WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlhS
+Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwiYXoi
+OnsiWFMiOltdfSwidlYiOnsiWFMiOltdfSwiWE8iOnsiR3oiOltdfSwiVHAiOnsiRUgiOltdfSwibGMi
+OnsiRUgiOltdfSwiengiOnsiRUgiOltdfSwiankiOnsiRUgiOltdfSwiRXEiOnsiWFMiOltdfSwia1ki
+OnsiWFMiOltdfSwiTjUiOnsiRm8iOlsiMSIsIjIiXSwiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIi
+XSwiWWsuSyI6IjEiLCJZay5WIjoiMiJ9LCJpNSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXSwiY1guRSI6
+IjEifSwiTjYiOnsiQW4iOlsiMSJdfSwiVlIiOnsid0wiOltdLCJ2WCI6W119LCJFSyI6eyJpYiI6W10s
+Ik9kIjpbXX0sIktXIjp7ImNYIjpbImliIl0sImNYLkUiOiJpYiJ9LCJQYiI6eyJBbiI6WyJpYiJdfSwi
+dFEiOnsiT2QiOltdfSwiTkYiOnsiY1giOlsiT2QiXSwiY1guRSI6Ik9kIn0sIlNkIjp7IkFuIjpbIk9k
+Il19LCJlSCI6eyJlcSI6W119LCJMWiI6eyJYaiI6WyJAIl0sImVIIjpbXSwiZXEiOltdfSwiRGciOnsi
+bEQiOlsiQ1AiXSwiWGoiOlsiQCJdLCJ6TSI6WyJDUCJdLCJlSCI6W10sImJRIjpbIkNQIl0sIlNVIjpb
+IkNQIl0sImVxIjpbXSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sInpN
+IjpbIklmIl0sIlhqIjpbIkAiXSwiZUgiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJlcSI6W10s
+ImNYIjpbIklmIl19LCJ4aiI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJAIl0sImVIIjpb
+XSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiZXEiOltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwi
+ZEUiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiQCJdLCJlSCI6W10sImJRIjpbIklmIl0s
+IlNVIjpbIklmIl0sImVxIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklm
+Il0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwiZUgiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJl
+cSI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJ3ZiI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJd
+LCJYaiI6WyJAIl0sImVIIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiZXEiOltdLCJjWCI6WyJJ
+ZiJdLCJsRC5FIjoiSWYifSwiUHEiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiQCJdLCJl
+SCI6W10sImJRIjpbIklmIl0sIlNVIjpbIklmIl0sImVxIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6Iklm
+In0sImVFIjp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwiZUgiOltdLCJiUSI6WyJJ
+ZiJdLCJTVSI6WyJJZiJdLCJlcSI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJWNiI6eyJuNiI6
+W10sImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwiZUgiOltdLCJiUSI6WyJJZiJdLCJT
+VSI6WyJJZiJdLCJlcSI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJ1OSI6eyJYUyI6W119LCJ4
+Ijp7IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwi
+WmYiOnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiT0giOnsiWFMiOltdfSwibTAiOnsiSkIi
+OltdfSwiSmkiOnsiSkIiOltdfSwiYjYiOnsiWHYiOlsiMSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwi
+Y1giOlsiMSJdfSwibG0iOnsiQW4iOlsiMSJdfSwibVciOnsiY1giOlsiMSJdfSwidXkiOnsibEQiOlsi
+MSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWwiOnsiWWsiOlsiMSIsIjIiXSwi
+WjAiOlsiMSIsIjIiXX0sIllrIjp7IlowIjpbIjEiLCIyIl19LCJQbiI6eyJaMCI6WyIxIiwiMiJdfSwi
+R2oiOnsiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIs
+IjIiXX0sIlZqIjp7Ik1hIjpbIjEiXSwieHUiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlh2
+Ijp7Inh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwi
+WjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJR
+IjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6
+TTxJZj4iLCJxVSJdLCJVay5TIjoiek08SWY+In0sIlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJa
+aSI6eyJVayI6WyJxVSIsInpNPElmPiJdfSwiVWQiOnsiWFMiOltdfSwiSzgiOnsiWFMiOltdfSwiYnki
+OnsiVWsiOlsiTWgiLCJxVSJdLCJVay5TIjoiTWgifSwib2oiOnsid0kiOlsiTWgiLCJxVSJdfSwiTXgi
+Onsid0kiOlsicVUiLCJNaCJdfSwidTUiOnsiVWsiOlsicVUiLCJ6TTxJZj4iXSwiVWsuUyI6InFVIn0s
+IkUzIjp7IndJIjpbInFVIiwiek08SWY+Il19LCJHWSI6eyJ3SSI6WyJ6TTxJZj4iLCJxVSJdfSwiQ1Ai
+OnsibGYiOltdfSwiQzYiOnsiWFMiOltdfSwiTEsiOnsiWFMiOltdfSwiQVQiOnsiWFMiOltdfSwiYkoi
+OnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMi
+OnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1ki
+OnsiWFMiOltdfSwidDciOnsiWFMiOltdfSwiQ0QiOnsiUnoiOltdfSwiYUUiOnsiUnoiOltdfSwiSWYi
+OnsibGYiOltdfSwiek0iOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpYiI6eyJPZCI6W119LCJ4dSI6
+eyJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlpkIjp7Ikd6IjpbXX0sInFVIjp7InZYIjpbXX0sIlJuIjp7
+IkJMIjpbXX0sIkRuIjp7ImlEIjpbXX0sIlVmIjp7ImlEIjpbXX0sInFlIjp7ImlEIjpbXX0sInFFIjp7
+ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJHaCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZlki
+OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm5CIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJR
+UCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwibngiOnsidUgiOltdLCJEMCI6W119LCJRRiI6eyJ1
+SCI6W10sIkQwIjpbXX0sIklCIjp7InRuIjpbImxmIl19LCJ3eiI6eyJsRCI6WyIxIl0sInpNIjpbIjEi
+XSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sImN2Ijp7InVIIjpbXSwiRDAiOltdfSwi
+aEgiOnsiQXoiOltdfSwiaDQiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlZiIjp7InVIIjpbXSwi
+RDAiOltdfSwiZkoiOnsiRDAiOltdfSwid2EiOnsiRDAiOltdfSwiT0siOnsiZWEiOltdfSwiZTciOnsi
+bEQiOlsidUgiXSwiek0iOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIn0s
+InVIIjp7IkQwIjpbXX0sIkJIIjp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhq
+IjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCIsIkdtLkUiOiJ1SCJ9LCJT
+TiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZXciOnsiZWEiOltdfSwibHAiOnsiY3YiOltdLCJ1
+SCI6W10sIkQwIjpbXX0sIlRiIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJJdiI6eyJjdiI6W10s
+InVIIjpbXSwiRDAiOltdfSwiV1AiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sInlZIjp7ImN2Ijpb
+XSwidUgiOltdLCJEMCI6W119LCJ3NiI6eyJlYSI6W119LCJLNSI6eyJ2NiI6W10sIkQwIjpbXX0sIkNt
+Ijp7IkQwIjpbXX0sIkNRIjp7InVIIjpbXSwiRDAiOltdfSwidzQiOnsidG4iOlsibGYiXX0sInJoIjp7
+IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVIIl0sImJRIjpbInVIIl0s
+ImNYIjpbInVIIl0sImxELkUiOiJ1SCIsIkdtLkUiOiJ1SCJ9LCJjZiI6eyJZayI6WyJxVSIsInFVIl0s
+IlowIjpbInFVIiwicVUiXX0sImk3Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZ
+ay5LIjoicVUiLCJZay5WIjoicVUifSwiU3kiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFV
+Il0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJJNCI6eyJNYSI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJi
+USI6WyJxVSJdLCJjWCI6WyJxVSJdfSwiUk8iOnsicWgiOlsiMSJdfSwiZXUiOnsiUk8iOlsiMSJdLCJx
+aCI6WyIxIl19LCJ4QyI6eyJNTyI6WyIxIl19LCJKUSI6eyJrRiI6W119LCJ2RCI6eyJrRiI6W119LCJt
+NiI6eyJrRiI6W119LCJjdCI6eyJrRiI6W119LCJPdyI6eyJrRiI6W119LCJXOSI6eyJBbiI6WyIxIl19
+LCJkVyI6eyJ2NiI6W10sIkQwIjpbXX0sIm1rIjp7InkwIjpbXX0sIktvIjp7Im9uIjpbXX0sIkFzIjp7
+Ik1hIjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl19LCJyNyI6eyJFNCI6
+W119LCJUeiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJFNCI6W10sImNYIjpbIjEi
+XSwibEQuRSI6IjEifSwibmQiOnsiZDUiOltdLCJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiS2UiOnsi
+TWEiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXX0sImQ1Ijp7ImN2Ijpb
+XSwidUgiOltdLCJEMCI6W119LCJuNiI6eyJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJdLCJlcSI6W10sImNY
+IjpbIklmIl19LCJYQSI6eyJrRiI6W119LCJkdiI6eyJSeiI6W119LCJPRiI6eyJmdiI6W119LCJydSI6
+eyJmdiI6W119LCJJViI6eyJmdiI6W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2Uo
+J3siYlEiOjEsIncyIjoxLCJNTyI6MSwia1QiOjIsIm1XIjoxLCJ1eSI6MSwiaWwiOjIsIlZqIjoxLCJu
+WSI6MSwiVEMiOjEsImNvIjoxfScpKQp2YXIgdT0oZnVuY3Rpb24gcnRpaSgpe3ZhciB0PUguTjAKcmV0
+dXJue2JxOnQoIkdoIiksbjp0KCJPSCIpLGNSOnQoIm5CIiksZDp0KCJBeiIpLFk6dCgiUVAiKSxnRjp0
+KCJQRDxHRCxAPiIpLGd3OnQoImJRPEA+IiksaDp0KCJjdiIpLFc6dCgiWFMiKSxCOnQoImVhIikscjp0
+KCJEMCIpLGc4OnQoIlJ6IiksYzg6dCgiaEgiKSxaOnQoIkVIIiksYVE6dCgiYjg8Yzg+IiksYzp0KCJi
+ODxAPiIpLEU6dCgiTEwiKSxncDp0KCJINyIpLEk6dCgiU2ciKSxvOnQoInZRIiksZWg6dCgiY1g8dUg+
+IiksWDp0KCJjWDxxVT4iKSxSOnQoImNYPEA+IiksZkE6dCgiamQ8U2U+IiksZ2k6dCgiamQ8ajg+Iiks
+Sjp0KCJqZDxaMDxxVSxNaD4+IiksZmg6dCgiamQ8Wlo+IiksaTp0KCJqZDxrRj4iKSxzOnQoImpkPHFV
+PiIpLGhoOnQoImpkPHlEPiIpLGFKOnQoImpkPHdiPiIpLGI6dCgiamQ8QD4iKSx0OnQoImpkPElmPiIp
+LGVIOnQoInZtIiksZzp0KCJjNSIpLGFVOnQoIlhqPEA+IiksYW06dCgiVHo8QD4iKSxlbzp0KCJONTxH
+RCxAPiIpLG06dCgiRTQiKSxkejp0KCJoRiIpLGY0OnQoInpNPGo4PiIpLGQzOnQoInpNPFowPHFVLE1o
+Pj4iKSxldzp0KCJ6TTxNaD4iKSxhOnQoInpNPHFVPiIpLGo6dCgiek08QD4iKSxMOnQoInpNPElmPiIp
+LGFfOnQoInU4IiksUzp0KCJaMDxxVSxNaD4iKSxmOnQoIlowPHFVLHFVPiIpLGs6dCgiWjA8cVUsQD4i
+KSxHOnQoIlowPEAsQD4iKSxkdjp0KCJsSjxxVSxxVT4iKSxkbzp0KCJsSjxxVSxAPiIpLFY6dCgiT0si
+KSxkRDp0KCJlSCIpLGJtOnQoIlY2IiksQTp0KCJ1SCIpLGU6dCgia0YiKSxQOnQoImM4IiksSzp0KCJN
+aCIpLEY6dCgiZXciKSxxOnQoInRuPGxmPiIpLGZ2OnQoIndMIiksYXY6dCgiSmMiKSxhTzp0KCJuZCIp
+LEM6dCgieHU8cVU+IiksbDp0KCJHeiIpLE46dCgicVUiKSxkRzp0KCJxVShxVSkiKSxnNzp0KCJkNSIp
+LGZvOnQoIkdEIiksYVc6dCgieVkiKSx1OnQoImVxIiksZ2M6dCgibjYiKSxhazp0KCJrZCIpLHY6dCgi
+R2o8cVUscVU+Iiksdzp0KCJpRCIpLGNjOnQoIlU1PHFVPiIpLGc0OnQoIks1IiksY2k6dCgidjYiKSxn
+Mjp0KCJDbSIpLGJqOnQoIlpmPGZKPiIpLGg5OnQoIkNRIiksYWM6dCgiZTciKSxROnQoImV1PE9LPiIp
+LFQ6dCgid3o8Y3Y+IikseDp0KCJGZTxALEA+IiksYW86dCgidnM8Zko+IiksXzp0KCJ2czxAPiIpLGZK
+OnQoInZzPElmPiIpLE86dCgiSlEiKSxEOnQoImJuIikseTp0KCJhMiIpLGFsOnQoImEyKE1oKSIpLGJC
+OnQoImEyKHFVKSIpLGJmOnQoImEyKEApIiksZ1I6dCgiQ1AiKSx6OnQoIkAiKSxmTzp0KCJAKCkiKSxV
+OnQoIkAoZWEpIiksYkk6dCgiQChNaCkiKSxlcDp0KCJAKE1oLE1oKSIpLGFnOnQoIkAoTWgsR3opIiks
+YlU6dCgiQCh4dTxxVT4pIiksZE86dCgiQChxVSkiKSxiYzp0KCJAKEApIiksYjg6dCgiQChALEApIiks
+cDp0KCJJZiIpLGRpOnQoImxmIiksSDp0KCJ+IiksTTp0KCJ+KCkiKSxhbjp0KCJ+KGV3KSIpLGVBOnQo
+In4ocVUscVUpIiksY0E6dCgifihxVSxAKSIpfX0pKCk7KGZ1bmN0aW9uIGNvbnN0YW50cygpe3ZhciB0
+PWh1bmtIZWxwZXJzLm1ha2VDb25zdExpc3QKQy5SWT1XLlFQLnByb3RvdHlwZQpDLkJaPVcuVmIucHJv
+dG90eXBlCkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5Paz1KLnZCLnByb3RvdHlwZQpDLk5tPUouamQucHJv
+dG90eXBlCkMuam49Si5iVS5wcm90b3R5cGUKQy5DRD1KLnFJLnByb3RvdHlwZQpDLnhCPUouRHIucHJv
+dG90eXBlCkMuREc9Si5jNS5wcm90b3R5cGUKQy5FeD1XLnU4LnByb3RvdHlwZQpDLkx0PVcuU04ucHJv
+dG90eXBlCkMuWlE9Si5pQy5wcm90b3R5cGUKQy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUoua2QucHJv
+dG90eXBlCkMub2w9Vy5LNS5wcm90b3R5cGUKQy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAuQ1YoKQpD
+LndiPWZ1bmN0aW9uIGdldFRhZ0ZhbGxiYWNrKG8pIHsKICB2YXIgcyA9IE9iamVjdC5wcm90b3R5cGUu
+dG9TdHJpbmcuY2FsbChvKTsKICByZXR1cm4gcy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKfQpD
+Lk80PWZ1bmN0aW9uKCkgewogIHZhciB0b1N0cmluZ0Z1bmN0aW9uID0gT2JqZWN0LnByb3RvdHlwZS50
+b1N0cmluZzsKICBmdW5jdGlvbiBnZXRUYWcobykgewogICAgdmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9u
+LmNhbGwobyk7CiAgICByZXR1cm4gcy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKICB9CiAgZnVu
+Y3Rpb24gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZykgewogICAgaWYgKC9eSFRNTFtBLVpdLipFbGVt
+ZW50JC8udGVzdCh0YWcpKSB7CiAgICAgIHZhciBuYW1lID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9i
+amVjdCk7CiAgICAgIGlmIChuYW1lID09ICJbb2JqZWN0IE9iamVjdF0iKSByZXR1cm4gbnVsbDsKICAg
+ICAgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICB9CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25UYWdH
+ZW5lcmljQnJvd3NlcihvYmplY3QsIHRhZykgewogICAgaWYgKHNlbGYuSFRNTEVsZW1lbnQgJiYgb2Jq
+ZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHJldHVybiAiSFRNTEVsZW1lbnQiOwogICAgcmV0dXJu
+IGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWco
+dGFnKSB7CiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAg
+ICBpZiAodHlwZW9mIHdpbmRvd1t0YWddID09ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIHZh
+ciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAi
+ZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAg
+fQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0b3IodGFnKSB7IHJldHVybiBudWxsOyB9CiAgdmFyIGlzQnJv
+d3NlciA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCI7CiAgcmV0dXJuIHsKICAgIGdldFRhZzog
+Z2V0VGFnLAogICAgZ2V0VW5rbm93blRhZzogaXNCcm93c2VyID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNC
+cm93c2VyIDogZ2V0VW5rbm93blRhZywKICAgIHByb3RvdHlwZUZvclRhZzogcHJvdG90eXBlRm9yVGFn
+LAogICAgZGlzY3JpbWluYXRvcjogZGlzY3JpbWluYXRvciB9Owp9CkMuZGs9ZnVuY3Rpb24oZ2V0VGFn
+RmFsbGJhY2spIHsKICByZXR1cm4gZnVuY3Rpb24oaG9va3MpIHsKICAgIGlmICh0eXBlb2YgbmF2aWdh
+dG9yICE9ICJvYmplY3QiKSByZXR1cm4gaG9va3M7CiAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFn
+ZW50OwogICAgaWYgKHVhLmluZGV4T2YoIkR1bXBSZW5kZXJUcmVlIikgPj0gMCkgcmV0dXJuIGhvb2tz
+OwogICAgaWYgKHVhLmluZGV4T2YoIkNocm9tZSIpID49IDApIHsKICAgICAgZnVuY3Rpb24gY29uZmly
+bShwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiB3aW5kb3cgPT0gIm9iamVjdCIgJiYgd2luZG93W3Bd
+ICYmIHdpbmRvd1twXS5uYW1lID09IHA7CiAgICAgIH0KICAgICAgaWYgKGNvbmZpcm0oIldpbmRvdyIp
+ICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50IikpIHJldHVybiBob29rczsKICAgIH0KICAgIGhvb2tzLmdl
+dFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwogIH07Cn0KQy5ZcT1mdW5jdGlvbihob29rcykgewogIGlmICh0
+eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnICE9ICJmdW5jdGlvbiIpIHJldHVybiBob29r
+czsKICBob29rcy5nZXRUYWcgPSBkYXJ0RXhwZXJpbWVudGFsRml4dXBHZXRUYWcoaG9va3MuZ2V0VGFn
+KTsKfQpDLktVPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2
+YXIgcHJvdG90eXBlRm9yVGFnID0gaG9va3MucHJvdG90eXBlRm9yVGFnOwogIGZ1bmN0aW9uIGdldFRh
+Z0ZpeGVkKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICBpZiAodGFnID09ICJEb2N1bWVu
+dCIpIHsKICAgICAgaWYgKCEhby54bWxWZXJzaW9uKSByZXR1cm4gIiFEb2N1bWVudCI7CiAgICAgIHJl
+dHVybiAiIUhUTUxEb2N1bWVudCI7CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBw
+cm90b3R5cGVGb3JUYWdGaXhlZCh0YWcpIHsKICAgIGlmICh0YWcgPT0gIkRvY3VtZW50IikgcmV0dXJu
+IG51bGw7CiAgICByZXR1cm4gcHJvdG90eXBlRm9yVGFnKHRhZyk7CiAgfQogIGhvb2tzLmdldFRhZyA9
+IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnByb3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVk
+Owp9CkMueGk9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRv
+ciA9PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50Lmlu
+ZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkgcmV0dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5n
+ZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwK
+ICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAgICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9s
+b2NhdGlvbiIsCiAgICAiTG9jYXRpb24iOiAiIUxvY2F0aW9uIiwKICAgICJXb3JrZXJNZXNzYWdlRXZl
+bnQiOiAiTWVzc2FnZUV2ZW50IiwKICAgICJYTUxEb2N1bWVudCI6ICIhRG9jdW1lbnQifTsKICBmdW5j
+dGlvbiBnZXRUYWdGaXJlZm94KG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICByZXR1cm4g
+cXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0K
+Qy5pNz1mdW5jdGlvbihob29rcykgewogIHZhciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09
+ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhP
+ZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRU
+YWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAg
+ICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAgICJIVE1MRERFbGVtZW50IjogIkhUTUxFbGVt
+ZW50IiwKICAgICJIVE1MRFRFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MUGhyYXNlRWxl
+bWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiUG9zaXRpb24iOiAiR2VvcG9zaXRpb24iCiAgfTsKICBm
+dW5jdGlvbiBnZXRUYWdJRShvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgdmFyIG5ld1Rh
+ZyA9IHF1aWNrTWFwW3RhZ107CiAgICBpZiAobmV3VGFnKSByZXR1cm4gbmV3VGFnOwogICAgaWYgKHRh
+ZyA9PSAiT2JqZWN0IikgewogICAgICBpZiAod2luZG93LkRhdGFWaWV3ICYmIChvIGluc3RhbmNlb2Yg
+d2luZG93LkRhdGFWaWV3KSkgcmV0dXJuICJEYXRhVmlldyI7CiAgICB9CiAgICByZXR1cm4gdGFnOwog
+IH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdJRSh0YWcpIHsKICAgIHZhciBjb25zdHJ1Y3RvciA9
+IHdpbmRvd1t0YWddOwogICAgaWYgKGNvbnN0cnVjdG9yID09IG51bGwpIHJldHVybiBudWxsOwogICAg
+cmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7
+CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBlRm9yVGFnSUU7Cn0KQy5mUT1mdW5jdGlv
+bihob29rcykgeyByZXR1cm4gaG9va3M7IH0KCkMuQ3Q9bmV3IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkK
+Qy54TT1uZXcgUC51NSgpCkMuUWs9bmV3IFAuRTMoKQpDLk5VPW5ldyBQLkppKCkKQy5wZD1uZXcgUC5a
+ZCgpCkMuQWQ9bmV3IE0uSDcoMCwiSGludEFjdGlvbktpbmQuYWRkTnVsbGFibGVIaW50IikKQy5uZT1u
+ZXcgTS5INygxLCJIaW50QWN0aW9uS2luZC5hZGROb25OdWxsYWJsZUhpbnQiKQpDLm15PW5ldyBNLkg3
+KDIsIkhpbnRBY3Rpb25LaW5kLmNoYW5nZVRvTnVsbGFibGVIaW50IikKQy5yeD1uZXcgTS5INygzLCJI
+aW50QWN0aW9uS2luZC5jaGFuZ2VUb05vbk51bGxhYmxlSGludCIpCkMud1Y9bmV3IE0uSDcoNCwiSGlu
+dEFjdGlvbktpbmQucmVtb3ZlTnVsbGFibGVIaW50IikKQy5mUj1uZXcgTS5INyg1LCJIaW50QWN0aW9u
+S2luZC5yZW1vdmVOb25OdWxsYWJsZUhpbnQiKQpDLkEzPW5ldyBQLk14KG51bGwpCkMublg9bmV3IFAu
+b2oobnVsbCkKQy5HYj1ILlZNKHQoWzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5W
+TSh0KFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xh
+c3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0Iiwi
+Kjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxs
+Y2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIs
+IkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQi
+LCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJF
+QTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFV
+RElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0
+ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9y
+IiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRP
+Tjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFi
+aW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5W
+QVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpj
+aGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFs
+aWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwi
+Q09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01N
+QU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6
+OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwi
+REVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJ
+RUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJG
+T1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0
+aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6
+bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1Ojph
+bGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6
+d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIi
+LCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0
+aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklN
+Rzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2Vt
+YXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vz
+c2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5Q
+VVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6Omlu
+cHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjpt
+YXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBV
+VDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6
+c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6
+dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJL
+RVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZv
+ciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVl
+IiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJN
+RU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjpt
+aW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9M
+OjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BU
+R1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNl
+bGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxp
+Z24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6
+dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11
+bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNF
+TEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xv
+ciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmci
+LCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0
+aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFs
+aWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNo
+YXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0Iiwi
+VEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0
+aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6
+OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6
+Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJF
+QTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVB
+Ojp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09U
+Ojp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJU
+SDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWln
+aHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6
+OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFE
+Ojp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYi
+LCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIs
+IlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIs
+IlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11
+dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCww
+LDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCww
+LDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQi
+LCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJB
+TUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwi
+TUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMuZG49SC5W
+TSh0KFtdKSxILk4wKCJqZDxMTD4iKSkKQy54RD1ILlZNKHQoW10pLHUucykKQy5oVT1ILlZNKHQoW10p
+LHUuYikKQy50bz1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0p
+LHUudCkKQy5yaz1ILlZNKHQoW0MuQWQsQy5uZSxDLm15LEMucngsQy53VixDLmZSXSksSC5OMCgiamQ8
+SDc+IikpCkMuRjM9SC5WTSh0KFswLDAsMjQ1NzYsMTAyMyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0p
+LHUudCkKQy5lYT1ILlZNKHQoWzAsMCwzMjc1NCwxMTI2Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0p
+LHUudCkKQy5aSj1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0p
+LHUudCkKQy5XZD1ILlZNKHQoWzAsMCw2NTQ5MCwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0p
+LHUudCkKQy5ReD1ILlZNKHQoWyJiaW5kIiwiaWYiLCJyZWYiLCJyZXBlYXQiLCJzeW50YXgiXSksdS5z
+KQpDLkJJPUguVk0odChbIkE6OmhyZWYiLCJBUkVBOjpocmVmIiwiQkxPQ0tRVU9URTo6Y2l0ZSIsIkJP
+RFk6OmJhY2tncm91bmQiLCJDT01NQU5EOjppY29uIiwiREVMOjpjaXRlIiwiRk9STTo6YWN0aW9uIiwi
+SU1HOjpzcmMiLCJJTlBVVDo6c3JjIiwiSU5TOjpjaXRlIiwiUTo6Y2l0ZSIsIlZJREVPOjpwb3N0ZXIi
+XSksdS5zKQpDLkNNPW5ldyBILkxQKDAse30sQy54RCxILk4wKCJMUDxxVSx6TTxqOD4+IikpCkMuV089
+bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFVLHFVPiIpKQpDLmlIPUguVk0odChbXSksSC5OMCgi
+amQ8R0Q+IikpCkMuRHg9bmV3IEguTFAoMCx7fSxDLmlILEguTjAoIkxQPEdELEA+IikpCkMuWTI9bmV3
+IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGlyZWN0b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2
+aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1uZXcgSC53digiY2FsbCIpCkMud1E9bmV3IFAu
+RnkobnVsbCwyKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQueWo9MAokLm1KPW51bGwKJC5Q
+ND1udWxsCiQueT1udWxsCiQudT1udWxsCiQueDc9bnVsbAokLmo9bnVsbAokLnY9bnVsbAokLks9bnVs
+bAokLlM2PW51bGwKJC5rOD1udWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQokLnhnPVtdCiQu
+eG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQuRVU9bnVsbAokLm9yPVAuRmwodS5OLHUuWikKJC5J
+Nj1udWxsCiQuRmY9bnVsbH0pKCk7KGZ1bmN0aW9uIGxhenlJbml0aWFsaXplcnMoKXt2YXIgdD1odW5r
+SGVscGVycy5sYXp5CnQoJCwiZmEiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2Rh
+cnRDbG9zdXJlIil9KQp0KCQsIlkyIiwiQSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2pz
+Iil9KQp0KCQsIlUyIiwiU24iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh7CnRvU3RyaW5nOmZ1
+bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnQoJCwieHEiLCJscSIsZnVuY3Rpb24oKXty
+ZXR1cm4gSC5jTShILlM3KHskbWV0aG9kJDpudWxsLAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiIk
+cmVjZWl2ZXIkIn19KSl9KQp0KCQsIlIxIiwiTjkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyhu
+dWxsKSl9KQp0KCQsImZOIiwiaUkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2YXIg
+JGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5e251bGwuJG1ldGhvZCQoJGFyZ3VtZW50c0V4
+cHIkKX1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsInFpIiwiVU4iLGZ1bmN0aW9u
+KCl7cmV0dXJuIEguY00oSC5TNyh2b2lkIDApKX0pCnQoJCwicloiLCJaaCIsZnVuY3Rpb24oKXtyZXR1
+cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7KHZv
+aWQgMCkuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0o
+KSl9KQp0KCQsImtxIiwick4iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5NaihudWxsKSl9KQp0KCQs
+InR0IiwiYzMiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt0cnl7bnVsbC4kbWV0aG9k
+JH1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsImR0IiwiSEsiLGZ1bmN0aW9uKCl7
+cmV0dXJuIEguY00oSC5Naih2b2lkIDApKX0pCnQoJCwiQTciLCJyMSIsZnVuY3Rpb24oKXtyZXR1cm4g
+SC5jTShmdW5jdGlvbigpe3RyeXsodm9pZCAwKS4kbWV0aG9kJH1jYXRjaChzKXtyZXR1cm4gcy5tZXNz
+YWdlfX0oKSl9KQp0KCQsIldjIiwidXQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuT2ooKX0pCnQoJCwia2gi
+LCJ0TCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5XSSgpfSkKdCgkLCJidCIsIlY3IixmdW5jdGlvbigpe3Jl
+dHVybiBILkRRKEguWEYoSC5WTShbLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIs
+LTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIs
+LTIsLTIsLTIsLTIsLTEsLTIsLTIsLTIsLTIsLTIsNjIsLTIsNjIsLTIsNjMsNTIsNTMsNTQsNTUsNTYs
+NTcsNTgsNTksNjAsNjEsLTIsLTIsLTIsLTEsLTIsLTIsLTIsMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwx
+MSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMCwyMSwyMiwyMywyNCwyNSwtMiwtMiwtMiwtMiw2Mywt
+MiwyNiwyNywyOCwyOSwzMCwzMSwzMiwzMywzNCwzNSwzNiwzNywzOCwzOSw0MCw0MSw0Miw0Myw0NCw0
+NSw0Niw0Nyw0OCw0OSw1MCw1MSwtMiwtMiwtMiwtMiwtMl0sdS50KSkpfSkKdCgkLCJNNSIsIk94Iixm
+dW5jdGlvbigpe3JldHVybiB0eXBlb2YgcHJvY2VzcyE9InVuZGVmaW5lZCImJk9iamVjdC5wcm90b3R5
+cGUudG9TdHJpbmcuY2FsbChwcm9jZXNzKT09IltvYmplY3QgcHJvY2Vzc10iJiZwcm9jZXNzLnBsYXRm
+b3JtPT0id2luMzIifSkKdCgkLCJtZiIsIno0IixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeW1xcLVxc
+LjAtOUEtWl9hLXp+XSokIil9KQp0KCQsIkF2IiwicDYiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBFcnJv
+cigpLnN0YWNrIT12b2lkIDB9KQp0KCQsIkpHIiwidloiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuS04oKX0p
+CnQoJCwiU0MiLCJBTiIsZnVuY3Rpb24oKXtyZXR1cm4gUC50TShbIkEiLCJBQkJSIiwiQUNST05ZTSIs
+IkFERFJFU1MiLCJBUkVBIiwiQVJUSUNMRSIsIkFTSURFIiwiQVVESU8iLCJCIiwiQkRJIiwiQkRPIiwi
+QklHIiwiQkxPQ0tRVU9URSIsIkJSIiwiQlVUVE9OIiwiQ0FOVkFTIiwiQ0FQVElPTiIsIkNFTlRFUiIs
+IkNJVEUiLCJDT0RFIiwiQ09MIiwiQ09MR1JPVVAiLCJDT01NQU5EIiwiREFUQSIsIkRBVEFMSVNUIiwi
+REQiLCJERUwiLCJERVRBSUxTIiwiREZOIiwiRElSIiwiRElWIiwiREwiLCJEVCIsIkVNIiwiRklFTERT
+RVQiLCJGSUdDQVBUSU9OIiwiRklHVVJFIiwiRk9OVCIsIkZPT1RFUiIsIkZPUk0iLCJIMSIsIkgyIiwi
+SDMiLCJINCIsIkg1IiwiSDYiLCJIRUFERVIiLCJIR1JPVVAiLCJIUiIsIkkiLCJJRlJBTUUiLCJJTUci
+LCJJTlBVVCIsIklOUyIsIktCRCIsIkxBQkVMIiwiTEVHRU5EIiwiTEkiLCJNQVAiLCJNQVJLIiwiTUVO
+VSIsIk1FVEVSIiwiTkFWIiwiTk9CUiIsIk9MIiwiT1BUR1JPVVAiLCJPUFRJT04iLCJPVVRQVVQiLCJQ
+IiwiUFJFIiwiUFJPR1JFU1MiLCJRIiwiUyIsIlNBTVAiLCJTRUNUSU9OIiwiU0VMRUNUIiwiU01BTEwi
+LCJTT1VSQ0UiLCJTUEFOIiwiU1RSSUtFIiwiU1RST05HIiwiU1VCIiwiU1VNTUFSWSIsIlNVUCIsIlRB
+QkxFIiwiVEJPRFkiLCJURCIsIlRFWFRBUkVBIiwiVEZPT1QiLCJUSCIsIlRIRUFEIiwiVElNRSIsIlRS
+IiwiVFJBQ0siLCJUVCIsIlUiLCJVTCIsIlZBUiIsIlZJREVPIiwiV0JSIl0sdS5OKX0pCnQoJCwiWDQi
+LCJoRyIsZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXlxcUyskIil9KQp0KCQsIndPIiwib3ciLGZ1bmN0
+aW9uKCl7cmV0dXJuIHUubS5hKFAuTkQoc2VsZikpfSkKdCgkLCJrdCIsIkNyIixmdW5jdGlvbigpe3Jl
+dHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkKdCgkLCJmSyIsImtJIixmdW5jdGlvbigpe3Jl
+dHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMubz1hfX0pCnQoJCwicXQiLCJ6QiIsZnVuY3Rp
+b24oKXtyZXR1cm4gbmV3IFQubVEoKX0pCnQoJCwiT2wiLCJVRSIsZnVuY3Rpb24oKXtyZXR1cm4gUC5o
+SyhDLm9sLmdtVyhXLngzKCkpLmhyZWYpLmdoWSgpLnEoMCwiYXV0aFRva2VuIil9KQp0KCQsImhUIiwi
+eVAiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0IC5wYW5l
+bC1jb250ZW50Iil9KQp0KCQsIlc2IiwiaEwiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNl
+bGVjdG9yKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVudCIpfSkKdCgkLCJUUiIsIkRXIixmdW5jdGlv
+bigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiZm9vdGVyIil9KQp0KCQsIkVZIiwiZmkiLGZ1
+bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCJoZWFkZXIiKX0pCnQoJCwiYXYiLCJE
+OSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIiN1bml0LW5hbWUiKX0pCnQo
+JCwiZmUiLCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEwuWEEoKX0pCnQoJCwiZW8iLCJuVSIsZnVu
+Y3Rpb24oKXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0pCnQoJCwieXIiLCJiRCIsZnVuY3Rpb24oKXty
+ZXR1cm4gbmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlteL10kIiksUC5udSgiXi8iKSl9KQp0KCQsIk1r
+IiwiS2siLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklWKFAubnUoIlsvXFxcXF0iKSxQLm51KCJbXi9c
+XFxcXSQiKSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStcXFxcW15cXFxcL10rfFthLXpBLVpdOlsvXFxc
+XF0pIiksUC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIpKX0pCnQoJCwiYWsiLCJFYiIsZnVuY3Rpb24o
+KXtyZXR1cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUoIiheW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6
+Ly98W14vXSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly9bXi9dKiIpLFAubnUoIl4v
+IikpfSkKdCgkLCJscyIsIkhrIixmdW5jdGlvbigpe3JldHVybiBPLlJoKCl9KX0pKCk7KGZ1bmN0aW9u
+IG5hdGl2ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIgdD1mdW5jdGlvbihhKXt2YXIgbj17fQpuW2Fd
+PTEKcmV0dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJzLmNvbnZlcnRUb0Zhc3RPYmplY3QobikpWzBd
+fQp2LmdldElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0dXJuIHQoIl9fX2RhcnRfIithK3YuaXNvbGF0
+ZVRhZyl9CnZhciBzPSJfX19kYXJ0X2lzb2xhdGVfdGFnc18iCnZhciByPU9iamVjdFtzXXx8KE9iamVj
+dFtzXT1PYmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcT0iX1p4WXhYIgpmb3IodmFyIHA9MDs7cCsrKXt2
+YXIgbz10KHErIl8iK3ArIl8iKQppZighKG8gaW4gcikpe3Jbb109MQp2Lmlzb2xhdGVUYWc9bwpicmVh
+a319di5kaXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElzb2xhdGVUYWcoImRpc3BhdGNoX3JlY29yZCIp
+fSgpCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcoe0RPTUVycm9yOkoudkIs
+RE9NSW1wbGVtZW50YXRpb246Si52QixNZWRpYUVycm9yOkoudkIsTmF2aWdhdG9yOkoudkIsTmF2aWdh
+dG9yQ29uY3VycmVudEhhcmR3YXJlOkoudkIsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6Si52QixPdmVy
+Y29uc3RyYWluZWRFcnJvcjpKLnZCLFBvc2l0aW9uRXJyb3I6Si52QixSYW5nZTpKLnZCLFNRTEVycm9y
+OkoudkIsRGF0YVZpZXc6SC5lSCxBcnJheUJ1ZmZlclZpZXc6SC5lSCxGbG9hdDMyQXJyYXk6SC5EZyxG
+bG9hdDY0QXJyYXk6SC5EZyxJbnQxNkFycmF5OkgueGosSW50MzJBcnJheTpILmRFLEludDhBcnJheTpI
+LlpBLFVpbnQxNkFycmF5Okgud2YsVWludDMyQXJyYXk6SC5QcSxVaW50OENsYW1wZWRBcnJheTpILmVF
+LENhbnZhc1BpeGVsQXJyYXk6SC5lRSxVaW50OEFycmF5OkguVjYsSFRNTEF1ZGlvRWxlbWVudDpXLnFF
+LEhUTUxCUkVsZW1lbnQ6Vy5xRSxIVE1MQnV0dG9uRWxlbWVudDpXLnFFLEhUTUxDYW52YXNFbGVtZW50
+OlcucUUsSFRNTENvbnRlbnRFbGVtZW50OlcucUUsSFRNTERMaXN0RWxlbWVudDpXLnFFLEhUTUxEYXRh
+RWxlbWVudDpXLnFFLEhUTUxEYXRhTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGV0YWlsc0VsZW1lbnQ6Vy5x
+RSxIVE1MRGlhbG9nRWxlbWVudDpXLnFFLEhUTUxEaXZFbGVtZW50OlcucUUsSFRNTEVtYmVkRWxlbWVu
+dDpXLnFFLEhUTUxGaWVsZFNldEVsZW1lbnQ6Vy5xRSxIVE1MSFJFbGVtZW50OlcucUUsSFRNTEhlYWRF
+bGVtZW50OlcucUUsSFRNTEhlYWRpbmdFbGVtZW50OlcucUUsSFRNTEh0bWxFbGVtZW50OlcucUUsSFRN
+TElGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MSW1hZ2VFbGVtZW50OlcucUUsSFRNTElucHV0RWxlbWVudDpX
+LnFFLEhUTUxMSUVsZW1lbnQ6Vy5xRSxIVE1MTGFiZWxFbGVtZW50OlcucUUsSFRNTExlZ2VuZEVsZW1l
+bnQ6Vy5xRSxIVE1MTGlua0VsZW1lbnQ6Vy5xRSxIVE1MTWFwRWxlbWVudDpXLnFFLEhUTUxNZWRpYUVs
+ZW1lbnQ6Vy5xRSxIVE1MTWVudUVsZW1lbnQ6Vy5xRSxIVE1MTWV0YUVsZW1lbnQ6Vy5xRSxIVE1MTWV0
+ZXJFbGVtZW50OlcucUUsSFRNTE1vZEVsZW1lbnQ6Vy5xRSxIVE1MT0xpc3RFbGVtZW50OlcucUUsSFRN
+TE9iamVjdEVsZW1lbnQ6Vy5xRSxIVE1MT3B0R3JvdXBFbGVtZW50OlcucUUsSFRNTE9wdGlvbkVsZW1l
+bnQ6Vy5xRSxIVE1MT3V0cHV0RWxlbWVudDpXLnFFLEhUTUxQYXJhbUVsZW1lbnQ6Vy5xRSxIVE1MUGlj
+dHVyZUVsZW1lbnQ6Vy5xRSxIVE1MUHJlRWxlbWVudDpXLnFFLEhUTUxQcm9ncmVzc0VsZW1lbnQ6Vy5x
+RSxIVE1MUXVvdGVFbGVtZW50OlcucUUsSFRNTFNjcmlwdEVsZW1lbnQ6Vy5xRSxIVE1MU2hhZG93RWxl
+bWVudDpXLnFFLEhUTUxTbG90RWxlbWVudDpXLnFFLEhUTUxTb3VyY2VFbGVtZW50OlcucUUsSFRNTFNw
+YW5FbGVtZW50OlcucUUsSFRNTFN0eWxlRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50
+OlcucUUsSFRNTFRhYmxlQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6Vy5x
+RSxIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNvbEVsZW1lbnQ6Vy5xRSxI
+VE1MVGV4dEFyZWFFbGVtZW50OlcucUUsSFRNTFRpbWVFbGVtZW50OlcucUUsSFRNTFRpdGxlRWxlbWVu
+dDpXLnFFLEhUTUxUcmFja0VsZW1lbnQ6Vy5xRSxIVE1MVUxpc3RFbGVtZW50OlcucUUsSFRNTFVua25v
+d25FbGVtZW50OlcucUUsSFRNTFZpZGVvRWxlbWVudDpXLnFFLEhUTUxEaXJlY3RvcnlFbGVtZW50Olcu
+cUUsSFRNTEZvbnRFbGVtZW50OlcucUUsSFRNTEZyYW1lRWxlbWVudDpXLnFFLEhUTUxGcmFtZVNldEVs
+ZW1lbnQ6Vy5xRSxIVE1MTWFycXVlZUVsZW1lbnQ6Vy5xRSxIVE1MRWxlbWVudDpXLnFFLEhUTUxBbmNo
+b3JFbGVtZW50OlcuR2gsSFRNTEFyZWFFbGVtZW50OlcuZlksSFRNTEJhc2VFbGVtZW50OlcubkIsQmxv
+YjpXLkF6LEhUTUxCb2R5RWxlbWVudDpXLlFQLENEQVRBU2VjdGlvbjpXLm54LENoYXJhY3RlckRhdGE6
+Vy5ueCxDb21tZW50OlcubngsUHJvY2Vzc2luZ0luc3RydWN0aW9uOlcubngsVGV4dDpXLm54LENTU1N0
+eWxlRGVjbGFyYXRpb246Vy5vSixNU1N0eWxlQ1NTUHJvcGVydGllczpXLm9KLENTUzJQcm9wZXJ0aWVz
+Olcub0osWE1MRG9jdW1lbnQ6Vy5RRixEb2N1bWVudDpXLlFGLERPTUV4Y2VwdGlvbjpXLk5oLERPTVJl
+Y3RSZWFkT25seTpXLklCLERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5jdixBYm9ydFBheW1lbnRF
+dmVudDpXLmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5pbWF0aW9uUGxheWJhY2tFdmVudDpXLmVhLEFw
+cGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVudDpXLmVh
+LEJhY2tncm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50OlcuZWEsQmFj
+a2dyb3VuZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDpXLmVhLEJlZm9y
+ZVVubG9hZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEsQ2FuTWFrZVBheW1lbnRFdmVudDpXLmVhLENs
+aXBib2FyZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVhLEN1c3RvbUV2ZW50OlcuZWEsRGV2aWNlTW90
+aW9uRXZlbnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OlcuZWEsRXJyb3JFdmVudDpXLmVhLEV4
+dGVuZGFibGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6Vy5lYSxGZXRjaEV2ZW50Olcu
+ZWEsRm9udEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3JlaWduRmV0Y2hFdmVudDpXLmVhLEdhbWVwYWRF
+dmVudDpXLmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLEluc3RhbGxFdmVudDpXLmVhLE1lZGlhRW5jcnlw
+dGVkRXZlbnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVudDpXLmVhLE1lZGlhUXVlcnlMaXN0RXZlbnQ6
+Vy5lYSxNZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFTdHJlYW1UcmFja0V2ZW50OlcuZWEsTWVzc2Fn
+ZUV2ZW50OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpXLmVhLE1JRElNZXNzYWdlRXZlbnQ6Vy5lYSxN
+dXRhdGlvbkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQYWdlVHJhbnNpdGlvbkV2ZW50
+OlcuZWEsUGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6Vy5l
+YSxQb3BTdGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50Olcu
+ZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6Vy5lYSxQcm9taXNlUmVqZWN0aW9uRXZl
+bnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hhbm5lbEV2ZW50OlcuZWEsUlRDRFRNRlRvbmVD
+aGFuZ2VFdmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6Vy5lYSxSVENUcmFja0V2ZW50
+OlcuZWEsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDpXLmVhLFNlbnNvckVycm9yRXZlbnQ6Vy5l
+YSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3BlZWNoUmVjb2duaXRpb25FdmVudDpXLmVhLFNw
+ZWVjaFN5bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2ZW50OlcuZWEsU3luY0V2ZW50OlcuZWEsVHJh
+Y2tFdmVudDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVhLFdlYktpdFRyYW5zaXRpb25FdmVudDpXLmVh
+LFZSRGV2aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVudDpXLmVhLFZSU2Vzc2lvbkV2ZW50OlcuZWEs
+TW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVTQkNvbm5lY3Rpb25FdmVudDpXLmVhLElEQlZl
+cnNpb25DaGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OlcuZWEsT2ZmbGluZUF1ZGlv
+Q29tcGxldGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0RXZlbnQ6Vy5lYSxFdmVudDpXLmVhLElucHV0
+RXZlbnQ6Vy5lYSxFdmVudFRhcmdldDpXLkQwLEZpbGU6Vy5oSCxIVE1MRm9ybUVsZW1lbnQ6Vy5oNCxI
+aXN0b3J5OlcuYnIsSFRNTERvY3VtZW50OlcuVmIsWE1MSHR0cFJlcXVlc3Q6Vy5mSixYTUxIdHRwUmVx
+dWVzdEV2ZW50VGFyZ2V0Olcud2EsSW1hZ2VEYXRhOlcuU2csTG9jYXRpb246Vy51OCxNb3VzZUV2ZW50
+OlcuT0ssRHJhZ0V2ZW50OlcuT0ssUG9pbnRlckV2ZW50OlcuT0ssV2hlZWxFdmVudDpXLk9LLERvY3Vt
+ZW50RnJhZ21lbnQ6Vy51SCxTaGFkb3dSb290OlcudUgsRG9jdW1lbnRUeXBlOlcudUgsTm9kZTpXLnVI
+LE5vZGVMaXN0OlcuQkgsUmFkaW9Ob2RlTGlzdDpXLkJILEhUTUxQYXJhZ3JhcGhFbGVtZW50OlcuU04s
+UHJvZ3Jlc3NFdmVudDpXLmV3LFJlc291cmNlUHJvZ3Jlc3NFdmVudDpXLmV3LEhUTUxTZWxlY3RFbGVt
+ZW50OlcubHAsSFRNTFRhYmxlRWxlbWVudDpXLlRiLEhUTUxUYWJsZVJvd0VsZW1lbnQ6Vy5JdixIVE1M
+VGFibGVTZWN0aW9uRWxlbWVudDpXLldQLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6Vy55WSxDb21wb3NpdGlv
+bkV2ZW50OlcudzYsRm9jdXNFdmVudDpXLnc2LEtleWJvYXJkRXZlbnQ6Vy53NixUZXh0RXZlbnQ6Vy53
+NixUb3VjaEV2ZW50OlcudzYsVUlFdmVudDpXLnc2LFdpbmRvdzpXLks1LERPTVdpbmRvdzpXLks1LERl
+ZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOlcuQ20s
+U2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxXb3JrZXJHbG9iYWxTY29wZTpXLkNtLEF0dHI6Vy5D
+USxDbGllbnRSZWN0OlcudzQsRE9NUmVjdDpXLnc0LE5hbWVkTm9kZU1hcDpXLnJoLE1vek5hbWVkQXR0
+ck1hcDpXLnJoLElEQktleVJhbmdlOlAuaEYsU1ZHU2NyaXB0RWxlbWVudDpQLm5kLFNWR0FFbGVtZW50
+OlAuZDUsU1ZHQW5pbWF0ZUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDpQLmQ1LFNW
+R0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OlAuZDUsU1ZHQW5pbWF0aW9uRWxlbWVudDpQLmQ1LFNWR0Np
+cmNsZUVsZW1lbnQ6UC5kNSxTVkdDbGlwUGF0aEVsZW1lbnQ6UC5kNSxTVkdEZWZzRWxlbWVudDpQLmQ1
+LFNWR0Rlc2NFbGVtZW50OlAuZDUsU1ZHRGlzY2FyZEVsZW1lbnQ6UC5kNSxTVkdFbGxpcHNlRWxlbWVu
+dDpQLmQ1LFNWR0ZFQmxlbmRFbGVtZW50OlAuZDUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6UC5kNSxT
+VkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9zaXRlRWxlbWVudDpQLmQ1
+LFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OlAuZDUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50
+OlAuZDUsU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OlAuZDUsU1ZHRkVEaXN0YW50TGlnaHRFbGVt
+ZW50OlAuZDUsU1ZHRkVGbG9vZEVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNBRWxlbWVudDpQLmQ1LFNWR0ZF
+RnVuY0JFbGVtZW50OlAuZDUsU1ZHRkVGdW5jR0VsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNSRWxlbWVudDpQ
+LmQ1LFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDpQLmQ1LFNWR0ZFSW1hZ2VFbGVtZW50OlAuZDUsU1ZH
+RkVNZXJnZUVsZW1lbnQ6UC5kNSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6UC5kNSxTVkdGRU1vcnBob2xv
+Z3lFbGVtZW50OlAuZDUsU1ZHRkVPZmZzZXRFbGVtZW50OlAuZDUsU1ZHRkVQb2ludExpZ2h0RWxlbWVu
+dDpQLmQ1LFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRVNwb3RMaWdodEVsZW1l
+bnQ6UC5kNSxTVkdGRVRpbGVFbGVtZW50OlAuZDUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDpQLmQ1LFNW
+R0ZpbHRlckVsZW1lbnQ6UC5kNSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDpQLmQ1LFNWR0dFbGVtZW50
+OlAuZDUsU1ZHR2VvbWV0cnlFbGVtZW50OlAuZDUsU1ZHR3JhcGhpY3NFbGVtZW50OlAuZDUsU1ZHSW1h
+Z2VFbGVtZW50OlAuZDUsU1ZHTGluZUVsZW1lbnQ6UC5kNSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6
+UC5kNSxTVkdNYXJrZXJFbGVtZW50OlAuZDUsU1ZHTWFza0VsZW1lbnQ6UC5kNSxTVkdNZXRhZGF0YUVs
+ZW1lbnQ6UC5kNSxTVkdQYXRoRWxlbWVudDpQLmQ1LFNWR1BhdHRlcm5FbGVtZW50OlAuZDUsU1ZHUG9s
+eWdvbkVsZW1lbnQ6UC5kNSxTVkdQb2x5bGluZUVsZW1lbnQ6UC5kNSxTVkdSYWRpYWxHcmFkaWVudEVs
+ZW1lbnQ6UC5kNSxTVkdSZWN0RWxlbWVudDpQLmQ1LFNWR1NldEVsZW1lbnQ6UC5kNSxTVkdTdG9wRWxl
+bWVudDpQLmQ1LFNWR1N0eWxlRWxlbWVudDpQLmQ1LFNWR1NWR0VsZW1lbnQ6UC5kNSxTVkdTd2l0Y2hF
+bGVtZW50OlAuZDUsU1ZHU3ltYm9sRWxlbWVudDpQLmQ1LFNWR1RTcGFuRWxlbWVudDpQLmQ1LFNWR1Rl
+eHRDb250ZW50RWxlbWVudDpQLmQ1LFNWR1RleHRFbGVtZW50OlAuZDUsU1ZHVGV4dFBhdGhFbGVtZW50
+OlAuZDUsU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDpQLmQ1LFNWR1RpdGxlRWxlbWVudDpQLmQ1LFNW
+R1VzZUVsZW1lbnQ6UC5kNSxTVkdWaWV3RWxlbWVudDpQLmQ1LFNWR0dyYWRpZW50RWxlbWVudDpQLmQ1
+LFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OlAuZDUsU1ZHRkVEcm9wU2hhZG93RWxl
+bWVudDpQLmQ1LFNWR01QYXRoRWxlbWVudDpQLmQ1LFNWR0VsZW1lbnQ6UC5kNX0pCmh1bmtIZWxwZXJz
+LnNldE9yVXBkYXRlTGVhZlRhZ3Moe0RPTUVycm9yOnRydWUsRE9NSW1wbGVtZW50YXRpb246dHJ1ZSxN
+ZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQ29uY3VycmVudEhhcmR3YXJlOnRy
+dWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29uc3RyYWluZWRFcnJvcjp0cnVlLFBv
+c2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRydWUsRGF0YVZpZXc6dHJ1ZSxBcnJh
+eUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxvYXQ2NEFycmF5OnRydWUsSW50MTZB
+cnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1ZSxVaW50MTZBcnJheTp0cnVlLFVp
+bnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxDYW52YXNQaXhlbEFycmF5OnRydWUs
+VWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUsSFRNTEJSRWxlbWVudDp0cnVlLEhU
+TUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6dHJ1ZSxIVE1MQ29udGVudEVsZW1l
+bnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFFbGVtZW50OnRydWUsSFRNTERhdGFM
+aXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFsb2dFbGVtZW50OnRy
+dWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRNTEZpZWxkU2V0RWxl
+bWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZGlu
+Z0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVudDp0cnVlLEhU
+TUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRydWUsSFRNTExJRWxlbWVudDp0cnVl
+LEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVudDp0cnVlLEhUTUxMaW5rRWxlbWVu
+dDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxlbWVudDp0cnVlLEhUTUxNZW51RWxl
+bWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRlckVsZW1lbnQ6dHJ1ZSxIVE1MTW9k
+RWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVudDp0cnVlLEhU
+TUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVudDp0cnVlLEhUTUxPdXRwdXRFbGVt
+ZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0dXJlRWxlbWVudDp0cnVlLEhUTUxQ
+cmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVlLEhUTUxRdW90ZUVsZW1lbnQ6dHJ1
+ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVtZW50OnRydWUsSFRNTFNsb3RFbGVt
+ZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5
+bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDZWxsRWxl
+bWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUhlYWRlckNlbGxF
+bGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhUTUxUZXh0QXJlYUVsZW1lbnQ6dHJ1
+ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50OnRydWUsSFRNTFRyYWNrRWxlbWVu
+dDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlk
+ZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1
+ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxlbWVudDp0cnVlLEhUTUxNYXJxdWVl
+RWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNob3JFbGVtZW50OnRydWUsSFRNTEFy
+ZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxvYjpmYWxzZSxIVE1MQm9keUVsZW1l
+bnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRhOnRydWUsQ29tbWVudDp0cnVlLFBy
+b2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NTdHlsZURlY2xhcmF0aW9uOnRydWUs
+TVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGllczp0cnVlLFhNTERvY3VtZW50OnRy
+dWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9NUmVjdFJlYWRPbmx5OmZhbHNlLERP
+TVRva2VuTGlzdDp0cnVlLEVsZW1lbnQ6ZmFsc2UsQWJvcnRQYXltZW50RXZlbnQ6dHJ1ZSxBbmltYXRp
+b25FdmVudDp0cnVlLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6dHJ1ZSxBcHBsaWNhdGlvbkNhY2hlRXJy
+b3JFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hF
+dmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaGVkRXZl
+bnQ6dHJ1ZSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6dHJ1ZSxCZWZvcmVVbmxvYWRFdmVudDp0cnVl
+LEJsb2JFdmVudDp0cnVlLENhbk1ha2VQYXltZW50RXZlbnQ6dHJ1ZSxDbGlwYm9hcmRFdmVudDp0cnVl
+LENsb3NlRXZlbnQ6dHJ1ZSxDdXN0b21FdmVudDp0cnVlLERldmljZU1vdGlvbkV2ZW50OnRydWUsRGV2
+aWNlT3JpZW50YXRpb25FdmVudDp0cnVlLEVycm9yRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlRXZlbnQ6dHJ1
+ZSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OnRydWUsRmV0Y2hFdmVudDp0cnVlLEZvbnRGYWNlU2V0TG9h
+ZEV2ZW50OnRydWUsRm9yZWlnbkZldGNoRXZlbnQ6dHJ1ZSxHYW1lcGFkRXZlbnQ6dHJ1ZSxIYXNoQ2hh
+bmdlRXZlbnQ6dHJ1ZSxJbnN0YWxsRXZlbnQ6dHJ1ZSxNZWRpYUVuY3J5cHRlZEV2ZW50OnRydWUsTWVk
+aWFLZXlNZXNzYWdlRXZlbnQ6dHJ1ZSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OnRydWUsTWVkaWFTdHJlYW1F
+dmVudDp0cnVlLE1lZGlhU3RyZWFtVHJhY2tFdmVudDp0cnVlLE1lc3NhZ2VFdmVudDp0cnVlLE1JRElD
+b25uZWN0aW9uRXZlbnQ6dHJ1ZSxNSURJTWVzc2FnZUV2ZW50OnRydWUsTXV0YXRpb25FdmVudDp0cnVl
+LE5vdGlmaWNhdGlvbkV2ZW50OnRydWUsUGFnZVRyYW5zaXRpb25FdmVudDp0cnVlLFBheW1lbnRSZXF1
+ZXN0RXZlbnQ6dHJ1ZSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OnRydWUsUG9wU3RhdGVFdmVudDp0
+cnVlLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDp0cnVlLFByZXNlbnRhdGlvbkNv
+bm5lY3Rpb25DbG9zZUV2ZW50OnRydWUsUHJvbWlzZVJlamVjdGlvbkV2ZW50OnRydWUsUHVzaEV2ZW50
+OnRydWUsUlRDRGF0YUNoYW5uZWxFdmVudDp0cnVlLFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6dHJ1ZSxS
+VENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OnRydWUsUlRDVHJhY2tFdmVudDp0cnVlLFNlY3VyaXR5UG9s
+aWN5VmlvbGF0aW9uRXZlbnQ6dHJ1ZSxTZW5zb3JFcnJvckV2ZW50OnRydWUsU3BlZWNoUmVjb2duaXRp
+b25FcnJvcjp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6dHJ1ZSxTcGVlY2hTeW50aGVzaXNFdmVu
+dDp0cnVlLFN0b3JhZ2VFdmVudDp0cnVlLFN5bmNFdmVudDp0cnVlLFRyYWNrRXZlbnQ6dHJ1ZSxUcmFu
+c2l0aW9uRXZlbnQ6dHJ1ZSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxWUkRldmljZUV2ZW50OnRy
+dWUsVlJEaXNwbGF5RXZlbnQ6dHJ1ZSxWUlNlc3Npb25FdmVudDp0cnVlLE1vam9JbnRlcmZhY2VSZXF1
+ZXN0RXZlbnQ6dHJ1ZSxVU0JDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6
+dHJ1ZSxBdWRpb1Byb2Nlc3NpbmdFdmVudDp0cnVlLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDp0
+cnVlLFdlYkdMQ29udGV4dEV2ZW50OnRydWUsRXZlbnQ6ZmFsc2UsSW5wdXRFdmVudDpmYWxzZSxFdmVu
+dFRhcmdldDpmYWxzZSxGaWxlOnRydWUsSFRNTEZvcm1FbGVtZW50OnRydWUsSGlzdG9yeTp0cnVlLEhU
+TUxEb2N1bWVudDp0cnVlLFhNTEh0dHBSZXF1ZXN0OnRydWUsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdl
+dDpmYWxzZSxJbWFnZURhdGE6dHJ1ZSxMb2NhdGlvbjp0cnVlLE1vdXNlRXZlbnQ6dHJ1ZSxEcmFnRXZl
+bnQ6dHJ1ZSxQb2ludGVyRXZlbnQ6dHJ1ZSxXaGVlbEV2ZW50OnRydWUsRG9jdW1lbnRGcmFnbWVudDp0
+cnVlLFNoYWRvd1Jvb3Q6dHJ1ZSxEb2N1bWVudFR5cGU6dHJ1ZSxOb2RlOmZhbHNlLE5vZGVMaXN0OnRy
+dWUsUmFkaW9Ob2RlTGlzdDp0cnVlLEhUTUxQYXJhZ3JhcGhFbGVtZW50OnRydWUsUHJvZ3Jlc3NFdmVu
+dDp0cnVlLFJlc291cmNlUHJvZ3Jlc3NFdmVudDp0cnVlLEhUTUxTZWxlY3RFbGVtZW50OnRydWUsSFRN
+TFRhYmxlRWxlbWVudDp0cnVlLEhUTUxUYWJsZVJvd0VsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVTZWN0aW9u
+RWxlbWVudDp0cnVlLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6dHJ1ZSxDb21wb3NpdGlvbkV2ZW50OnRydWUs
+Rm9jdXNFdmVudDp0cnVlLEtleWJvYXJkRXZlbnQ6dHJ1ZSxUZXh0RXZlbnQ6dHJ1ZSxUb3VjaEV2ZW50
+OnRydWUsVUlFdmVudDpmYWxzZSxXaW5kb3c6dHJ1ZSxET01XaW5kb3c6dHJ1ZSxEZWRpY2F0ZWRXb3Jr
+ZXJHbG9iYWxTY29wZTp0cnVlLFNlcnZpY2VXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFNoYXJlZFdvcmtl
+ckdsb2JhbFNjb3BlOnRydWUsV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxBdHRyOnRydWUsQ2xpZW50UmVj
+dDp0cnVlLERPTVJlY3Q6dHJ1ZSxOYW1lZE5vZGVNYXA6dHJ1ZSxNb3pOYW1lZEF0dHJNYXA6dHJ1ZSxJ
+REJLZXlSYW5nZTp0cnVlLFNWR1NjcmlwdEVsZW1lbnQ6dHJ1ZSxTVkdBRWxlbWVudDp0cnVlLFNWR0Fu
+aW1hdGVFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlVHJh
+bnNmb3JtRWxlbWVudDp0cnVlLFNWR0FuaW1hdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdDaXJjbGVFbGVtZW50
+OnRydWUsU1ZHQ2xpcFBhdGhFbGVtZW50OnRydWUsU1ZHRGVmc0VsZW1lbnQ6dHJ1ZSxTVkdEZXNjRWxl
+bWVudDp0cnVlLFNWR0Rpc2NhcmRFbGVtZW50OnRydWUsU1ZHRWxsaXBzZUVsZW1lbnQ6dHJ1ZSxTVkdG
+RUJsZW5kRWxlbWVudDp0cnVlLFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVDb21wb25l
+bnRUcmFuc2ZlckVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvc2l0ZUVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbnZv
+bHZlTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZFRGlmZnVzZUxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZF
+RGlzcGxhY2VtZW50TWFwRWxlbWVudDp0cnVlLFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDp0cnVlLFNW
+R0ZFRmxvb2RFbGVtZW50OnRydWUsU1ZHRkVGdW5jQUVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNCRWxlbWVu
+dDp0cnVlLFNWR0ZFRnVuY0dFbGVtZW50OnRydWUsU1ZHRkVGdW5jUkVsZW1lbnQ6dHJ1ZSxTVkdGRUdh
+dXNzaWFuQmx1ckVsZW1lbnQ6dHJ1ZSxTVkdGRUltYWdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VFbGVt
+ZW50OnRydWUsU1ZHRkVNZXJnZU5vZGVFbGVtZW50OnRydWUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDp0
+cnVlLFNWR0ZFT2Zmc2V0RWxlbWVudDp0cnVlLFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdG
+RVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OnRydWUsU1ZH
+RkVUaWxlRWxlbWVudDp0cnVlLFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6dHJ1ZSxTVkdGaWx0ZXJFbGVt
+ZW50OnRydWUsU1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6dHJ1ZSxTVkdHRWxlbWVudDp0cnVlLFNWR0dl
+b21ldHJ5RWxlbWVudDp0cnVlLFNWR0dyYXBoaWNzRWxlbWVudDp0cnVlLFNWR0ltYWdlRWxlbWVudDp0
+cnVlLFNWR0xpbmVFbGVtZW50OnRydWUsU1ZHTGluZWFyR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHTWFy
+a2VyRWxlbWVudDp0cnVlLFNWR01hc2tFbGVtZW50OnRydWUsU1ZHTWV0YWRhdGFFbGVtZW50OnRydWUs
+U1ZHUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdQYXR0ZXJuRWxlbWVudDp0cnVlLFNWR1BvbHlnb25FbGVtZW50
+OnRydWUsU1ZHUG9seWxpbmVFbGVtZW50OnRydWUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OnRydWUs
+U1ZHUmVjdEVsZW1lbnQ6dHJ1ZSxTVkdTZXRFbGVtZW50OnRydWUsU1ZHU3RvcEVsZW1lbnQ6dHJ1ZSxT
+VkdTdHlsZUVsZW1lbnQ6dHJ1ZSxTVkdTVkdFbGVtZW50OnRydWUsU1ZHU3dpdGNoRWxlbWVudDp0cnVl
+LFNWR1N5bWJvbEVsZW1lbnQ6dHJ1ZSxTVkdUU3BhbkVsZW1lbnQ6dHJ1ZSxTVkdUZXh0Q29udGVudEVs
+ZW1lbnQ6dHJ1ZSxTVkdUZXh0RWxlbWVudDp0cnVlLFNWR1RleHRQYXRoRWxlbWVudDp0cnVlLFNWR1Rl
+eHRQb3NpdGlvbmluZ0VsZW1lbnQ6dHJ1ZSxTVkdUaXRsZUVsZW1lbnQ6dHJ1ZSxTVkdVc2VFbGVtZW50
+OnRydWUsU1ZHVmlld0VsZW1lbnQ6dHJ1ZSxTVkdHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdDb21wb25l
+bnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDp0cnVlLFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6dHJ1ZSxT
+VkdNUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdFbGVtZW50OmZhbHNlfSkKSC5MWi4kbmF0aXZlU3VwZXJjbGFz
+c1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlJHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZl
+clZpZXciCkguVlAuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5EZy4kbmF0
+aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILldCLiRuYXRpdmVTdXBlcmNsYXNzVGFn
+PSJBcnJheUJ1ZmZlclZpZXciCkguWkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmll
+dyIKSC5QZy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3In0pKCkKY29udmVydEFs
+bFRvRmFzdE9iamVjdCh3KQpjb252ZXJ0VG9GYXN0T2JqZWN0KCQpOyhmdW5jdGlvbihhKXtpZih0eXBl
+b2YgZG9jdW1lbnQ9PT0idW5kZWZpbmVkIil7YShudWxsKQpyZXR1cm59aWYodHlwZW9mIGRvY3VtZW50
+LmN1cnJlbnRTY3JpcHQhPSd1bmRlZmluZWQnKXthKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQpCnJldHVy
+bn12YXIgdD1kb2N1bWVudC5zY3JpcHRzCmZ1bmN0aW9uIG9uTG9hZChiKXtmb3IodmFyIHI9MDtyPHQu
+bGVuZ3RoOysrcil0W3JdLnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSkKYShi
+LnRhcmdldCl9Zm9yKHZhciBzPTA7czx0Lmxlbmd0aDsrK3MpdFtzXS5hZGRFdmVudExpc3RlbmVyKCJs
+b2FkIixvbkxvYWQsZmFsc2UpfSkoZnVuY3Rpb24oYSl7di5jdXJyZW50U2NyaXB0PWEKaWYodHlwZW9m
+IGRhcnRNYWluUnVubmVyPT09ImZ1bmN0aW9uIilkYXJ0TWFpblJ1bm5lcihMLklxLFtdKQplbHNlIEwu
+SXEoW10pfSl9KSgpCi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pZ3JhdGlvbi5qcy5tYXAK
''';
diff --git a/pkg/nnbd_migration/lib/src/front_end/unit_link.dart b/pkg/nnbd_migration/lib/src/front_end/unit_link.dart
index de80deb..c5becbf 100644
--- a/pkg/nnbd_migration/lib/src/front_end/unit_link.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/unit_link.dart
@@ -4,8 +4,7 @@
/// Information about a link to a compilation unit.
class UnitLink {
- /// The relative URL of this compilation unit on the preview server.
- final String url;
+ final String fullPath;
final List<String> pathParts;
final int editCount;
@@ -14,7 +13,7 @@
/// A compilation unit in the root has a depth of 0.
final int depth;
- UnitLink(this.url, this.pathParts, this.editCount)
+ UnitLink(this.fullPath, this.pathParts, this.editCount)
: depth = pathParts.length - 1;
String get fileName => pathParts.last;
diff --git a/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
index d6653ab..66aec49 100644
--- a/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
@@ -111,6 +111,10 @@
for (var region in unitInfo.targets) {
if (region.length > 0) {
var openOffset = mapper.map(region.offset);
+ if (openOffset == null) {
+ // Region has been deleted via a hint action.
+ continue;
+ }
var openInsertion = openInsertions[openOffset] ?? '';
openInsertion = '<span id="o${region.offset}">$openInsertion';
openInsertions[openOffset] = openInsertion;
@@ -128,6 +132,10 @@
for (var region in unitInfo.sources ?? <NavigationSource>[]) {
if (region.length > 0) {
var openOffset = mapper.map(region.offset);
+ if (openOffset == null) {
+ // Region has been deleted via a hint action.
+ continue;
+ }
var target = region.target;
if (target.filePath != unitInfo.path ||
region.offset != target.offset) {
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart b/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart
index 7ae0ca8..f37aa66 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/edit_details.dart
@@ -19,8 +19,11 @@
/// The line number of the edit.
final int line;
- /// The path of the file that was edited.
- final String path;
+ /// The path of the file that was edited, to be shown to the user.
+ final String displayPath;
+
+ /// The path of the file that was edited, as a URI.
+ final String uriPath;
/// 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.
@@ -30,21 +33,24 @@
{this.edits,
@required this.explanation,
@required this.line,
- @required this.path,
+ @required this.displayPath,
+ @required this.uriPath,
this.traces = const []});
EditDetails.fromJson(dynamic json)
: edits = _decodeEdits(json['edits']),
explanation = json['explanation'] as String,
line = json['line'] as int,
- path = json['path'] as String,
+ displayPath = json['displayPath'] as String,
+ uriPath = json['uriPath'] as String,
traces = _decodeTraces(json['traces']);
Map<String, Object> toJson() => {
if (edits != null) 'edits': [for (var edit in edits) edit.toJson()],
'explanation': explanation,
'line': line,
- 'path': path,
+ 'displayPath': displayPath,
+ 'uriPath': uriPath,
if (traces != null)
'traces': [for (var trace in traces) trace.toJson()],
};
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
index 9468ead..1710839 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -158,18 +158,32 @@
});
}
-Future<HttpRequest> doGet(String path,
+/// Perform a GET request on the path, return the json decoded response.
+///
+/// Returns a T so that the various json objects can be requested (lists, maps,
+/// etc.).
+Future<T> doGet<T>(String path,
{Map<String, String> queryParameters = const {}}) =>
- HttpRequest.request(pathWithQueryParameters(path, queryParameters),
- requestHeaders: {'Content-Type': 'application/json; charset=UTF-8'});
+ doRequest(HttpRequest()
+ ..open('GET', pathWithQueryParameters(path, queryParameters), async: true)
+ ..setRequestHeader('Content-Type', 'application/json; charset=UTF-8'));
-Future<Map<String, Object>> doPost(String path, [Object body]) async {
+/// Perform a GET request on the path, return the json decoded response.
+Future<Map<String, Object>> doPost(String path, [Object body]) => doRequest(
+ HttpRequest()
+ ..open('POST', pathWithQueryParameters(path, {}), async: true)
+ ..setRequestHeader('Content-Type', 'application/json; charset=UTF-8'),
+ body);
+
+/// Execute the [HttpRequest], handle its error codes, and return or throw the
+/// response.
+///
+/// This is preferable over helper methods on [HttpRequest] because they ignore
+/// the response body on a non-200 code. We want to get that response body in
+/// that case, though, because it may be an error response from the server with
+/// useful debugging information (stack trace etc).
+Future<T> doRequest<T>(HttpRequest xhr, [Object body]) async {
var completer = new Completer<HttpRequest>();
-
- var xhr = HttpRequest()
- ..open('POST', pathWithQueryParameters(path, {}), async: true)
- ..setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
-
xhr.onLoad.listen((e) {
completer.complete(xhr);
});
@@ -178,12 +192,17 @@
xhr.send(body == null ? null : jsonEncode(body));
- await completer.future;
+ try {
+ await completer.future;
+ } catch (e, st) {
+ // Handle refused connection and make it user-presentable.
+ throw AsyncError('Error reaching migration preview server.', st);
+ }
final json = jsonDecode(xhr.responseText);
if (xhr.status == 200) {
// Request OK.
- return json as Map<String, Object>;
+ return json as T;
} else {
throw json;
}
@@ -303,10 +322,6 @@
if (path.contains('?')) {
path = path.substring(0, path.indexOf('?'));
}
- // Fix-up the path - it might be relative.
- if (relativeTo != null) {
- path = _p.normalize(_p.join(_p.dirname(relativeTo), path));
- }
var offset = getOffset(location);
var lineNumber = getLine(location);
@@ -329,23 +344,17 @@
}
/// Loads the explanation for [region], into the ".panel-content" div.
-void loadAndPopulateEditDetails(String path, int offset, int line) {
- // Request the region, then do work with the response.
- doGet(path, queryParameters: {'region': 'region', 'offset': '$offset'})
- .then((HttpRequest xhr) {
- if (xhr.status == 200) {
- var response = EditDetails.fromJson(jsonDecode(xhr.responseText));
- populateEditDetails(response);
- pushState(path, offset, line);
- addClickHandlers('.edit-panel .panel-content', false);
- } else {
- window.alert('Request failed; status of ${xhr.status}');
- }
- }).catchError((e, st) {
- logError('loadRegionExplanation: $e', st);
-
- window.alert('Could not load $path ($e).');
- });
+void loadAndPopulateEditDetails(String path, int offset, int line) async {
+ try {
+ final responseJson = await doGet<Map<String, Object>>(path,
+ queryParameters: {'region': 'region', 'offset': '$offset'});
+ var response = EditDetails.fromJson(responseJson);
+ populateEditDetails(response);
+ pushState(path, offset, line);
+ addClickHandlers('.edit-panel .panel-content', false);
+ } catch (e, st) {
+ handleError('Could not load edit details', e, st);
+ }
}
/// Load the file at [path] from the server, optionally scrolling [offset] into
@@ -356,7 +365,7 @@
int line,
bool clearEditDetails, {
VoidCallback callback,
-}) {
+}) async {
// Handle the case where we're requesting a directory.
if (!path.endsWith('.dart')) {
writeCodeAndRegions(path, FileDetails.empty(), clearEditDetails);
@@ -368,50 +377,36 @@
return;
}
- // Navigating to another file; request it, then do work with the response.
- doGet(path, queryParameters: {'inline': 'true'}).then((HttpRequest xhr) {
- if (xhr.status == 200) {
- Map<String, dynamic> response =
- jsonDecode(xhr.responseText) as Map<String, dynamic>;
- writeCodeAndRegions(
- path, FileDetails.fromJson(response), clearEditDetails);
- maybeScrollToAndHighlight(offset, line);
- var filePathPart =
- path.contains('?') ? path.substring(0, path.indexOf('?')) : path;
- updatePage(filePathPart, offset);
- if (callback != null) {
- callback();
- }
- } else {
- window.alert('Request failed; status of ${xhr.status}');
+ try {
+ // Navigating to another file; request it, then do work with the response.
+ final response = await doGet<Map<String, Object>>(path,
+ queryParameters: {'inline': 'true'});
+ writeCodeAndRegions(path, FileDetails.fromJson(response), clearEditDetails);
+ maybeScrollToAndHighlight(offset, line);
+ var filePathPart =
+ path.contains('?') ? path.substring(0, path.indexOf('?')) : path;
+ updatePage(filePathPart, offset);
+ if (callback != null) {
+ callback();
}
- }).catchError((e, st) {
- logError('loadFile: $e', st);
-
- window.alert('Could not load $path ($e).');
- });
+ } catch (e, st) {
+ handleError('Could not load dart file $path', e, st);
+ }
}
/// Load the navigation tree into the ".nav-tree" div.
-void loadNavigationTree() {
+void loadNavigationTree() async {
var path = '/_preview/navigationTree.json';
// Request the navigation tree, then do work with the response.
- doGet(path).then((HttpRequest xhr) {
- if (xhr.status == 200) {
- dynamic response = jsonDecode(xhr.responseText);
- var navTree = document.querySelector('.nav-tree');
- navTree.innerHtml = '';
- writeNavigationSubtree(
- navTree, NavigationTreeNode.listFromJson(response));
- } else {
- window.alert('Request failed; status of ${xhr.status}');
- }
- }).catchError((e, st) {
- logError('loadNavigationTree: $e', st);
-
- window.alert('Could not load $path ($e).');
- });
+ try {
+ final response = await doGet<List<Object>>(path);
+ var navTree = document.querySelector('.nav-tree');
+ navTree.innerHtml = '';
+ writeNavigationSubtree(navTree, NavigationTreeNode.listFromJson(response));
+ } catch (e, st) {
+ handleError('Could not load navigation tree', e, st);
+ }
}
void logError(e, st) {
@@ -525,19 +520,20 @@
return;
}
- var filePath = response.path;
- var parentDirectory = _p.dirname(filePath);
+ var fileDisplayPath = response.displayPath;
+ var parentDirectory = _p.dirname(fileDisplayPath);
// 'Changed ... at foo.dart:12.'
var explanationMessage = response.explanation;
- var relPath = _p.relative(filePath, from: rootPath);
+ var relPath = _p.relative(fileDisplayPath, from: rootPath);
var line = response.line;
Element explanation = document.createElement('p');
editPanel.append(explanation);
explanation
..appendText('$explanationMessage at ')
..append(AnchorElement(
- href: pathWithQueryParameters(filePath, {'line': line.toString()}))
+ href: pathWithQueryParameters(
+ response.uriPath, {'line': line.toString()}))
..appendText('$relPath:$line.'));
explanation.scrollIntoView();
_populateEditTraces(response, editPanel, parentDirectory);
@@ -707,11 +703,7 @@
var targetLine = link.line;
AnchorElement a = AnchorElement();
a.append(Text('${link.path}:$targetLine'));
-
- var relLink = link.href;
- var fullPath = _p.normalize(_p.join(parentDirectory, relLink));
-
- a.setAttribute('href', fullPath);
+ a.setAttribute('href', link.href);
a.classes.add('nav-link');
return a;
}
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index a153713..4c6112b 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -164,6 +164,11 @@
_typeProvider, constructorElement.type, _graph.never, _graph, target,
returnType: decoratedReturnType);
_variables.recordDecoratedElementType(constructorElement, functionType);
+ for (var parameter in constructorElement.parameters) {
+ var parameterType = DecoratedType.forImplicitType(
+ _typeProvider, parameter.type, _graph, target);
+ _variables.recordDecoratedElementType(parameter, parameterType);
+ }
}
return null;
}
@@ -781,11 +786,20 @@
_graph.makeNonNullableUnion(decoratedType.node,
NullabilityCommentOrigin(source, node, false));
_variables.recordNullabilityHint(source, node, hint);
+ decoratedType.node.hintActions[HintActionKind.removeNonNullableHint] =
+ hint.changesToRemove(source.contents.data);
+ decoratedType.node.hintActions[HintActionKind.changeToNullableHint] =
+ hint.changesToReplace(source.contents.data, '/*?*/');
break;
case HintCommentKind.question:
_graph.makeNullableUnion(
decoratedType.node, NullabilityCommentOrigin(source, node, true));
_variables.recordNullabilityHint(source, node, hint);
+ decoratedType.node.hintActions[HintActionKind.removeNullableHint] =
+ hint.changesToRemove(source.contents.data);
+ decoratedType
+ .node.hintActions[HintActionKind.changeToNonNullableHint] =
+ hint.changesToReplace(source.contents.data, '/*!*/');
break;
default:
break;
diff --git a/pkg/nnbd_migration/lib/src/preview/pages.dart b/pkg/nnbd_migration/lib/src/preview/pages.dart
new file mode 100644
index 0000000..29defdb
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/preview/pages.dart
@@ -0,0 +1,117 @@
+// 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 'dart:convert';
+import 'dart:io';
+
+/// An entity that knows how to serve itself over http.
+abstract class Page {
+ final StringBuffer buf = StringBuffer();
+
+ final String id;
+
+ Page(this.id);
+
+ String get path => '/$id';
+
+ Future<String> generate(Map<String, String> params) async {
+ buf.clear();
+ // TODO(brianwilkerson) Determine if await is necessary, if so, change the
+ // return type of [generatePage] to `Future<void>`.
+ await (generatePage(params) as dynamic);
+ return buf.toString();
+ }
+
+ Future<void> generatePage(Map<String, String> params);
+}
+
+/// Contains a collection of Pages.
+abstract class Site {
+ final String title;
+ final List<Page> pages = [];
+
+ Site(this.title);
+
+ Page createExceptionPage(String message, StackTrace trace);
+
+ Page createUnknownPage(String unknownPath);
+
+ Future<void> handleGetRequest(HttpRequest request) async {
+ try {
+ var path = request.uri.path;
+
+ if (path == '/') {
+ respondRedirect(request, pages.first.path);
+ return;
+ }
+
+ for (var page in pages) {
+ if (page.path == path) {
+ var response = request.response;
+ response.headers.contentType = ContentType.html;
+ response.write(await page.generate(request.uri.queryParameters));
+ response.close();
+ return;
+ }
+ }
+
+ await respond(request, createUnknownPage(path), HttpStatus.notFound);
+ } catch (e, st) {
+ try {
+ await respond(request, createExceptionPage('$e', st),
+ HttpStatus.internalServerError);
+ } catch (e, st) {
+ var response = request.response;
+ response.statusCode = HttpStatus.internalServerError;
+ response.headers.contentType = ContentType.text;
+ response.write('$e\n\n$st');
+ response.close();
+ }
+ }
+ }
+
+ Future<void> respond(
+ HttpRequest request,
+ Page page, [
+ int code = HttpStatus.ok,
+ ]) async {
+ var response = request.response;
+ response.statusCode = code;
+ response.headers.contentType = ContentType.html;
+ response.write(await page.generate(request.uri.queryParameters));
+ await response.close();
+ }
+
+ Future<void> respondJson(
+ HttpRequest request,
+ Map<String, Object> json, [
+ int code = HttpStatus.ok,
+ ]) async {
+ var response = request.response;
+ response.statusCode = code;
+ response.headers.contentType = ContentType.json;
+ response.write(jsonEncode(json));
+ await response.close();
+ }
+
+ Future<void> respondOk(
+ HttpRequest request, {
+ int code = HttpStatus.ok,
+ }) async {
+ if (request.headers.contentType.subType == 'json') {
+ return respondJson(request, {'success': true}, code);
+ }
+
+ var response = request.response;
+ response.statusCode = code;
+ await response.close();
+ }
+
+ Future<void> respondRedirect(HttpRequest request, String pathFragment) async {
+ var response = request.response;
+ response.statusCode = HttpStatus.movedTemporarily;
+ await response.redirect(request.uri.resolve(pathFragment));
+ }
+}
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_page.dart b/pkg/nnbd_migration/lib/src/preview/preview_page.dart
index 7cebe8c..23ca203 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_page.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_page.dart
@@ -4,8 +4,8 @@
import 'dart:async';
+import 'package:nnbd_migration/src/preview/pages.dart';
import 'package:nnbd_migration/src/preview/preview_site.dart';
-import 'package:analysis_server/src/status/pages.dart';
/// A page displayed on the preview site.
abstract class PreviewPage extends Page {
@@ -14,7 +14,7 @@
/// Initialize a newly created page within the given [site]. The [id] is the
/// portion of the path to the page that follows the initial slash ('/').
- PreviewPage(this.site, String id) : super(id, '', description: '');
+ PreviewPage(this.site, String id) : super(id);
/// Whether pages of this type require authorization.
bool get requiresAuth;
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index 639fa63..45d8cca 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -8,7 +8,6 @@
import 'dart:math';
import 'dart:typed_data';
-import 'package:analysis_server/src/status/pages.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:nnbd_migration/src/edit_plan.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
@@ -22,6 +21,7 @@
import 'package:nnbd_migration/src/preview/index_file_page.dart';
import 'package:nnbd_migration/src/preview/navigation_tree_page.dart';
import 'package:nnbd_migration/src/preview/not_found_page.dart';
+import 'package:nnbd_migration/src/preview/pages.dart';
import 'package:nnbd_migration/src/preview/preview_page.dart';
import 'package:nnbd_migration/src/preview/region_page.dart';
import 'package:nnbd_migration/src/preview/unauthorized_page.dart';
@@ -255,13 +255,19 @@
}
final unitInfo = unitInfoMap[path];
final diskMapper = unitInfo.diskChangesOffsetMapper;
+ final diskOffsetStart = diskMapper.map(offset);
+ final diskOffsetEnd = diskMapper.map(end);
+ if (diskOffsetStart == null || diskOffsetEnd == null) {
+ throw StateError('Cannot perform edit. Relevant code has been deleted by'
+ ' a previous hint action. Rerun the migration and try again.');
+ }
final insertionOnly = offset == end;
if (insertionOnly) {
- unitInfo.handleInsertion(offset, replacement);
+ unitInfo.handleSourceEdit(SourceEdit(offset, 0, replacement));
migrationState.needsRerun = true;
}
- var newContent = diskContent.replaceRange(
- diskMapper.map(offset), diskMapper.map(end), replacement);
+ var newContent =
+ diskContent.replaceRange(diskOffsetStart, diskOffsetEnd, replacement);
file.writeAsStringSync(newContent);
unitInfo.diskContent = newContent;
if (!insertionOnly) {
@@ -294,10 +300,16 @@
for (final entry in edits.entries) {
final offset = entry.key;
final edits = entry.value;
- final sourceEdit = edits.toSourceEdit(diskMapper.map(offset));
- // TODO(mfairhurst): handle deletions
- unitInfo.handleInsertion(sourceEdit.offset, sourceEdit.replacement);
- newContent = sourceEdit.apply(newContent);
+ final diskOffset = diskMapper.map(offset);
+ if (diskOffset == null) {
+ throw StateError(
+ 'Cannot perform edit. Relevant code has been deleted by'
+ ' a previous hint action. Rerun the migration and try again.');
+ }
+ final unmappedSourceEdit = edits.toSourceEdit(offset);
+ final diskSourceEdit = edits.toSourceEdit(diskMapper.map(offset));
+ unitInfo.handleSourceEdit(unmappedSourceEdit);
+ newContent = diskSourceEdit.apply(newContent);
}
file.writeAsStringSync(newContent);
unitInfo.diskContent = newContent;
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 72b8d29..29d4359 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -484,6 +484,37 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void>
+ test_class_alias_synthetic_constructor_with_parameters_and_subclass() async {
+ var content = '''
+void main() {
+ E e = E(null);
+}
+class C {
+ C(int i);
+}
+mixin M {}
+class D = C with M;
+class E extends D {
+ E(int i) : super(i);
+}
+''';
+ var expected = '''
+void main() {
+ E e = E(null);
+}
+class C {
+ C(int? i);
+}
+mixin M {}
+class D = C with M;
+class E extends D {
+ E(int? i) : super(i);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_class_with_default_constructor() async {
var content = '''
void main() => f(Foo());
@@ -5092,7 +5123,7 @@
class C {
final bool? x;
C.one({this.x});
- C.two({required this.x}) : assert(x != null);
+ C.two({required bool this.x}) : assert(x != null);
}
test() => C.one();
''';
@@ -6125,7 +6156,6 @@
await _checkSingleFileChanges(content, expected);
}
- @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38453')
Future<void>
test_unconditional_use_of_field_formal_param_does_not_create_hard_edge() async {
var content = '''
@@ -6140,7 +6170,28 @@
class C {
int? i;
int j;
- C.one(this.i) : j = i! + 1;
+ C.one(int this.i) : j = i + 1;
+ C.two() : i = null, j = 0;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void>
+ test_unconditional_use_of_field_formal_param_does_not_create_hard_edge_generic() async {
+ var content = '''
+class C {
+ List<int/*?*/> i;
+ int j;
+ C.one(this.i) : j = i.length;
+ C.two() : i = null, j = 0;
+}
+''';
+ var expected = '''
+class C {
+ List<int?>? i;
+ int j;
+ C.one(List<int?> this.i) : j = i.length;
C.two() : i = null, j = 0;
}
''';
diff --git a/pkg/nnbd_migration/test/fix_aggregator_test.dart b/pkg/nnbd_migration/test/fix_aggregator_test.dart
index b5927a7..b04ab18 100644
--- a/pkg/nnbd_migration/test/fix_aggregator_test.dart
+++ b/pkg/nnbd_migration/test/fix_aggregator_test.dart
@@ -956,6 +956,82 @@
''');
}
+ Future<void> test_parameter_field_formal_addExplicitType() async {
+ await analyze('''
+class C {
+ int x;
+ C(this.x) {}
+}
+''');
+ var previewInfo = run({
+ findNode.fieldFormalParameter('this.x'):
+ NodeChangeForFieldFormalParameter()
+ ..addExplicitType = nnbdTypeProvider.intType
+ });
+ expect(previewInfo.applyTo(code), '''
+class C {
+ int x;
+ C(int this.x) {}
+}
+''');
+ }
+
+ Future<void>
+ test_parameter_field_formal_addExplicitType_declared_with_final() async {
+ await analyze('''
+class C {
+ int x;
+ C(final this.x) {}
+}
+''');
+ var previewInfo = run({
+ findNode.fieldFormalParameter('this.x'):
+ NodeChangeForFieldFormalParameter()
+ ..addExplicitType = nnbdTypeProvider.intType
+ });
+ expect(previewInfo.applyTo(code), '''
+class C {
+ int x;
+ C(final int this.x) {}
+}
+''');
+ }
+
+ Future<void>
+ test_parameter_field_formal_addExplicitType_declared_with_var() async {
+ await analyze('''
+class C {
+ int x;
+ C(var this.x) {}
+}
+''');
+ var previewInfo = run({
+ findNode.fieldFormalParameter('this.x'):
+ NodeChangeForFieldFormalParameter()
+ ..addExplicitType = nnbdTypeProvider.intType
+ });
+ expect(previewInfo.applyTo(code), '''
+class C {
+ int x;
+ C(int this.x) {}
+}
+''');
+ }
+
+ Future<void> test_parameter_field_formal_addExplicitType_no() async {
+ await analyze('''
+class C {
+ int x;
+ C(this.x) {}
+}
+''');
+ var previewInfo = run({
+ findNode.fieldFormalParameter('this.x'):
+ NodeChangeForFieldFormalParameter()
+ });
+ expect(previewInfo, isNull);
+ }
+
Future<void> test_post_increment_add_null_check() async {
var content = 'f(int x) => x++;';
await analyze(content);
diff --git a/pkg/nnbd_migration/test/front_end/analysis_abstract.dart b/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
index d371a67..03f98ee 100644
--- a/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
+++ b/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
@@ -2,40 +2,15 @@
// 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:analysis_server/protocol/protocol.dart';
-import 'package:analysis_server/protocol/protocol_constants.dart';
-import 'package:analysis_server/protocol/protocol_generated.dart'
- 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/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import '../abstract_context.dart';
-import 'mocks.dart';
/// An abstract base for all 'analysis' domain tests.
class AbstractAnalysisTest extends AbstractContextTest
with ResourceProviderMixin {
bool generateSummaryFiles = false;
- MockServerChannel serverChannel;
- TestPluginManager pluginManager;
- AnalysisServer server;
- RequestHandler handler;
-
- final List<GeneralAnalysisService> generalServices =
- <GeneralAnalysisService>[];
- final Map<AnalysisService, List<String>> analysisSubscriptions = {};
-
String projectPath;
String testFolder;
String testFile;
@@ -43,41 +18,12 @@
AbstractAnalysisTest();
- AnalysisDomainHandler get analysisHandler =>
- server.handlers.singleWhere((handler) => handler is AnalysisDomainHandler)
- as AnalysisDomainHandler;
-
- AnalysisOptions get analysisOptions => testDiver.analysisOptions;
-
- AnalysisDriver get testDiver => server.getAnalysisDriver(testFile);
-
void addAnalysisOptionsFile(String content) {
newFile(
resourceProvider.pathContext.join(projectPath, 'analysis_options.yaml'),
content: content);
}
- void addAnalysisSubscription(AnalysisService service, String file) {
- // add file to subscription
- var files = analysisSubscriptions[service];
- if (files == null) {
- files = <String>[];
- analysisSubscriptions[service] = files;
- }
- files.add(file);
- // set subscriptions
- var request =
- AnalysisSetSubscriptionsParams(analysisSubscriptions).toRequest('0');
- handleSuccessfulRequest(request);
- }
-
- void addGeneralAnalysisSubscription(GeneralAnalysisService service) {
- generalServices.add(service);
- var request =
- AnalysisSetGeneralSubscriptionsParams(generalServices).toRequest('0');
- handleSuccessfulRequest(request);
- }
-
String addTestFile(String content) {
newFile(testFile, content: content);
testCode = content;
@@ -97,39 +43,9 @@
addAnalysisOptionsFile(buffer.toString());
}
- AnalysisServer createAnalysisServer() {
- //
- // Create an SDK in the mock file system.
- //
- MockSdk(
- generateSummaryFiles: generateSummaryFiles,
- resourceProvider: resourceProvider);
- //
- // Create server
- //
- var options = AnalysisServerOptions();
- return AnalysisServer(
- serverChannel,
- resourceProvider,
- options,
- DartSdkManager(resourceProvider.convertPath('/sdk'), true),
- CrashReportingAttachmentsBuilder.empty,
- InstrumentationService.NULL_SERVICE);
- }
-
/// Creates a project [projectPath].
void createProject({Map<String, String> packageRoots}) {
newFolder(projectPath);
- var request = AnalysisSetAnalysisRootsParams([projectPath], [],
- packageRoots: packageRoots)
- .toRequest('0');
- handleSuccessfulRequest(request, handler: analysisHandler);
- }
-
- void doAllDeclarationsTrackerWork() {
- while (server.declarationsTracker.hasWork) {
- server.declarationsTracker.doWork();
- }
}
/// Returns the offset of [search] in the file at the given [path].
@@ -150,71 +66,16 @@
return offset;
}
- /// Validates that the given [request] is handled successfully.
- Response handleSuccessfulRequest(Request request, {RequestHandler handler}) {
- handler ??= this.handler;
- var response = handler.handleRequest(request);
- expect(response, isResponseSuccess(request.id));
- return response;
- }
-
String modifyTestFile(String content) {
modifyFile(testFile, content);
testCode = content;
return testFile;
}
- void processNotification(Notification notification) {
- if (notification.event == SERVER_NOTIFICATION_ERROR) {
- fail('${notification.toJson()}');
- }
- }
-
- void removeGeneralAnalysisSubscription(GeneralAnalysisService service) {
- generalServices.remove(service);
- var request =
- AnalysisSetGeneralSubscriptionsParams(generalServices).toRequest('0');
- handleSuccessfulRequest(request);
- }
-
- void setPriorityFiles(List<String> files) {
- var request = AnalysisSetPriorityFilesParams(files).toRequest('0');
- handleSuccessfulRequest(request);
- }
-
void setUp() {
super.setUp();
- serverChannel = MockServerChannel();
projectPath = convertPath(AbstractContextTest.testsPath);
testFolder = convertPath('${AbstractContextTest.testsPath}/bin');
testFile = convertPath('${AbstractContextTest.testsPath}/bin/test.dart');
- pluginManager = TestPluginManager();
- server = createAnalysisServer();
- server.pluginManager = pluginManager;
- handler = analysisHandler;
- // listen for notifications
- var notificationStream = serverChannel.notificationController.stream;
- notificationStream.listen((Notification notification) {
- processNotification(notification);
- });
- }
-
- void tearDown() {
- server.done();
- handler = null;
- server = null;
- serverChannel = null;
- }
-
- /// Returns a [Future] that completes when the server's analysis is complete.
- Future waitForTasksFinished() {
- return server.onAnalysisComplete;
- }
-
- /// Completes with a successful [Response] for the given [request].
- /// Otherwise fails.
- Future<Response> waitResponse(Request request,
- {bool throwOnError = true}) async {
- return serverChannel.sendRequest(request, throwOnError: throwOnError);
}
}
diff --git a/pkg/nnbd_migration/test/front_end/info_builder_test.dart b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
index 1e1e15a..e03998a 100644
--- a/pkg/nnbd_migration/test/front_end/info_builder_test.dart
+++ b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
@@ -25,12 +25,7 @@
@reflectiveTest
class BuildEnclosingMemberDescriptionTest extends AbstractAnalysisTest {
Future<ResolvedUnitResult> resolveTestFile() async {
- var includedRoot = resourceProvider.pathContext.dirname(testFile);
- server.setAnalysisRoots('0', [includedRoot], [], {});
- return await server
- .getAnalysisDriver(testFile)
- .currentSession
- .getResolvedUnit(testFile);
+ return await session.getResolvedUnit(testFile);
}
Future<void> test_classConstructor_named() async {
@@ -1361,6 +1356,54 @@
unit.content.indexOf('i/*!*/'), 'Null check hint');
}
+ Future<void> test_trace_refers_to_variable_initializer() async {
+ var unit = await buildInfoForSingleTestFile('''
+void f(int/*?*/ i) {
+ var x = <int>[i];
+ int y = x[0];
+}
+''', migratedContent: '''
+void f(int/*?*/ i) {
+ var x = <int?>[i];
+ int? y = x[0];
+}
+''');
+ var region = unit.regions
+ .where((regionInfo) => regionInfo.offset == unit.content.indexOf('? y'))
+ .single;
+ expect(region.traces, hasLength(1));
+ var trace = region.traces.single;
+ expect(trace.description, 'Nullability reason');
+ var entries = trace.entries;
+ expect(entries, hasLength(8));
+ // Entry 0 is the nullability of y
+ assertTraceEntry(unit, entries[0], 'f.y', unit.content.indexOf('int? y'),
+ contains('f.y'));
+ // Entry 1 is the edge from the list element type of x to y, due to array
+ // indexing.
+ assertTraceEntry(unit, entries[1], 'f.y', unit.content.indexOf('x[0]'),
+ contains('data flow'));
+ // Entry 2 is the nullability of the implicit list element type of x
+ assertTraceEntry(
+ unit, entries[2], null, null, contains('type argument 0 of f.x'));
+ // Entry 3 is the edge from the explicit list element type on the RHS of x
+ // to the implicit list element type on the LHS of x
+ assertTraceEntry(unit, entries[3], 'f.x', unit.content.indexOf('<int?>[i]'),
+ contains('data flow'));
+ // Entry 4 is the explicit list element type on the RHS of x
+ assertTraceEntry(unit, entries[4], 'f.x', unit.content.indexOf('int?>[i]'),
+ contains('list element type'));
+ // Entry 5 is the edge from the parameter i to the list literal
+ assertTraceEntry(unit, entries[5], 'f.x', unit.content.indexOf('i]'),
+ contains('data flow'));
+ // Entry 6 is the nullability of the parameter i
+ assertTraceEntry(unit, entries[6], 'f', unit.content.indexOf('int/*?*/'),
+ contains('parameter 0 of f'));
+ // Entry 7 is the edge due to the explicit /*?*/ hint
+ assertTraceEntry(unit, entries[7], 'f', unit.content.indexOf('int/*?*/'),
+ contains('explicitly hinted to be nullable'));
+ }
+
Future<void> test_trace_substitutionNode() async {
var unit = await buildInfoForSingleTestFile('''
class C<T extends Object/*!*/> {}
@@ -1451,7 +1494,7 @@
expect(trace.description, 'Non-nullability reason');
var entries = trace.entries;
expect(entries, hasLength(1));
- assertTraceEntry(unit, entries[0], null, unit.content.indexOf('int'),
+ assertTraceEntry(unit, entries[0], 'i', unit.content.indexOf('int'),
'No reason found to make nullable');
expect(region.kind, NullabilityFixKind.typeNotMadeNullable);
}
diff --git a/pkg/nnbd_migration/test/front_end/migration_info_test.dart b/pkg/nnbd_migration/test/front_end/migration_info_test.dart
index 850ba40..ad989db 100644
--- a/pkg/nnbd_migration/test/front_end/migration_info_test.dart
+++ b/pkg/nnbd_migration/test/front_end/migration_info_test.dart
@@ -65,12 +65,12 @@
expect(() => unitInfo.hadDiskContent(''), throwsA(isA<AssertionError>()));
}
- void test_handleInsertion() {
+ void test_handleSourceEdit() {
final unitInfo = UnitInfo('/foo.dart');
unitInfo.content = 'int x;';
unitInfo.migrationOffsetMapper =
OffsetMapper.forEdits([SourceEdit('int'.length, 0, ' ')]);
- unitInfo.handleInsertion('int'.length, '/*?*/');
+ unitInfo.handleSourceEdit(SourceEdit('int'.length, 0, '/*?*/'));
expect(unitInfo.content, 'int/*?*/ x;');
expect(unitInfo.offsetMapper.map('in'.length), 'in'.length);
expect(unitInfo.offsetMapper.map('int'.length), 'int/*?*/'.length);
@@ -82,7 +82,27 @@
'int/*?*/ x'.length);
}
- void test_handleInsertion_regression_41894() {
+ void test_handleSourceEdit_deletion() {
+ final unitInfo = UnitInfo('/foo.dart');
+ unitInfo.content = 'int/*!*/ x = null!;';
+ unitInfo.migrationOffsetMapper =
+ OffsetMapper.forEdits([SourceEdit('int/*!*/ x = null'.length, 0, '!')]);
+ unitInfo.handleSourceEdit(SourceEdit('int'.length, '/*!*/'.length, ''));
+ expect(unitInfo.content, 'int x = null!;');
+ expect(unitInfo.offsetMapper.map('in'.length), 'in'.length);
+ expect(unitInfo.offsetMapper.map('int/*!*/ x'.length), 'int x'.length);
+ expect(unitInfo.offsetMapper.map('int/*!*/ x = null'.length),
+ 'int x = null'.length);
+ expect(unitInfo.offsetMapper.map('int/*!*/ x = null;'.length),
+ 'int x = null!;'.length);
+ expect(unitInfo.diskChangesOffsetMapper.map('in'.length), 'in'.length);
+ expect(
+ unitInfo.diskChangesOffsetMapper.map('int/*!*/'.length), 'int'.length);
+ expect(unitInfo.diskChangesOffsetMapper.map('int/*!*/ x'.length),
+ 'int x'.length);
+ }
+
+ void test_handleSourceEdit_regression_41894() {
final unitInfo = UnitInfo('/foo.dart');
unitInfo.content = 'C<C<C<T > > > x;';
unitInfo.migrationOffsetMapper = OffsetMapper.forEdits([
@@ -91,10 +111,10 @@
SourceEdit('C<C<C<T>>'.length, 0, ' '),
SourceEdit('C<C<C<T>>>'.length, 0, ' ')
]);
- unitInfo.handleInsertion('C<C<C<T'.length, '/*?*/');
- unitInfo.handleInsertion('C<C<C<T>'.length, '/*?*/');
- unitInfo.handleInsertion('C<C<C<T>>'.length, '/*?*/');
- unitInfo.handleInsertion('C<C<C<T>>>'.length, '/*?*/');
+ unitInfo.handleSourceEdit(SourceEdit('C<C<C<T'.length, 0, '/*?*/'));
+ unitInfo.handleSourceEdit(SourceEdit('C<C<C<T>'.length, 0, '/*?*/'));
+ unitInfo.handleSourceEdit(SourceEdit('C<C<C<T>>'.length, 0, '/*?*/'));
+ unitInfo.handleSourceEdit(SourceEdit('C<C<C<T>>>'.length, 0, '/*?*/'));
// Before 41894 was fixed, this would produce:
//
diff --git a/pkg/nnbd_migration/test/front_end/mocks.dart b/pkg/nnbd_migration/test/front_end/mocks.dart
index 839623c..de744b6 100644
--- a/pkg/nnbd_migration/test/front_end/mocks.dart
+++ b/pkg/nnbd_migration/test/front_end/mocks.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.
-import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:test/test.dart';
/// A [Matcher] that check that the given [Response] has an expected identifier
diff --git a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
index 264f3f9..e314cf2 100644
--- a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
@@ -2,12 +2,14 @@
// 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/file_system/memory_file_system.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/navigation_tree_renderer.dart';
import 'package:nnbd_migration/src/front_end/path_mapper.dart';
import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:path/path.dart' as path;
import 'nnbd_migration_test_base.dart';
@@ -21,6 +23,8 @@
@reflectiveTest
class NavigationTreeRendererTest extends NnbdMigrationTestBase {
+ PathMapper pathMapper;
+
/// Render the navigation tree view for [files].
Future<List<NavigationTreeNode>> renderNavigationTree(
Map<String, String> files) async {
@@ -28,8 +32,8 @@
await buildInfoForTestFiles(files, includedRoot: packageRoot);
var migrationInfo =
MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
- return NavigationTreeRenderer(migrationInfo, PathMapper(resourceProvider))
- .render();
+ pathMapper = PathMapper(resourceProvider);
+ return NavigationTreeRenderer(migrationInfo, pathMapper).render();
}
Future<void> test_containsEditCounts() async {
@@ -60,13 +64,15 @@
expect(
libNode,
isNavigationTreeNode.named('lib').havingSubtree([
- isNavigationTreeNode.named('src').havingSubtree(
- [isNavigationTreeNode.havingHref('/project/lib/src/b.dart')]),
- isNavigationTreeNode.havingHref('/project/lib/a.dart')
+ isNavigationTreeNode.named('src').havingSubtree([
+ isNavigationTreeNode.havingHref(
+ '/project/lib/src/b.dart', pathMapper)
+ ]),
+ isNavigationTreeNode.havingHref('/project/lib/a.dart', pathMapper)
]));
var toolNode = response[1];
- expect(toolNode.href, '/project/tool.dart');
+ expect(toolNode.href, pathMapper.map(convertPath('/project/tool.dart')));
}
Future<void> test_containsMultipleLinks_multipleDepths() async {
@@ -123,11 +129,11 @@
isNavigationTreeNode
.named('a.dart')
.havingPath(convertPath('lib/a.dart'))
- .havingHref('/project/lib/a.dart'),
+ .havingHref('/project/lib/a.dart', pathMapper),
isNavigationTreeNode
.named('b.dart')
.havingPath(convertPath('lib/b.dart'))
- .havingHref('/project/lib/b.dart')
+ .havingHref('/project/lib/b.dart', pathMapper)
]));
}
@@ -165,7 +171,7 @@
isNavigationTreeNode
.named('a.dart')
.havingPath(convertPath('lib/src/a.dart'))
- .havingHref('/project/lib/src/a.dart')
+ .havingHref('/project/lib/src/a.dart', pathMapper)
])
]));
}
@@ -179,7 +185,7 @@
var aNode = response[0];
expect(aNode.name, 'a.dart');
expect(aNode.path, 'a.dart');
- expect(aNode.href, '/project/a.dart');
+ expect(aNode.href, pathMapper.map(convertPath('/project/a.dart')));
}
}
@@ -193,8 +199,9 @@
TypeMatcher<NavigationTreeNode> named(dynamic matcher) =>
having((node) => node.name, 'name', matcher);
- TypeMatcher<NavigationTreeNode> havingHref(dynamic matcher) =>
- having((node) => node.href, 'href', matcher);
+ TypeMatcher<NavigationTreeNode> havingHref(
+ String path, PathMapper pathMapper) =>
+ having((node) => node.href, 'href', pathMapper.map(path));
TypeMatcher<NavigationTreeNode> havingPath(dynamic matcher) =>
having((node) => node.path, 'path', matcher);
diff --git a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
index 0fae1f0..6c1d384 100644
--- a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
+++ b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
@@ -2,12 +2,13 @@
// 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:analyzer/dart/analysis/results.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:meta/meta.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
+import 'package:nnbd_migration/src/front_end/driver_provider_impl.dart';
import 'package:nnbd_migration/src/front_end/info_builder.dart';
import 'package:nnbd_migration/src/front_end/instrumentation_listener.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
@@ -25,11 +26,6 @@
Set<UnitInfo> infos;
NodeMapper nodeMapper;
- void setUp() {
- super.setUp();
- nodeMapper = SimpleNodeMapper();
- }
-
/// Assert that some target in [targets] has various properties.
void assertInTargets(
{@required Iterable<NavigationTarget> targets,
@@ -104,12 +100,16 @@
void assertTraceEntry(UnitInfo unit, TraceEntryInfo entryInfo,
String function, int offset, Object descriptionMatcher,
{Set<HintActionKind> hintActions}) {
- assert(offset >= 0);
- var lineInfo = LineInfo.fromContent(unit.content);
- var expectedLocation = lineInfo.getLocation(offset);
- expect(entryInfo.target.filePath, unit.path);
- expect(entryInfo.target.line, expectedLocation.lineNumber);
- expect(unit.offsetMapper.map(entryInfo.target.offset), offset);
+ if (offset == null) {
+ expect(entryInfo.target, isNull);
+ } else {
+ assert(offset >= 0);
+ var lineInfo = LineInfo.fromContent(unit.content);
+ var expectedLocation = lineInfo.getLocation(offset);
+ expect(entryInfo.target.filePath, unit.path);
+ expect(entryInfo.target.line, expectedLocation.lineNumber);
+ expect(unit.offsetMapper.map(entryInfo.target.offset), offset);
+ }
expect(entryInfo.function, function);
expect(entryInfo.description, descriptionMatcher);
if (hintActions != null) {
@@ -187,6 +187,11 @@
return filteredInfos;
}
+ void setUp() {
+ super.setUp();
+ nodeMapper = SimpleNodeMapper();
+ }
+
/// Uses the InfoBuilder to build information for files at [testPaths], which
/// should all share a common parent directory, [includedRoot].
Future<void> _buildMigrationInfo(List<String> testPaths,
@@ -194,7 +199,7 @@
bool removeViaComments = true,
bool warnOnWeakCode = false}) async {
// Compute the analysis results.
- server.setAnalysisRoots('0', [includedRoot], [], {});
+ var server = DriverProviderImpl(resourceProvider, driver.analysisContext);
// Run the migration engine.
var listener = DartFixListener(server);
var instrumentationListener = InstrumentationListener();
@@ -207,10 +212,7 @@
Future<void> _forEachPath(
void Function(ResolvedUnitResult) callback) async {
for (var testPath in testPaths) {
- var result = await server
- .getAnalysisDriver(testPath)
- .currentSession
- .getResolvedUnit(testPath);
+ var result = await driver.currentSession.getResolvedUnit(testPath);
callback(result);
}
}
diff --git a/pkg/nnbd_migration/test/front_end/offset_mapper_test.dart b/pkg/nnbd_migration/test/front_end/offset_mapper_test.dart
index 7bacfd2..0112108 100644
--- a/pkg/nnbd_migration/test/front_end/offset_mapper_test.dart
+++ b/pkg/nnbd_migration/test/front_end/offset_mapper_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.
-import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -49,6 +49,33 @@
expect(mapper.map(55), 58);
}
+ void test_rebase_deletionRebasingInsertion() {
+ var mapper = OffsetMapper.rebase(OffsetMapper.forReplacement(5, 2, ''),
+ OffsetMapper.forInsertion(10, 5));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(4), 4);
+ expect(mapper.map(5), null);
+ expect(mapper.map(6), null);
+ expect(mapper.map(7), 5);
+ expect(mapper.map(8), 6);
+ expect(mapper.map(11), 14);
+ expect(mapper.map(12), 15);
+ }
+
+ void test_rebase_insertionRebasingDeletion() {
+ var mapper = OffsetMapper.rebase(OffsetMapper.forInsertion(5, 5),
+ OffsetMapper.forReplacement(10, 5, ''));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(4), 4);
+ expect(mapper.map(5), 10);
+ expect(mapper.map(6), 11);
+ expect(mapper.map(9), 14);
+ expect(mapper.map(10), null);
+ expect(mapper.map(14), null);
+ expect(mapper.map(15), 15);
+ expect(mapper.map(16), 16);
+ }
+
void test_rebase_insertMapper() {
var mapper = OffsetMapper.rebase(
OffsetMapper.forInsertion(5, 5), OffsetMapper.forInsertion(10, 5));
@@ -62,6 +89,36 @@
expect(mapper.map(12), 22);
}
+ void test_replacementMapper_effectivelyDeletes() {
+ var mapper = OffsetMapper.forReplacement(10, 5, '');
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), null);
+ expect(mapper.map(11), null);
+ expect(mapper.map(14), null);
+ expect(mapper.map(15), 10);
+ }
+
+ void test_replacementMapper_effectivelyDeletesAndInserts() {
+ var mapper = OffsetMapper.forReplacement(10, 5, 'foo');
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), null);
+ expect(mapper.map(11), null);
+ expect(mapper.map(14), null);
+ expect(mapper.map(15), 13);
+ expect(mapper.map(16), 14);
+ }
+
+ void test_replacementMapper_effectivelyInserts() {
+ var mapper = OffsetMapper.forReplacement(10, 0, 'five ');
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), 15);
+ expect(mapper.map(11), 16);
+ expect(mapper.map(20), 25);
+ }
+
void test_sequence_insertMappers() {
var mapper = OffsetMapper.sequence(
OffsetMapper.forInsertion(30, 10), OffsetMapper.forInsertion(10, 10));
@@ -98,6 +155,106 @@
expect(mapper.map(20), 35);
}
+ void test_sequence_replacementMappers_deleteAmidInsert() {
+ // Deleting in the middle of an insertion is equivalent to originally making
+ // a smaller insertion.
+ var mapper = OffsetMapper.sequence(
+ OffsetMapper.forReplacement(10, 0, 'five '),
+ OffsetMapper.forReplacement(12, 3, ''));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), 12);
+ expect(mapper.map(11), 13);
+ }
+
+ void test_sequence_replacementMappers_deleteAroundInsert() {
+ // Deleting around an insertion is equivalent to originally making a smaller
+ // deletion.
+ var mapper = OffsetMapper.sequence(
+ OffsetMapper.forReplacement(15, 0, 'five '),
+ OffsetMapper.forReplacement(10, 15, ''));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), null);
+ expect(mapper.map(11), null);
+ expect(mapper.map(19), null);
+ expect(mapper.map(20), 10);
+ expect(mapper.map(21), 11);
+ }
+
+ void test_sequence_replacementMappers_deleteIntoInsert() {
+ // A deletion starting before an insertion that goes into the middle of an
+ // insertion is equivalent to a smaller deletion + a smaller insertion.
+ var mapper = OffsetMapper.sequence(
+ OffsetMapper.forReplacement(10, 0, 'five '),
+ OffsetMapper.forReplacement(5, 7, ''));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(4), 4);
+ expect(mapper.map(5), null);
+ expect(mapper.map(6), null);
+ expect(mapper.map(10), 8);
+ expect(mapper.map(11), 9);
+ }
+
+ void test_sequence_replacementMappers_deletePastInsert() {
+ // A deletion starting in the middle of an insertion that goes past the end
+ // is equivalent to a smaller insertion + a smaller deletion.
+ var mapper = OffsetMapper.sequence(
+ OffsetMapper.forReplacement(10, 0, 'five '),
+ OffsetMapper.forReplacement(12, 10, ''));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), null);
+ expect(mapper.map(11), null);
+ expect(mapper.map(16), null);
+ expect(mapper.map(17), 12);
+ expect(mapper.map(18), 13);
+ }
+
+ void test_sequence_replacementMappers_insertAmidDeletion() {
+ // Inserting at a deletion offset is equivalent to inserting after the
+ // deletion.
+ var mapper = OffsetMapper.sequence(OffsetMapper.forReplacement(10, 5, ''),
+ OffsetMapper.forReplacement(10, 0, 'foo'));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), null);
+ expect(mapper.map(11), null);
+ expect(mapper.map(14), null);
+ expect(mapper.map(15), 13);
+ expect(mapper.map(16), 14);
+ }
+
+ void test_sequence_replacementMappers_twoDeletions_consecutive() {
+ var mapper = OffsetMapper.sequence(OffsetMapper.forReplacement(10, 5, ''),
+ OffsetMapper.forReplacement(10, 5, ''));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), null);
+ expect(mapper.map(11), null);
+ expect(mapper.map(19), null);
+ expect(mapper.map(20), 10);
+ expect(mapper.map(21), 11);
+ }
+
+ void test_sequence_replacementMappers_twoDeletions_separate() {
+ var mapper = OffsetMapper.sequence(OffsetMapper.forReplacement(10, 5, ''),
+ OffsetMapper.forReplacement(15, 5, ''));
+ expect(mapper.map(0), 0);
+ expect(mapper.map(9), 9);
+ expect(mapper.map(10), null);
+ expect(mapper.map(11), null);
+ expect(mapper.map(14), null);
+ expect(mapper.map(15), 10);
+ expect(mapper.map(16), 11);
+ expect(mapper.map(19), 14);
+ expect(mapper.map(20), null);
+ expect(mapper.map(21), null);
+ expect(mapper.map(24), null);
+ expect(mapper.map(25), 15);
+ expect(mapper.map(26), 16);
+ }
+
void test_singleEdit() {
var mapper = OffsetMapper.forEdits([
SourceEdit(13, 0, '?'),
diff --git a/pkg/nnbd_migration/test/front_end/region_renderer_test.dart b/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
index 934614a..88307a0 100644
--- a/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
@@ -20,6 +20,8 @@
@reflectiveTest
class RegionRendererTest extends NnbdMigrationTestBase {
+ PathMapper pathMapper;
+
/// Render the region at [offset], using a [MigrationInfo] which knows only
/// about the library at `infos.single`.
EditDetails renderRegion(int offset) {
@@ -28,9 +30,8 @@
MigrationInfo(infos, {}, resourceProvider.pathContext, packageRoot);
var unitInfo = infos.single;
var region = unitInfo.regionAt(offset);
- return RegionRenderer(
- region, unitInfo, migrationInfo, PathMapper(resourceProvider))
- .render();
+ pathMapper = PathMapper(resourceProvider);
+ return RegionRenderer(region, unitInfo, migrationInfo, pathMapper).render();
}
Future<void> test_modifiedOutput_containsExplanation() async {
@@ -44,8 +45,12 @@
await buildInfoForSingleTestFile('int a = null;',
migratedContent: 'int? a = null;');
var response = renderRegion(3);
- expect(response.path,
+ expect(response.displayPath,
equals(convertPath('${AbstractContextTest.testsPath}/bin/test.dart')));
+ expect(
+ response.uriPath,
+ equals(pathMapper.map(
+ convertPath('${AbstractContextTest.testsPath}/bin/test.dart'))));
expect(response.line, equals(1));
}
@@ -60,8 +65,12 @@
await buildInfoForSingleTestFile('f(int a) => a.isEven;',
migratedContent: 'f(int a) => a.isEven;');
var response = renderRegion(5);
- expect(response.path,
+ expect(response.displayPath,
equals(convertPath('${AbstractContextTest.testsPath}/bin/test.dart')));
+ expect(
+ response.uriPath,
+ equals(pathMapper.map(
+ convertPath('${AbstractContextTest.testsPath}/bin/test.dart'))));
expect(response.line, equals(1));
}
}
diff --git a/pkg/nnbd_migration/test/isolate_server_test.dart b/pkg/nnbd_migration/test/isolate_server_test.dart
deleted file mode 100644
index c352204..0000000
--- a/pkg/nnbd_migration/test/isolate_server_test.dart
+++ /dev/null
@@ -1,264 +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';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:isolate';
-
-import 'package:analysis_server_client/protocol.dart';
-import 'package:async/src/stream_sink_transformer.dart';
-import 'package:nnbd_migration/isolate_server.dart';
-import 'package:stream_channel/isolate_channel.dart';
-import 'package:stream_channel/src/stream_channel_transformer.dart';
-import 'package:stream_channel/stream_channel.dart';
-import 'package:test/test.dart';
-
-void main() {
- FakeIsolate isolate;
- FakeIsolateChannel isolateChannel;
- Server server;
-
- setUp(() async {
- isolate = FakeIsolate();
- isolateChannel = FakeIsolateChannel();
- server = Server(isolate: isolate, isolateChannel: isolateChannel);
- });
-
- group('listenToOutput', () {
- test('good', () async {
- isolateChannel.stream = _goodMessage();
-
- final future = server.send('blahMethod', null);
- server.listenToOutput();
-
- final response = await future;
- expect(response['foo'], 'bar');
- });
-
- test('error', () async {
- isolateChannel.stream = _badMessage();
-
- final future = server.send('blahMethod', null);
- future.catchError((e) {
- expect(e, const TypeMatcher<RequestError>());
- final error = e as RequestError;
- expect(error.code, RequestErrorCode.UNKNOWN_REQUEST);
- expect(error.message, 'something went wrong');
- expect(error.stackTrace, 'some long stack trace');
- });
- server.listenToOutput();
- });
-
- test('event', () async {
- isolateChannel.stream = _eventMessage();
-
- final completer = Completer();
- void eventHandler(Notification notification) {
- expect(notification.event, 'fooEvent');
- expect(notification.params.length, 2);
- expect(notification.params['foo'] as String, 'bar');
- expect(notification.params['baz'] as String, 'bang');
- completer.complete();
- }
-
- server.send('blahMethod', null);
- server.listenToOutput(notificationProcessor: eventHandler);
- await completer.future;
- });
- });
-
- group('stop', () {
- test('ok', () async {
- final fakeOut = StreamController<List<int>>();
- isolateChannel.stream = fakeOut.stream;
- // ignore: unawaited_futures
- isolateChannel.fakeIn.controller.stream.first.then((_) {
- var encoded = json.encode({'id': '0'});
- fakeOut.add(utf8.encoder.convert('$encoded\n'));
- });
- server.isolateExited.complete();
- server.listenToOutput();
- await server.stop(timeLimit: const Duration(milliseconds: 1));
- expect(isolate.killed, isFalse);
- });
- test('stopped', () async {
- final fakeOut = StreamController<List<int>>();
- isolateChannel.stream = fakeOut.stream;
-
- server.isolateExited.complete();
- server.listenToOutput();
- await server.stop(timeLimit: const Duration(milliseconds: 1));
- expect(isolate.killed, isFalse);
- });
- test('kill', () async {
- final fakeOut = StreamController<List<int>>();
- isolateChannel.stream = fakeOut.stream;
-
- server.listenToOutput();
- await server.stop(timeLimit: const Duration(milliseconds: 10));
- expect(isolate.killed, isTrue);
- });
- });
-}
-
-final _badErrorMessage = {
- 'code': 'UNKNOWN_REQUEST',
- 'message': 'something went wrong',
- 'stackTrace': 'some long stack trace'
-};
-
-Stream<List<int>> _badMessage() async* {
- yield utf8.encoder.convert('Observatory listening on foo bar\n');
- final sampleJson = {
- 'id': '0',
- 'error': _badErrorMessage,
- };
- yield utf8.encoder.convert(json.encode(sampleJson));
-}
-
-Stream<List<int>> _eventMessage() async* {
- yield utf8.encoder.convert('Observatory listening on foo bar\n');
- final sampleJson = {
- 'event': 'fooEvent',
- 'params': {'foo': 'bar', 'baz': 'bang'}
- };
- yield utf8.encoder.convert(json.encode(sampleJson));
-}
-
-Stream<List<int>> _goodMessage() async* {
- yield utf8.encoder.convert('Observatory listening on foo bar\n');
- final sampleJson = {
- 'id': '0',
- 'result': {'foo': 'bar'}
- };
- yield utf8.encoder.convert(json.encode(sampleJson));
-}
-
-class FakeIsolate implements Isolate {
- bool killed = false;
-
- @override
- void addErrorListener(SendPort port) => throw UnimplementedError();
-
- @override
- void addOnExitListener(SendPort port, {Object response}) =>
- throw UnimplementedError();
-
- @override
- SendPort get controlPort => throw UnimplementedError();
-
- @override
- String get debugName => throw UnimplementedError();
-
- @override
- Stream get errors => throw UnimplementedError();
-
- @override
- Capability get pauseCapability => throw UnimplementedError();
-
- @override
- void ping(SendPort port,
- {Object response, int priority = Isolate.immediate}) =>
- throw UnimplementedError();
-
- @override
- void removeErrorListener(SendPort port) => throw UnimplementedError();
-
- @override
- void removeOnExitListener(SendPort port) => throw UnimplementedError();
-
- @override
- void resume(Capability capability) => throw UnimplementedError();
-
- @override
- Capability get terminateCapability => throw UnimplementedError();
-
- @override
- void kill({int priority = Isolate.beforeNextEvent}) {
- killed = true;
- }
-
- @override
- Capability pause([Capability resumeCapability]) => throw UnimplementedError();
-
- @override
- void setErrorsFatal(bool errorsAreFatal) => throw UnimplementedError();
-}
-
-class FakeIsolateChannel<T> implements IsolateChannel<T> {
- FakeIsolateInput fakeIn = FakeIsolateInput();
-
- @override
- StreamChannel<S> cast<S>() => throw UnimplementedError();
-
- @override
- StreamChannel<T> changeSink(
- StreamSink<T> Function(StreamSink<T> sink) change) =>
- throw UnimplementedError();
-
- @override
- StreamChannel<T> changeStream(Stream<T> Function(Stream<T> stream) change) =>
- throw UnimplementedError();
-
- @override
- void pipe(StreamChannel<T> other) => throw UnimplementedError();
-
- @override
- StreamSink<T> get sink => fakeIn as StreamSink<T>;
-
- @override
- Stream<T> stream;
-
- @override
- StreamChannel<S> transform<S>(StreamChannelTransformer<S, T> transformer) =>
- throw UnimplementedError();
-
- @override
- StreamChannel<T> transformSink(StreamSinkTransformer<T, T> transformer) =>
- throw UnimplementedError();
-
- @override
- StreamChannel<T> transformStream(StreamTransformer<T, T> transformer) =>
- throw UnimplementedError();
-}
-
-class FakeIsolateInput implements IOSink {
- final controller = StreamController<String>();
-
- @override
- Encoding encoding;
-
- @override
- Future get done => null;
-
- @override
- void add(List<int> data) {
- controller.add(utf8.decode(data));
- }
-
- @override
- void addError(Object error, [StackTrace stackTrace]) {}
-
- @override
- Future addStream(Stream<List<int>> stream) => null;
-
- @override
- Future close() => null;
-
- @override
- Future flush() => null;
-
- @override
- void write(Object obj) {}
-
- @override
- void writeAll(Iterable objects, [String separator = '']) {}
-
- @override
- void writeCharCode(int charCode) {}
-
- @override
- void writeln([Object obj = '']) {}
-}
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 1fad3f8..4bc0b9d 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -15,6 +15,8 @@
import 'package:meta/meta.dart';
import 'package:nnbd_migration/migration_cli.dart';
import 'package:nnbd_migration/src/front_end/non_nullable_fix.dart';
+import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
+import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -404,6 +406,47 @@
});
}
+ test_lifecycle_preview_region_link() async {
+ var projectContents = simpleProject(sourceText: 'int x;');
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await runWithPreviewServer(cli, [projectDir], (url) async {
+ expect(
+ logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+ await assertPreviewServerResponsive(url);
+ var uri = Uri.parse(url);
+ var authToken = uri.queryParameters['authToken'];
+ var regionResponse = await http.get(
+ uri.replace(
+ path: resourceProvider.pathContext
+ .toUri(resourceProvider.pathContext
+ .join(projectDir, 'lib', 'test.dart'))
+ .path,
+ queryParameters: {
+ 'region': 'region',
+ 'offset': '3',
+ 'authToken': authToken
+ }),
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ var regionJson = EditDetails.fromJson(jsonDecode(regionResponse.body));
+ final displayPath = regionJson.displayPath;
+ final uriPath = regionJson.uriPath;
+ // uriPath should be a working URI
+ final contentsResponse = await http.get(
+ uri.replace(
+ path: uriPath,
+ queryParameters: {'inline': 'true', 'authToken': authToken}),
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ assertHttpSuccess(contentsResponse);
+
+ // Display path should be the actual windows path
+ final file = resourceProvider
+ .getFolder(projectDir)
+ .getChildAssumingFile(displayPath);
+ expect(file.exists, isTrue);
+ });
+ }
+
test_lifecycle_preview_rerun() async {
var origSourceText = 'void f() {}';
var projectContents = simpleProject(sourceText: origSourceText);
@@ -554,6 +597,75 @@
});
}
+ test_lifecycle_preview_stacktrace_link() async {
+ var projectContents = simpleProject(sourceText: 'int x;');
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await runWithPreviewServer(cli, [projectDir], (url) async {
+ expect(
+ logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+ await assertPreviewServerResponsive(url);
+ var uri = Uri.parse(url);
+ var authToken = uri.queryParameters['authToken'];
+ var regionUri = uri.replace(
+ path: resourceProvider.pathContext
+ .toUri(resourceProvider.pathContext
+ .join(projectDir, 'lib', 'test.dart'))
+ .path,
+ queryParameters: {
+ 'region': 'region',
+ 'offset': '3',
+ 'authToken': authToken
+ });
+ var regionResponse = await http.get(regionUri,
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ var regionJson = EditDetails.fromJson(jsonDecode(regionResponse.body));
+ final traceEntry = regionJson.traces[0].entries[0];
+ final displayPath = traceEntry.link.path;
+ final uriPath = traceEntry.link.href;
+ // uriPath should be a working URI
+ final contentsResponse = await http.get(
+ regionUri
+ .resolve(uriPath)
+ .replace(queryParameters: {'authToken': authToken}),
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ assertHttpSuccess(contentsResponse);
+ });
+ }
+
+ test_lifecycle_preview_navigation_tree() async {
+ var projectContents = simpleProject(sourceText: 'int x;');
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await runWithPreviewServer(cli, [projectDir], (url) async {
+ expect(
+ logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+ await assertPreviewServerResponsive(url);
+ var uri = Uri.parse(url);
+ var authToken = uri.queryParameters['authToken'];
+ var treeResponse = await http.get(
+ uri.replace(
+ path: '/_preview/navigationTree.json',
+ queryParameters: {'authToken': authToken}),
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ var navRoots = jsonDecode(treeResponse.body);
+ for (final root in navRoots) {
+ var navTree = NavigationTreeNode.fromJson(root);
+ for (final file in navTree.subtree) {
+ if (file.href != null) {
+ print(file.href);
+ final contentsResponse = await http.get(
+ uri
+ .resolve(file.href)
+ .replace(queryParameters: {'authToken': authToken}),
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ assertHttpSuccess(contentsResponse);
+ }
+ }
+ }
+ });
+ }
+
test_lifecycle_summary() async {
var projectContents = simpleProject();
var projectDir = await createProjectDir(projectContents);
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index 4a6b32b..9abb1b4 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -674,9 +674,7 @@
class A extends Object {}
''');
final node = decoratedTypeAnnotation('Object').node;
- expect(
- node.hintActions, isNot(contains(HintActionKind.addNonNullableHint)));
- expect(node.hintActions, isNot(contains(HintActionKind.addNullableHint)));
+ expect(node.hintActions, isEmpty);
}
Future<void> test_field_type_implicit_dynamic() async {
@@ -1243,9 +1241,7 @@
.declaredElement)
.typeArguments[0]
.node;
- expect(
- node.hintActions, isNot(contains(HintActionKind.addNonNullableHint)));
- expect(node.hintActions, isNot(contains(HintActionKind.addNullableHint)));
+ expect(node.hintActions, isEmpty);
}
Future<void> test_implicit_type_no_add_hint_actions() async {
@@ -1259,9 +1255,7 @@
.variables[0]
.declaredElement)
.node;
- expect(
- node.hintActions, isNot(contains(HintActionKind.addNonNullableHint)));
- expect(node.hintActions, isNot(contains(HintActionKind.addNullableHint)));
+ expect(node.hintActions, isEmpty);
}
Future<void> test_interfaceType_generic_instantiate_to_dynamic() async {
@@ -1823,8 +1817,20 @@
expect(
node.hintActions, isNot(contains(HintActionKind.addNonNullableHint)));
expect(node.hintActions, isNot(contains(HintActionKind.addNullableHint)));
- // TODO(mfairhurst): support 'change to null hint'/'remove non-null hint'
- // Filed as dartbug.com/41857, dartbug.com/41858
+ expect(node.hintActions,
+ isNot(contains(HintActionKind.changeToNonNullableHint)));
+ expect(
+ node.hintActions[HintActionKind.removeNonNullableHint]
+ .applyTo(super.testCode),
+ '''
+void f(int i) {}
+''');
+ expect(
+ node.hintActions[HintActionKind.changeToNullableHint]
+ .applyTo(super.testCode),
+ '''
+void f(int/*?*/ i) {}
+''');
}
Future<void> test_type_comment_question() async {
@@ -1836,8 +1842,20 @@
expect(
node.hintActions, isNot(contains(HintActionKind.addNonNullableHint)));
expect(node.hintActions, isNot(contains(HintActionKind.addNullableHint)));
- // TODO(mfairhurst): support 'change to non-null hint'/'remove null hint'
- // Filed as dartbug.com/41857, dartbug.com/41858
+ expect(
+ node.hintActions, isNot(contains(HintActionKind.changeToNullableHint)));
+ expect(
+ node.hintActions[HintActionKind.removeNullableHint]
+ .applyTo(super.testCode),
+ '''
+void f(int i) {}
+''');
+ expect(
+ node.hintActions[HintActionKind.changeToNonNullableHint]
+ .applyTo(super.testCode),
+ '''
+void f(int/*!*/ i) {}
+''');
}
Future<void> test_type_nested_add_non_null_hint() async {
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index 0ea2029..7aeda69 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -2,11 +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 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide NavigationTarget;
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/migration_state.dart';
import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
@@ -56,13 +57,11 @@
file.writeAsStringSync(content);
site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
// Add a source change for analysis_options, which has no UnitInfo.
- dartfixListener.addSourceChange(
+ dartfixListener.addSourceFileEdit(
'enable experiment',
Location(analysisOptionsPath, 9, 0, 1, 9),
- SourceChange('enable experiment', edits: [
- SourceFileEdit(analysisOptionsPath, 0, edits: [
- SourceEdit(9, 0, '\n enable-experiment:\n - non-nullable')
- ])
+ SourceFileEdit(analysisOptionsPath, 0, edits: [
+ SourceEdit(9, 0, '\n enable-experiment:\n - non-nullable')
]));
// This should not crash.
site.performApply();
@@ -93,12 +92,10 @@
..diskContent = '// different content';
final currentContent = 'void main() {}';
file.writeAsStringSync(currentContent);
- dartfixListener.addSourceChange(
+ dartfixListener.addSourceFileEdit(
'test change',
Location(path, 10, 0, 1, 10),
- SourceChange('test change', edits: [
- SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')])
- ]));
+ SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
expect(() => site.performApply(), throwsA(isA<StateError>()));
expect(file.readAsStringSync(), currentContent);
expect(state.hasBeenApplied, false);
@@ -110,14 +107,12 @@
final content = 'void main() {}';
file.writeAsStringSync(content);
site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
- dartfixListener.addSourceChange(
+ dartfixListener.addSourceFileEdit(
'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')
- ])
+ SourceFileEdit(path, 0, edits: [
+ SourceEdit(10, 0, 'List args'),
+ SourceEdit(13, 0, '\n print(args);\n')
]));
site.performApply();
expect(file.readAsStringSync(), '''
@@ -133,12 +128,10 @@
final content = 'void main() {}';
file.writeAsStringSync(content);
site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
- dartfixListener.addSourceChange(
+ dartfixListener.addSourceFileEdit(
'test change',
Location(path, 10, 0, 1, 10),
- SourceChange('test change', edits: [
- SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')])
- ]));
+ SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
site.performApply();
expect(file.readAsStringSync(), 'void main(List args) {}');
expect(state.hasBeenApplied, true);
@@ -204,55 +197,6 @@
});
}
- void test_performEdit_multiple() async {
- final path = convertPath('/test.dart');
- final file = getFile(path);
- final content = r'''
-int x;
-int y = x;
-''';
- file.writeAsStringSync(content);
- final migratedContent = '''
-int? x;
-int? y = x;
-''';
- final unitInfo = await buildInfoForSingleTestFile(content,
- migratedContent: migratedContent);
- site.unitInfoMap[path] = unitInfo;
- final firstEditOffset = unitInfo.regions[0].edits[0].offset;
- performEdit(path, firstEditOffset, '/*?*/');
- final secondEditOffset = unitInfo.regions[1].edits[0].offset;
- performEdit(path, secondEditOffset, '/*?*/');
- expect(file.readAsStringSync(), '''
-int/*?*/ x;
-int/*?*/ y = x;
-''');
- expect(unitInfo.content, '''
-int/*?*/? x;
-int/*?*/? y = x;
-''');
- assertRegion(
- region: unitInfo.regions[0], offset: unitInfo.content.indexOf('? x'));
- assertRegion(
- region: unitInfo.regions[1], offset: unitInfo.content.indexOf('? y'));
- final targets = List<NavigationTarget>.from(unitInfo.targets);
- assertInTargets(
- targets: targets,
- offset: unitInfo.content.indexOf('x'),
- offsetMapper: unitInfo.offsetMapper);
- assertInTargets(
- targets: targets,
- offset: unitInfo.content.indexOf('y'),
- offsetMapper: unitInfo.offsetMapper);
- var trace = unitInfo.regions[1].traces[0];
- assertTraceEntry(unitInfo, trace.entries[0], null,
- unitInfo.content.indexOf('int/*?*/? y'), contains('y (test.dart:2:1)'));
- assertTraceEntry(unitInfo, trace.entries[1], 'y',
- unitInfo.content.indexOf('= x;') + '= '.length, contains('data flow'));
- expect(state.hasBeenApplied, false);
- expect(state.needsRerun, true);
- }
-
void test_applyHintAction() async {
final path = convertPath('/home/tests/bin/test.dart');
final file = getFile(path);
@@ -294,11 +238,99 @@
offset: unitInfo.content.indexOf('y'),
offsetMapper: unitInfo.offsetMapper);
var trace = unitInfo.regions[1].traces[0];
- assertTraceEntry(unitInfo, trace.entries[0], null,
+ assertTraceEntry(unitInfo, trace.entries[0], 'y',
unitInfo.content.indexOf('int/*?*/? y'), contains('y (test.dart:2:1)'));
assertTraceEntry(unitInfo, trace.entries[1], 'y',
unitInfo.content.indexOf('= x;') + '= '.length, contains('data flow'));
expect(state.hasBeenApplied, false);
expect(state.needsRerun, true);
}
+
+ void test_performEdit_multiple() async {
+ final path = convertPath('/test.dart');
+ final file = getFile(path);
+ final content = r'''
+int x;
+int y = x;
+''';
+ file.writeAsStringSync(content);
+ final migratedContent = '''
+int? x;
+int? y = x;
+''';
+ final unitInfo = await buildInfoForSingleTestFile(content,
+ migratedContent: migratedContent);
+ site.unitInfoMap[path] = unitInfo;
+ final firstEditOffset = unitInfo.regions[0].edits[0].offset;
+ performEdit(path, firstEditOffset, '/*?*/');
+ final secondEditOffset = unitInfo.regions[1].edits[0].offset;
+ performEdit(path, secondEditOffset, '/*?*/');
+ expect(file.readAsStringSync(), '''
+int/*?*/ x;
+int/*?*/ y = x;
+''');
+ expect(unitInfo.content, '''
+int/*?*/? x;
+int/*?*/? y = x;
+''');
+ assertRegion(
+ region: unitInfo.regions[0], offset: unitInfo.content.indexOf('? x'));
+ assertRegion(
+ region: unitInfo.regions[1], offset: unitInfo.content.indexOf('? y'));
+ final targets = List<NavigationTarget>.from(unitInfo.targets);
+ assertInTargets(
+ targets: targets,
+ offset: unitInfo.content.indexOf('x'),
+ offsetMapper: unitInfo.offsetMapper);
+ assertInTargets(
+ targets: targets,
+ offset: unitInfo.content.indexOf('y'),
+ offsetMapper: unitInfo.offsetMapper);
+ var trace = unitInfo.regions[1].traces[0];
+ assertTraceEntry(unitInfo, trace.entries[0], 'y',
+ unitInfo.content.indexOf('int/*?*/? y'), contains('y (test.dart:2:1)'));
+ assertTraceEntry(unitInfo, trace.entries[1], 'y',
+ unitInfo.content.indexOf('= x;') + '= '.length, contains('data flow'));
+ expect(state.hasBeenApplied, false);
+ expect(state.needsRerun, true);
+ }
+
+ void test_applyHintAction_removeHint() async {
+ final path = convertPath('/home/tests/bin/test.dart');
+ final file = getFile(path);
+ final content = r'''
+int/*!*/ x;
+int y = x;
+''';
+ file.writeAsStringSync(content);
+ final migratedContent = '''
+int/*!*/ x;
+int y = x;
+''';
+ final unitInfo = await buildInfoForSingleTestFile(content,
+ migratedContent: migratedContent);
+ site.unitInfoMap[path] = unitInfo;
+ await site.performHintAction(
+ unitInfo.regions[0].traces[0].entries[0].hintActions[0]);
+ expect(file.readAsStringSync(), '''
+int x;
+int y = x;
+''');
+ expect(unitInfo.content, '''
+int x;
+int y = x;
+''');
+ expect(unitInfo.regions, hasLength(1));
+ assertRegion(
+ kind: NullabilityFixKind.typeNotMadeNullable,
+ region: unitInfo.regions[0],
+ offset: unitInfo.content.indexOf(' y'));
+ final targets = List<NavigationTarget>.from(unitInfo.targets);
+ assertInTargets(
+ targets: targets,
+ offset: unitInfo.content.indexOf('x'),
+ offsetMapper: unitInfo.offsetMapper);
+ expect(state.hasBeenApplied, false);
+ expect(state.needsRerun, true);
+ }
}
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index 291ba60..355276b 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -21,7 +21,6 @@
import 'fix_reason_target_test.dart' as fix_reason_target_test;
import 'front_end/test_all.dart' as front_end;
import 'instrumentation_test.dart' as instrumentation_test;
-import 'isolate_server_test.dart' as isolate_server_test;
import 'node_builder_test.dart' as node_builder_test;
import 'nullability_node_test.dart' as nullability_node_test;
import 'preview/test_all.dart' as preview;
@@ -44,7 +43,6 @@
fix_reason_target_test.main();
front_end.main();
instrumentation_test.main();
- isolate_server_test.main();
node_builder_test.main();
nullability_node_test.main();
preview.main();
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 279de73..9c8a16a 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -233,6 +233,7 @@
if ($isNnbd) {
sdk.dart.nullSafety($isNnbdStrong);
+ sdk.dart.weakNullSafetyWarnings(!$isNnbdStrong);
}
dartMainRunner(function testMainWrapper() {
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 82b2a4c..0216c27 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -144,7 +144,8 @@
options = new CompilerOptions()
..fileSystem = fileSystem
- ..target = new VmTarget(new TargetFlags())
+ ..target = new VmTarget(new TargetFlags(
+ enableNullSafety: nullSafety == kNullSafetyOptionStrong))
..packagesFileUri = packagesUri
..sdkSummary = platformKernelPath
..verbose = verbose
@@ -354,6 +355,9 @@
if ((nullSafety == kNullSafetyOptionUnspecified) &&
options.experimentalFlags[ExperimentalFlag.nonNullable]) {
await autoDetectNullSafetyMode(script, options);
+ // Reinitialize target to set correct null safety mode.
+ options.target = new VmTarget(new TargetFlags(
+ enableNullSafety: options.nnbdMode == NnbdMode.Strong));
}
generator = new IncrementalCompiler(options, script);
}
@@ -419,6 +423,9 @@
if ((nullSafety == kNullSafetyOptionUnspecified) &&
options.experimentalFlags[ExperimentalFlag.nonNullable]) {
await autoDetectNullSafetyMode(script, options);
+ // Reinitialize target to set correct null safety mode.
+ options.target = new VmTarget(new TargetFlags(
+ enableNullSafety: options.nnbdMode == NnbdMode.Strong));
}
fe.CompilerResult compilerResult = requireMain
? await kernelForProgram(script, options)
diff --git a/pkg/vm/bin/snapshot_analysis.dart b/pkg/vm/bin/snapshot_analysis.dart
new file mode 100755
index 0000000..5d4a012
--- /dev/null
+++ b/pkg/vm/bin/snapshot_analysis.dart
@@ -0,0 +1,22 @@
+#!/usr/bin/env dart
+// 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:args/command_runner.dart';
+
+import 'package:vm/snapshot/compare.dart';
+import 'package:vm/snapshot/treemap.dart';
+
+final runner = CommandRunner('snapshot_analysis.dart',
+ 'Tools for binary size analysis of Dart VM AOT snapshots.')
+ ..addCommand(TreemapCommand())
+ ..addCommand(CompareCommand());
+
+void main(List<String> args) async {
+ try {
+ await runner.run(args);
+ } on UsageException catch (e) {
+ print(e.toString());
+ }
+}
diff --git a/pkg/vm/bin/compare_sizes.dart b/pkg/vm/lib/snapshot/compare.dart
similarity index 76%
rename from pkg/vm/bin/compare_sizes.dart
rename to pkg/vm/lib/snapshot/compare.dart
index 6c41417..47d65b6 100644
--- a/pkg/vm/bin/compare_sizes.dart
+++ b/pkg/vm/lib/snapshot/compare.dart
@@ -2,33 +2,72 @@
// 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 tool compares two JSON size reports produced by
-// --print-instructions-sizes-to and reports which symbols increased in size
-// and which symbols decreased in size.
+/// This tool compares two JSON size reports produced by
+/// --print-instructions-sizes-to and reports which symbols increased in size
+/// and which symbols decreased in size.
+library vm.snapshot.compare;
import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;
-bool limitWidth = false;
+import 'package:args/command_runner.dart';
-void main(List<String> args) {
- if (args.length == 3 && args[2] == 'narrow') {
- limitWidth = true;
- } else if (args.length != 2) {
- print("""
-Usage: dart ${Platform.script} <old.json> <new.json> [narrow]
+class CompareCommand extends Command<void> {
+ @override
+ final String name = 'compare';
+
+ @override
+ final String description = '''
+Compare two instruction size outputs and report which symbols changed in size.
This tool compares two JSON size reports produced by
---print-instructions-sizes-to and reports which symbols increased in size
-and which symbols decreased in size. The optional 'narrow' parameter limits
-the colunm widths.
-""");
- exit(-1);
+--print-instructions-sizes-to and reports which symbols
+changed in size.
+
+Use --narrow flag to limit column widths.''';
+
+ @override
+ String get invocation =>
+ super.invocation.replaceAll('[arguments]', '<old.json> <new.json>');
+
+ CompareCommand() {
+ argParser.addOption('column-width',
+ help: 'Truncate column content to the given width'
+ ' (${AsciiTable.unlimitedWidth} means do not truncate).',
+ defaultsTo: AsciiTable.unlimitedWidth.toString());
}
- final oldSizes = loadSymbolSizes(args[0]);
- final newSizes = loadSymbolSizes(args[1]);
+ @override
+ Future<void> run() async {
+ if (argResults.rest.length != 2) {
+ usageException('Need to provide path to old.json and new.json reports.');
+ }
+
+ final columnWidth = argResults['column-width'];
+ final maxWidth = int.tryParse(columnWidth);
+ if (maxWidth == null) {
+ usageException(
+ 'Specified column width (${columnWidth}) is not an integer');
+ }
+
+ final oldJsonPath = _checkExists(argResults.rest[0]);
+ final newJsonPath = _checkExists(argResults.rest[1]);
+ printComparison(oldJsonPath, newJsonPath, maxWidth: maxWidth);
+ }
+
+ String _checkExists(String path) {
+ if (!File(path).existsSync()) {
+ usageException('File $path does not exist!');
+ }
+ return path;
+ }
+}
+
+void printComparison(String oldJsonPath, String newJsonPath,
+ {int maxWidth: 0}) {
+ final oldSizes = loadSymbolSizes(oldJsonPath);
+ final newSizes = loadSymbolSizes(newJsonPath);
var totalOld = 0;
var totalNew = 0;
@@ -59,7 +98,7 @@
Text.left('Library'),
Text.left('Method'),
Text.right('Diff (Bytes)')
- ]);
+ ], maxWidth: maxWidth);
// Report [numLargerSymbolsToReport] symbols that increased in size most.
for (var key in changedSymbolsBySize
@@ -82,7 +121,7 @@
table.addSeparator();
table.render();
- print('Comparing ${args[0]} (old) to ${args[1]} (new)');
+ print('Comparing ${oldJsonPath} (old) to ${newJsonPath} (new)');
print('Old : ${totalOld} bytes.');
print('New : ${totalNew} bytes.');
print('Change: ${totalDiff > 0 ? '+' : ''}${totalDiff} bytes.');
@@ -217,8 +256,13 @@
}
class AsciiTable {
+ static const int unlimitedWidth = 0;
+
+ final int maxWidth;
+
final List<Row> rows = <Row>[];
- AsciiTable({List<dynamic> header}) {
+
+ AsciiTable({List<dynamic> header, this.maxWidth: unlimitedWidth}) {
if (header != null) {
addSeparator();
addRow(header);
@@ -251,9 +295,9 @@
}
}
- if (limitWidth) {
+ if (maxWidth > 0) {
for (var i = 0; i < widths.length; i++) {
- widths[i] = math.min(widths[i], 25);
+ widths[i] = math.min(widths[i], maxWidth);
}
}
diff --git a/pkg/vm/bin/run_binary_size_analysis.dart b/pkg/vm/lib/snapshot/treemap.dart
similarity index 72%
rename from pkg/vm/bin/run_binary_size_analysis.dart
rename to pkg/vm/lib/snapshot/treemap.dart
index bb67ba8..af46dd8 100644
--- a/pkg/vm/bin/run_binary_size_analysis.dart
+++ b/pkg/vm/lib/snapshot/treemap.dart
@@ -2,12 +2,13 @@
// 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 tool creates interactive navigatable binary size reports from
-// JSON file generated by the AOT compiler's --print-instructions-sizes-to
-// flag.
-//
-// It used the same visualization framework as Chromium's binary_size tool
-// located in runtime/third_party/binary_size.
+/// This tool creates interactive navigatable binary size reports from
+/// JSON file generated by the AOT compiler's --print-instructions-sizes-to
+/// flag.
+///
+/// It used the same visualization framework as Chromium's binary_size tool
+/// located in runtime/third_party/binary_size.
+library vm.snapshot.treemap;
import 'dart:async';
import 'dart:convert';
@@ -15,13 +16,17 @@
import 'dart:math' show max;
import 'package:path/path.dart' as p;
+import 'package:args/command_runner.dart';
import 'package:vm/snapshot/instruction_sizes.dart' as instruction_sizes;
-void main(List<String> args) async {
- if (args.length != 2) {
- print(r"""
-Usage: run_binary_size_analysis.dart <symbol-sizes.json> <output-directory>
+class TreemapCommand extends Command<void> {
+ @override
+ final name = 'treemap';
+
+ @override
+ final description = '''
+Create interactive treemap from snapshot profiling information.
This tool is used to process snapshot size reports produced by
--print-instructions-sizes-to=symbol-sizes.json.
@@ -29,19 +34,43 @@
It will create an interactive web-page in the output-directory which can be
viewed in a browser:
-$ google-chrome <output-directory>/index.html
-""");
- exit(-1);
+\$ google-chrome <output-directory>/index.html''';
+
+ @override
+ String get invocation => super
+ .invocation
+ .replaceAll('[arguments]', '<symbol-sizes.json> <output-directory>');
+
+ TreemapCommand() {
+ // [argParser] is automatically created by the parent class.
+ argParser.addFlag('force',
+ abbr: 'f',
+ help: 'Force overwrite output directory even if it already exists');
}
- final input = new File(args[0]);
- final outputDir = new Directory(args[1]);
+ @override
+ Future<void> run() async {
+ if (argResults.rest.length != 2) {
+ usageException('Need to specify input JSON and output directory.');
+ }
- if (!input.existsSync()) {
- print("Input file ${input} does not exist");
- return;
+ final input = new File(argResults.rest[0]);
+ final outputDir = new Directory(argResults.rest[1]);
+
+ if (!input.existsSync()) {
+ usageException('Input file ${input.path} does not exist!');
+ }
+
+ if (outputDir.existsSync() && !argResults['force']) {
+ usageException(
+ 'Output directory ${outputDir.path} already exists, specify --force to ignore.');
+ }
+
+ await generateTreeMap(input, outputDir);
}
+}
+Future<void> generateTreeMap(File input, Directory outputDir) async {
// Load symbols data produced by the AOT compiler and convert it to
// a tree.
final symbols = await instruction_sizes.load(input);
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 033258f..8bcbb48 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -22,10 +22,7 @@
import '../metadata/binary_cache.dart' show BinaryCacheMetadataRepository;
import '../transformations/call_site_annotator.dart' as callSiteAnnotator;
-import '../transformations/late_var_init_transformer.dart'
- as lateVarInitTransformer;
-import '../transformations/list_factory_specializer.dart'
- as listFactorySpecializer;
+import '../transformations/lowering.dart' as lowering show transformLibraries;
import '../transformations/ffi.dart' as transformFfi show ReplacedMembers;
import '../transformations/ffi_definitions.dart' as transformFfiDefinitions
show transformLibraries;
@@ -173,11 +170,9 @@
productMode: productMode);
logger?.call("Transformed async methods");
- listFactorySpecializer.transformLibraries(libraries, coreTypes);
- logger?.call("Specialized list factories");
-
- lateVarInitTransformer.transformLibraries(libraries);
- logger?.call("Transformed late variable initializers");
+ lowering.transformLibraries(
+ libraries, coreTypes, hierarchy, flags.enableNullSafety);
+ logger?.call("Lowering transformations performed");
callSiteAnnotator.transformLibraries(
component, libraries, coreTypes, hierarchy);
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index cecc5a0..1c11b71 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -156,9 +156,9 @@
}
}
- bool _isPointerType(Field field) {
+ bool _isPointerType(DartType type) {
return env.isSubtypeOf(
- field.type,
+ type,
InterfaceType(pointerClass, Nullability.legacy, [
InterfaceType(nativeTypesClasses[NativeType.kNativeType.index],
Nullability.legacy)
@@ -166,18 +166,52 @@
SubtypeCheckMode.ignoringNullabilities);
}
+ /// Returns members of [node] that correspond to struct fields.
+ ///
+ /// Note that getters and setters that originate from an external field have
+ /// the same `fileOffset`, we always returns getters first.
+ List<Member> _structFieldMembers(Class node) {
+ final externalGetterSetters = [...node.procedures]
+ ..retainWhere((p) => p.isExternal && (p.isGetter || p.isSetter));
+ final structMembers = [...node.fields, ...externalGetterSetters]
+ ..sort((m1, m2) {
+ if (m1.fileOffset == m2.fileOffset) {
+ // Getter and setter have same offset, getter comes first.
+ return (m1 as Procedure).isGetter ? -1 : 1;
+ }
+ return m1.fileOffset - m2.fileOffset;
+ });
+ return structMembers;
+ }
+
+ DartType _structFieldMemberType(Member member) {
+ if (member is Field) {
+ return member.type;
+ }
+ final Procedure p = member;
+ if (p.isGetter) {
+ return p.function.returnType;
+ }
+ return p.function.positionalParameters.single.type;
+ }
+
bool _checkFieldAnnotations(Class node) {
bool success = true;
- for (final Field f in node.fields) {
- if (f.initializer is! NullLiteral) {
- diagnosticReporter.report(
- templateFfiFieldInitializer.withArguments(f.name.name),
- f.fileOffset,
- f.name.name.length,
- f.fileUri);
+ final membersWithAnnotations = _structFieldMembers(node)
+ ..retainWhere((m) => (m is Field) || (m is Procedure && m.isGetter));
+ for (final Member f in membersWithAnnotations) {
+ if (f is Field) {
+ if (f.initializer is! NullLiteral) {
+ diagnosticReporter.report(
+ templateFfiFieldInitializer.withArguments(f.name.name),
+ f.fileOffset,
+ f.name.name.length,
+ f.fileUri);
+ }
}
final nativeTypeAnnos = _getNativeTypeAnnotations(f).toList();
- if (_isPointerType(f)) {
+ final type = _structFieldMemberType(f);
+ if (_isPointerType(type)) {
if (nativeTypeAnnos.length != 0) {
diagnosticReporter.report(
templateFfiFieldNoAnnotation.withArguments(f.name.name),
@@ -192,7 +226,6 @@
f.name.name.length,
f.fileUri);
} else {
- final DartType dartType = f.type;
final DartType nativeType = InterfaceType(
nativeTypesClasses[nativeTypeAnnos.first.index],
Nullability.legacy);
@@ -200,10 +233,10 @@
final DartType shouldBeDartType =
convertNativeTypeToDartType(nativeType, /*allowStructs=*/ false);
if (shouldBeDartType == null ||
- !env.isSubtypeOf(dartType, shouldBeDartType,
+ !env.isSubtypeOf(type, shouldBeDartType,
SubtypeCheckMode.ignoringNullabilities)) {
diagnosticReporter.report(
- templateFfiTypeMismatch.withArguments(dartType, shouldBeDartType,
+ templateFfiTypeMismatch.withArguments(type, shouldBeDartType,
nativeType, node.enclosingLibrary.isNonNullableByDefault),
f.fileOffset,
1,
@@ -261,19 +294,40 @@
///
/// Returns the total size of the struct (for all ABIs).
Map<Abi, int> _replaceFields(Class node, IndexedClass indexedClass) {
- final fields = <Field>[];
final types = <NativeType>[];
+ final fields = <int, Field>{};
+ final getters = <int, Procedure>{};
+ final setters = <int, Procedure>{};
- for (final Field f in node.fields) {
- if (_isPointerType(f)) {
- fields.add(f);
- types.add(NativeType.kPointer);
+ int i = 0;
+ for (final Member m in _structFieldMembers(node)) {
+ final dartType = _structFieldMemberType(m);
+
+ NativeType nativeType;
+ if (_isPointerType(dartType)) {
+ nativeType = NativeType.kPointer;
} else {
- final nativeTypeAnnos = _getNativeTypeAnnotations(f).toList();
+ final nativeTypeAnnos = _getNativeTypeAnnotations(m).toList();
if (nativeTypeAnnos.length == 1) {
- final NativeType t = nativeTypeAnnos.first;
- fields.add(f);
- types.add(t);
+ nativeType = nativeTypeAnnos.first;
+ }
+ }
+
+ if ((m is Field || (m is Procedure && m.isGetter)) &&
+ nativeType != null) {
+ types.add(nativeType);
+ if (m is Field) {
+ fields[i] = m;
+ }
+ if (m is Procedure) {
+ getters[i] = m;
+ }
+ i++;
+ }
+ if (m is Procedure && m.isSetter) {
+ final index = i - 1; // The corresponding getter's index.
+ if (getters.containsKey(index)) {
+ setters[i - 1] = m;
}
}
}
@@ -283,7 +337,7 @@
sizeAndOffsets[abi] = _calculateSizeAndOffsets(types, abi);
}
- for (int i = 0; i < fields.length; i++) {
+ for (final i in fields.keys) {
final fieldOffsets = sizeAndOffsets
.map((Abi abi, SizeAndOffsets v) => MapEntry(abi, v.offsets[i]));
final methods = _generateMethodsForField(
@@ -291,10 +345,35 @@
methods.forEach((p) => node.addMember(p));
}
- for (final Field f in fields) {
+ for (final Field f in fields.values) {
f.remove();
}
+ for (final i in getters.keys) {
+ final fieldOffsets = sizeAndOffsets
+ .map((Abi abi, SizeAndOffsets v) => MapEntry(abi, v.offsets[i]));
+ Procedure getter = getters[i];
+ getter.function.body = _generateGetterStatement(
+ getter.function.returnType,
+ types[i],
+ getter.fileOffset,
+ fieldOffsets);
+ getter.isExternal = false;
+ }
+
+ for (final i in setters.keys) {
+ final fieldOffsets = sizeAndOffsets
+ .map((Abi abi, SizeAndOffsets v) => MapEntry(abi, v.offsets[i]));
+ Procedure setter = setters[i];
+ setter.function.body = _generateSetterStatement(
+ setter.function.positionalParameters.single.type,
+ types[i],
+ setter.fileOffset,
+ fieldOffsets,
+ setter.function.positionalParameters.single);
+ setter.isExternal = false;
+ }
+
return sizeAndOffsets.map((k, v) => MapEntry(k, v.size));
}
@@ -315,14 +394,9 @@
listElementAt);
}
- List<Procedure> _generateMethodsForField(Field field, NativeType type,
- Map<Abi, int> offsets, IndexedClass indexedClass) {
- final DartType nativeType = type == NativeType.kPointer
- ? field.type
- : InterfaceType(nativeTypesClasses[type.index], Nullability.legacy);
- final Class nativeClass = (nativeType as InterfaceType).classNode;
- final NativeType nt = getType(nativeClass);
- final bool isPointer = nt == NativeType.kPointer;
+ Statement _generateGetterStatement(DartType dartType, NativeType type,
+ int fileOffset, Map<Abi, int> offsets) {
+ final bool isPointer = type == NativeType.kPointer;
// Sample output:
// int get x => _loadInt8(pointer, offset);
@@ -332,31 +406,27 @@
// _fromAddress<Int8>(_loadIntPtr(pointer, offset));
final loadMethod = isPointer
? loadMethods[NativeType.kIntptr]
- : optimizedTypes.contains(nt) ? loadMethods[nt] : loadStructMethod;
+ : optimizedTypes.contains(type) ? loadMethods[type] : loadStructMethod;
Expression getterReturnValue = StaticInvocation(
loadMethod,
Arguments([
PropertyGet(ThisExpression(), addressOfField.name, addressOfField)
- ..fileOffset = field.fileOffset,
+ ..fileOffset = fileOffset,
_runtimeBranchOnLayout(offsets)
]))
- ..fileOffset = field.fileOffset;
+ ..fileOffset = fileOffset;
if (isPointer) {
- final typeArg = (nativeType as InterfaceType).typeArguments.single;
+ final typeArg = (dartType as InterfaceType).typeArguments.single;
getterReturnValue = StaticInvocation(
fromAddressInternal, Arguments([getterReturnValue], types: [typeArg]))
- ..fileOffset = field.fileOffset;
+ ..fileOffset = fileOffset;
}
- final Procedure getter = Procedure(
- field.name,
- ProcedureKind.Getter,
- FunctionNode(ReturnStatement(getterReturnValue),
- returnType: field.type),
- fileUri: field.fileUri,
- reference:
- indexedClass?.lookupProcedureNotSetter(field.name.name)?.reference)
- ..fileOffset = field.fileOffset
- ..isNonNullableByDefault = field.isNonNullableByDefault;
+ return ReturnStatement(getterReturnValue);
+ }
+
+ Statement _generateSetterStatement(DartType dartType, NativeType type,
+ int fileOffset, Map<Abi, int> offsets, VariableDeclaration argument) {
+ final bool isPointer = type == NativeType.kPointer;
// Sample output:
// set x(int v) => _storeInt8(pointer, offset, v);
@@ -365,35 +435,48 @@
// set x(Pointer<Int8> v) =>
// _storeIntPtr(pointer, offset, (v as Pointer<Int8>).address);
final storeMethod =
- isPointer ? storeMethods[NativeType.kIntptr] : storeMethods[nt];
+ isPointer ? storeMethods[NativeType.kIntptr] : storeMethods[type];
+ Expression argumentExpression = VariableGet(argument)
+ ..fileOffset = fileOffset;
+ if (isPointer) {
+ argumentExpression = DirectPropertyGet(argumentExpression, addressGetter)
+ ..fileOffset = fileOffset;
+ }
+ return ReturnStatement(StaticInvocation(
+ storeMethod,
+ Arguments([
+ PropertyGet(ThisExpression(), addressOfField.name, addressOfField)
+ ..fileOffset = fileOffset,
+ _runtimeBranchOnLayout(offsets),
+ argumentExpression
+ ]))
+ ..fileOffset = fileOffset);
+ }
+
+ List<Procedure> _generateMethodsForField(Field field, NativeType type,
+ Map<Abi, int> offsets, IndexedClass indexedClass) {
+ final getterStatement =
+ _generateGetterStatement(field.type, type, field.fileOffset, offsets);
+ final Procedure getter = Procedure(field.name, ProcedureKind.Getter,
+ FunctionNode(getterStatement, returnType: field.type),
+ fileUri: field.fileUri,
+ reference:
+ indexedClass?.lookupProcedureNotSetter(field.name.name)?.reference)
+ ..fileOffset = field.fileOffset
+ ..isNonNullableByDefault = field.isNonNullableByDefault;
+
Procedure setter = null;
if (!field.isFinal) {
final VariableDeclaration argument =
VariableDeclaration('#v', type: field.type)
..fileOffset = field.fileOffset;
- Expression argumentExpression = VariableGet(argument)
- ..fileOffset = field.fileOffset;
- if (isPointer) {
- argumentExpression =
- DirectPropertyGet(argumentExpression, addressGetter)
- ..fileOffset = field.fileOffset;
- }
+ final setterStatement = _generateSetterStatement(
+ field.type, type, field.fileOffset, offsets, argument);
setter = Procedure(
field.name,
ProcedureKind.Setter,
- FunctionNode(
- ReturnStatement(StaticInvocation(
- storeMethod,
- Arguments([
- PropertyGet(
- ThisExpression(), addressOfField.name, addressOfField)
- ..fileOffset = field.fileOffset,
- _runtimeBranchOnLayout(offsets),
- argumentExpression
- ]))
- ..fileOffset = field.fileOffset),
- returnType: VoidType(),
- positionalParameters: [argument]),
+ FunctionNode(setterStatement,
+ returnType: VoidType(), positionalParameters: [argument]),
fileUri: field.fileUri,
reference:
indexedClass?.lookupProcedureSetter(field.name.name)?.reference)
@@ -485,7 +568,7 @@
return fieldType;
}
- Iterable<NativeType> _getNativeTypeAnnotations(Field node) {
+ Iterable<NativeType> _getNativeTypeAnnotations(Member node) {
return node.annotations
.whereType<ConstantExpression>()
.map((expr) => expr.constant)
diff --git a/pkg/vm/lib/transformations/late_var_init_transformer.dart b/pkg/vm/lib/transformations/late_var_init_transformer.dart
index 45c3cab..1dc1a87 100644
--- a/pkg/vm/lib/transformations/late_var_init_transformer.dart
+++ b/pkg/vm/lib/transformations/late_var_init_transformer.dart
@@ -5,13 +5,8 @@
import 'package:kernel/ast.dart';
/// Wraps the initializers of late local variables in closures.
-void transformLibraries(List<Library> libraries) {
- const transformer = _LateVarInitTransformer();
- libraries.forEach(transformer.visitLibrary);
-}
-
-class _LateVarInitTransformer extends Transformer {
- const _LateVarInitTransformer();
+class LateVarInitTransformer {
+ const LateVarInitTransformer();
bool _shouldApplyTransform(Statement s) {
if (s is VariableDeclaration) {
@@ -65,17 +60,13 @@
return newStatements;
}
- @override
- visitBlock(Block node) {
- super.visitBlock(node);
+ Block transformBlock(Block node) {
final statements = _transformStatements(node.statements);
if (statements == null) return node;
return Block(statements)..fileOffset = node.fileOffset;
}
- @override
- visitAssertBlock(AssertBlock node) {
- super.visitAssertBlock(node);
+ AssertBlock transformAssertBlock(AssertBlock node) {
final statements = _transformStatements(node.statements);
if (statements == null) return node;
return AssertBlock(statements)..fileOffset = node.fileOffset;
diff --git a/pkg/vm/lib/transformations/list_factory_specializer.dart b/pkg/vm/lib/transformations/list_factory_specializer.dart
index ad989c3..60aff5f 100644
--- a/pkg/vm/lib/transformations/list_factory_specializer.dart
+++ b/pkg/vm/lib/transformations/list_factory_specializer.dart
@@ -15,18 +15,13 @@
/// new List.filled(n, null, growable: true) => new _GrowableList(n)
/// new List.filled(n, null) => new _List(n)
///
-void transformLibraries(List<Library> libraries, CoreTypes coreTypes) {
- final transformer = new _ListFactorySpecializer(coreTypes);
- libraries.forEach(transformer.visitLibrary);
-}
-
-class _ListFactorySpecializer extends Transformer {
+class ListFactorySpecializer {
final Procedure _defaultListFactory;
final Procedure _listFilledFactory;
final Procedure _growableListFactory;
final Procedure _fixedListFactory;
- _ListFactorySpecializer(CoreTypes coreTypes)
+ ListFactorySpecializer(CoreTypes coreTypes)
: _defaultListFactory =
coreTypes.index.getMember('dart:core', 'List', ''),
_listFilledFactory =
@@ -41,10 +36,7 @@
assert(_fixedListFactory.isFactory);
}
- @override
- visitStaticInvocation(StaticInvocation node) {
- super.visitStaticInvocation(node);
-
+ TreeNode transformStaticInvocation(StaticInvocation node) {
final target = node.target;
if (target == _defaultListFactory) {
final args = node.arguments;
diff --git a/pkg/vm/lib/transformations/lowering.dart b/pkg/vm/lib/transformations/lowering.dart
new file mode 100644
index 0000000..3e3e410
--- /dev/null
+++ b/pkg/vm/lib/transformations/lowering.dart
@@ -0,0 +1,80 @@
+// 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';
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/core_types.dart' show CoreTypes;
+import 'package:kernel/transformations/type_casts_optimizer.dart'
+ as typeCastsOptimizer show transformAsExpression;
+import 'package:kernel/type_environment.dart'
+ show StaticTypeContext, TypeEnvironment;
+
+import 'late_var_init_transformer.dart' show LateVarInitTransformer;
+import 'list_factory_specializer.dart' show ListFactorySpecializer;
+
+/// VM-specific lowering transformations and optimizations combined into a
+/// single transformation pass.
+///
+/// Each transformation is applied locally to AST nodes of certain types
+/// after transforming children nodes.
+void transformLibraries(List<Library> libraries, CoreTypes coreTypes,
+ ClassHierarchy hierarchy, bool nullSafety) {
+ final transformer = _Lowering(coreTypes, hierarchy, nullSafety);
+ libraries.forEach(transformer.visitLibrary);
+}
+
+class _Lowering extends Transformer {
+ final TypeEnvironment env;
+ final bool nullSafety;
+ final ListFactorySpecializer listFactorySpecializer;
+ final LateVarInitTransformer lateVarInitTransformer;
+
+ Member _currentMember;
+ StaticTypeContext _cachedStaticTypeContext;
+
+ _Lowering(CoreTypes coreTypes, ClassHierarchy hierarchy, this.nullSafety)
+ : env = TypeEnvironment(coreTypes, hierarchy),
+ listFactorySpecializer = ListFactorySpecializer(coreTypes),
+ lateVarInitTransformer = LateVarInitTransformer();
+
+ StaticTypeContext get _staticTypeContext =>
+ _cachedStaticTypeContext ??= StaticTypeContext(_currentMember, env);
+
+ @override
+ defaultMember(Member node) {
+ _currentMember = node;
+ _cachedStaticTypeContext = null;
+
+ final result = super.defaultMember(node);
+
+ _currentMember = null;
+ _cachedStaticTypeContext = null;
+ return result;
+ }
+
+ @override
+ visitStaticInvocation(StaticInvocation node) {
+ node.transformChildren(this);
+ return listFactorySpecializer.transformStaticInvocation(node);
+ }
+
+ @override
+ visitAsExpression(AsExpression node) {
+ node.transformChildren(this);
+ return typeCastsOptimizer.transformAsExpression(
+ node, _staticTypeContext, nullSafety);
+ }
+
+ @override
+ visitBlock(Block node) {
+ node.transformChildren(this);
+ return lateVarInitTransformer.transformBlock(node);
+ }
+
+ @override
+ visitAssertBlock(AssertBlock node) {
+ node.transformChildren(this);
+ return lateVarInitTransformer.transformAssertBlock(node);
+ }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/calls.dart b/pkg/vm/lib/transformations/type_flow/calls.dart
index 55ff9ef..c0235ed 100644
--- a/pkg/vm/lib/transformations/type_flow/calls.dart
+++ b/pkg/vm/lib/transformations/type_flow/calls.dart
@@ -8,6 +8,7 @@
import 'dart:core' hide Type;
import 'package:kernel/ast.dart';
+import 'package:kernel/src/text_util.dart';
import 'types.dart';
import 'utils.dart';
@@ -116,7 +117,8 @@
other is DirectSelector && super == (other) && other.member == member;
@override
- String toString() => 'direct ${_callKindPrefix}[$member]';
+ String toString() => 'direct ${_callKindPrefix}'
+ '[${qualifiedMemberNameToString(member, includeLibraryName: true)}]';
}
/// Interface call via known interface target [member].
@@ -135,7 +137,8 @@
other is InterfaceSelector && super == (other) && other.member == member;
@override
- String toString() => '${_callKindPrefix}[$member]';
+ String toString() => '${_callKindPrefix}'
+ '[${qualifiedMemberNameToString(member, includeLibraryName: true)}]';
}
/// Virtual call (using 'this' as a receiver).
@@ -151,7 +154,8 @@
identical(this, other) || other is VirtualSelector && super == (other);
@override
- String toString() => 'virtual ${_callKindPrefix}[$member]';
+ String toString() => 'virtual ${_callKindPrefix}'
+ '[${qualifiedMemberNameToString(member, includeLibraryName: true)}]';
}
/// Dynamic call.
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index 8e66c3e..28df481 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -192,7 +192,8 @@
void accept(StatementVisitor visitor) => visitor.visitJoin(this);
@override
- String dump() => "$label = _Join [$staticType] (${values.join(", ")})";
+ String dump() => "$label = _Join [${staticType.toTypeText(verbose: true)}]"
+ " (${values.join(", ")})";
@override
Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index 4bd891c..a3739d8 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -11,6 +11,8 @@
import 'package:kernel/core_types.dart';
+import 'package:kernel/src/text_util.dart';
+
import 'utils.dart';
/// Dart class representation used in type flow analysis.
@@ -32,7 +34,8 @@
bool operator ==(other) => identical(this, other);
@override
- String toString() => classNode.toString();
+ String toString() =>
+ qualifiedClassNameToString(classNode, includeLibraryName: true);
}
abstract class GenericInterfacesInfo {
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index 69c5cb3..26c85a6 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -8,6 +8,7 @@
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/target/targets.dart';
+import 'package:kernel/src/text_util.dart';
import 'package:kernel/type_environment.dart';
import 'package:test/test.dart';
import 'package:vm/transformations/pragma.dart'
@@ -84,7 +85,8 @@
defaultMember(Member member) {
if (!member.isAbstract &&
!((member is Field) && (member.initializer == null))) {
- _buf.writeln("------------ $member ------------");
+ _buf.writeln(
+ "------------ ${qualifiedMemberNameToString(member)} ------------");
_buf.writeln(_summaryCollector.createSummary(member));
}
}
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 8ed5202..37f2ebb 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -883,7 +883,7 @@
if(y is #lib::C<dynamic, #lib::D::Q*, dart.core::List<#lib::D::P*>*>*) {
dart.core::print("22");
}
- [@vm.call-site-attributes.metadata=receiverType:InterfaceType(D<D::P*, D::Q*>*)] this.{#lib::D::foo} = y as{TypeError,ForDynamic} dart.core::Map<#lib::D::P*, #lib::D::Q*>*;
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(D<D.P*, D.Q*>*)] this.{#lib::D::foo} = y as{TypeError,ForDynamic} dart.core::Map<#lib::D::P*, #lib::D::Q*>*;
}
method foo3<T1 extends dart.core::Object* = dynamic, T2 extends dart.core::Object* = dynamic>(dynamic z) → dynamic {
if(z is #lib::A<#lib::D::foo3::T1*>*) {
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect
index 5981906..ed00cf1 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect
@@ -5,23 +5,23 @@
RESULT: _T {}?
------------ bool_expressions ------------
-t0* = _Call direct [foo] ()
+t0* = _Call direct [#lib::foo] ()
t1 = _TypeCheck (t0 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t2* = _Call direct [bar] ()
-t3* = _Call [num::+] (_T (dart.core::int)+, _T (dart.core::_Smi, 1))
-i_0 = _Join [InterfaceType(int*)] (_T (dart.core::_Smi, 0), t3)
-t5* = _Call [num::<] (i_0, _T (dart.core::_Smi, 10))
-t6* = _Call direct [bar] ()
-t7* = _Call direct [foo] ()
-t8 = _Join [DynamicType(dynamic)] (_T (dart.core::bool, true), t7)
+t2* = _Call direct [#lib::bar] ()
+t3* = _Call [dart.core::num.+] (_T (dart.core::int)+, _T (dart.core::_Smi, 1))
+i_0 = _Join [dart.core::int*] (_T (dart.core::_Smi, 0), t3)
+t5* = _Call [dart.core::num.<] (i_0, _T (dart.core::_Smi, 10))
+t6* = _Call direct [#lib::bar] ()
+t7* = _Call direct [#lib::foo] ()
+t8 = _Join [dynamic] (_T (dart.core::bool, true), t7)
t9 = _TypeCheck (t8 against dart.core::bool*) (for AsExpression( ? true : foo, as bool*))
-t10* = _Call direct [bar] ()
-t11* = _Call direct [bar] ()
-t12* = _Call direct [foo] ()
+t10* = _Call direct [#lib::bar] ()
+t11* = _Call direct [#lib::bar] ()
+t12* = _Call direct [#lib::foo] ()
t13 = _TypeCheck (t12 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t14* = _Call direct [foo] ()
+t14* = _Call direct [#lib::foo] ()
t15 = _TypeCheck (t14 against dart.core::bool*) (for AsExpression(foo, as bool*))
-y_0 = _Join [InterfaceType(bool*)] (_T (dart.core::bool), _T (dart.core::bool, true))
+y_0 = _Join [dart.core::bool*] (_T (dart.core::bool), _T (dart.core::bool, true))
RESULT: _T {}?
------------ main ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
index ab5df37..5ed0d02 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
@@ -1,56 +1,56 @@
------------- A:: ------------
+------------ A. ------------
%this = _Parameter #0 [_T (#lib::A)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- A::foo1 ------------
+------------ A.foo1 ------------
%this = _Parameter #0 [_T (#lib::A)+]
%x = _Parameter #1 [_T (dart.core::Object)+?]
RESULT: _T {}?
------------- B:: ------------
+------------ B. ------------
%this = _Parameter #0 [_T (#lib::B)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- B::bar1 ------------
+------------ B.bar1 ------------
%this = _Parameter #0 [_T (#lib::B)+]
%arg = _Parameter #1 [_T (dart.core::Object)+?]
RESULT: _T {}?
------------- B::bar2 ------------
+------------ B.bar2 ------------
%this = _Parameter #0 [_T (#lib::B)+]
RESULT: _T {}?
------------- B::bar3 ------------
+------------ B.bar3 ------------
%this = _Parameter #0 [_T (#lib::B)+]
%y = _Parameter #1 [_T (dart.core::int)+?]
RESULT: _T {}?
------------- B::bar4 ------------
+------------ B.bar4 ------------
%this = _Parameter #0 [_T (#lib::B)+]
RESULT: _T {}?
------------- C:: ------------
+------------ C. ------------
%this = _Parameter #0 [_T (#lib::C)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- C::interfaceCalls ------------
+------------ C.interfaceCalls ------------
%this = _Parameter #0 [_T (#lib::C)+]
%aa = _Parameter #1 [_T (#lib::A)+?]
%a2 = _Parameter #2 [_T (dart.core::Object)+?]
%a3 = _Parameter #3 [_T (dart.core::Object)+?]
%a4 = _Parameter #4 [_T (dart.core::Object)+?]
-t5 = _Call direct [B::] (_T (#lib::B))
-t6 = _Call [A::foo1] (%aa, _T (#lib::B))
+t5 = _Call direct [#lib::B.] (_T (#lib::B))
+t6 = _Call [#lib::A.foo1] (%aa, _T (#lib::B))
t7 = _Narrow (%aa to _T ANY)
-t8* = _Call get [A::foo2] (t7)
+t8* = _Call get [#lib::A.foo2] (t7)
t9 = _TypeCheck (t8 against dart.core::int*) (for AsExpression(.foo2 as int*))
-t10 = _Call set [A::foo3] (t7, t9)
-t11* = _Call get [A::foo1] (t7)
-t12* = _Call get [A::foo2] (t7)
+t10 = _Call set [#lib::A.foo3] (t7, t9)
+t11* = _Call get [#lib::A.foo1] (t7)
+t12* = _Call get [#lib::A.foo2] (t7)
t13* = _Call dynamic [call] (t12, %a2, %a3, t11)
RESULT: t13
------------- C::dynamicCalls ------------
+------------ C.dynamicCalls ------------
%this = _Parameter #0 [_T (#lib::C)+]
%aa = _Parameter #1 [_T ANY?]
%a2 = _Parameter #2 [_T (dart.core::Object)+?]
%a3 = _Parameter #3 [_T (dart.core::Object)+?]
%a4 = _Parameter #4 [_T (dart.core::Object)+?]
-t5 = _Call direct [B::] (_T (#lib::B))
+t5 = _Call direct [#lib::B.] (_T (#lib::B))
t6 = _Call dynamic [foo1] (%aa, _T (#lib::B))
t7 = _Narrow (%aa to _T ANY)
t8* = _Call dynamic get [foo2] (t7)
@@ -58,21 +58,21 @@
t10* = _Call dynamic get [foo1] (t7)
t11* = _Call dynamic [foo2] (t7, %a2, %a3, t10)
RESULT: t11
------------- D:: ------------
+------------ D. ------------
%this = _Parameter #0 [_T (#lib::D)+]
-t1 = _Call direct [B::] (%this)
+t1 = _Call direct [#lib::B.] (%this)
RESULT: _T {}?
------------- D::superCalls ------------
+------------ D.superCalls ------------
%this = _Parameter #0 [_T (#lib::D)+]
%a1 = _Parameter #1 [_T (dart.core::Object)+?]
%a2 = _Parameter #2 [_T (dart.core::Object)+?]
%a3 = _Parameter #3 [_T (dart.core::Object)+?]
%a4 = _Parameter #4 [_T (dart.core::Object)+?]
-t5 = _Call direct [B::bar1] (%this, %a1)
-t6* = _Call direct get [B::bar4] (%this)
-t7 = _Call direct set [B::bar3] (%this, t6)
-t8* = _Call direct get [B::bar2] (%this)
-t9* = _Call direct get [B::bar1] (%this)
+t5 = _Call direct [#lib::B.bar1] (%this, %a1)
+t6* = _Call direct get [#lib::B.bar4] (%this)
+t7 = _Call direct set [#lib::B.bar3] (%this, t6)
+t8* = _Call direct get [#lib::B.bar2] (%this)
+t9* = _Call direct get [#lib::B.bar1] (%this)
t10* = _Call dynamic [call] (t8, %a2, %a3, t9)
RESULT: t10
------------ main ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect
index d64dfc3..9448ea4 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect
@@ -1,85 +1,85 @@
------------- C:: ------------
+------------ C. ------------
%this = _Parameter #0 [_T (#lib::C)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- C::foo ------------
+------------ C.foo ------------
%this = _Parameter #0 [_T (#lib::C)+]
t1 = _Extract (%this[#lib::C/0]*)
t2 = _CreateConcreteType (#lib::D @ (t1))
-t3 = _Call direct [D::] (t2)
+t3 = _Call direct [#lib::D.] (t2)
RESULT: t2
------------- C::id1 ------------
+------------ C.id1 ------------
%this = _Parameter #0 [_T (#lib::C)+]
%x = _Parameter #1
t2 = _Extract (%this[#lib::C/0]*)
t3 = _TypeCheck (%x against t2) (for VariableDeclaration(x))
RESULT: t3
------------- C::id2 ------------
+------------ C.id2 ------------
%this = _Parameter #0 [_T (#lib::C)+]
%x = _Parameter #1
t2 = _Extract (%this[#lib::C/0]*)
t3 = _TypeCheck (%x against t2) (for VariableDeclaration(x))
RESULT: t3
------------- D:: ------------
+------------ D. ------------
%this = _Parameter #0 [_T (#lib::D)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- E:: ------------
+------------ E. ------------
%this = _Parameter #0 [_T (#lib::E)+]
-t1 = _Call direct [C::] (%this)
+t1 = _Call direct [#lib::C.] (%this)
RESULT: _T {}?
------------- E::foo ------------
+------------ E.foo ------------
%this = _Parameter #0 [_T (#lib::E)+]
-t1* = _Call direct [C::foo] (%this)
+t1* = _Call direct [#lib::C.foo] (%this)
RESULT: t1
------------- E::bar ------------
+------------ E.bar ------------
%this = _Parameter #0 [_T (#lib::E)+]
t1 = _Extract (%this[#lib::E/0]*)
t2 = _CreateConcreteType (#lib::D @ (t1))
-t3 = _Call direct [D::] (t2)
+t3 = _Call direct [#lib::D.] (t2)
RESULT: t2
------------- E::baz ------------
+------------ E.baz ------------
%this = _Parameter #0 [_T (#lib::E)+]
t1 = _Extract (%this[#lib::E/1]*)
t2 = _CreateConcreteType (#lib::D @ (t1))
-t3 = _Call direct [D::] (t2)
+t3 = _Call direct [#lib::D.] (t2)
RESULT: t2
------------- X:: ------------
+------------ X. ------------
%this = _Parameter #0 [_T (#lib::X)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- Y:: ------------
+------------ Y. ------------
%this = _Parameter #0 [_T (#lib::Y)+]
-t1 = _Call direct [X::] (%this)
+t1 = _Call direct [#lib::X.] (%this)
RESULT: _T {}?
------------- Z:: ------------
+------------ Z. ------------
%this = _Parameter #0 [_T (#lib::Z)+]
-t1 = _Call direct [X::] (%this)
+t1 = _Call direct [#lib::X.] (%this)
RESULT: _T {}?
------------- I:: ------------
+------------ I. ------------
%this = _Parameter #0 [_T (#lib::I)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- J:: ------------
+------------ J. ------------
%this = _Parameter #0 [_T (#lib::J)+]
-t1 = _Call direct [I::] (%this)
+t1 = _Call direct [#lib::I.] (%this)
RESULT: _T {}?
------------- K:: ------------
+------------ K. ------------
%this = _Parameter #0 [_T (#lib::K)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- C2:: ------------
+------------ C2. ------------
%this = _Parameter #0 [_T (#lib::C2)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- C2::id3 ------------
+------------ C2.id3 ------------
%this = _Parameter #0 [_T (#lib::C2)+]
%x = _Parameter #1
t2 = _Extract (%this[#lib::C2/0]*)
t3 = _CreateRuntimeType (dart.core::Comparable @ (t2)*)
t4 = _TypeCheck (%x against t3) (for VariableDeclaration(x))
RESULT: t4
------------- C2::id4 ------------
+------------ C2.id4 ------------
%this = _Parameter #0 [_T (#lib::C2)+]
%x = _Parameter #1
t2 = _Extract (%this[#lib::C2/0]*)
@@ -88,21 +88,21 @@
t5 = _TypeCheck (%x against t4) (for VariableDeclaration(x))
RESULT: t5
------------ main ------------
-t0 = _Call direct [C::] (_T (#lib::C<dart.core::int*>))
-t1 = _Call [C::foo] (_T (#lib::C<dart.core::int*>))
-t2 = _Call direct [E::] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t3 = _Call [E::foo] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t4 = _Call direct [E::] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t5 = _Call [E::bar] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t6 = _Call direct [E::] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t7* = _Call [E::baz] (_T (#lib::E<dart.core::int*, dart.core::String*>))
-t8 = _Call direct [C::] (_T (#lib::C<#lib::Y*>))
-t9 = _Call direct [Y::] (_T (#lib::Y))
-t10 = _Call [C::id1] (_T (#lib::C<#lib::Y*>), _T (#lib::Y))
-t11 = _Call direct [Z::] (_T (#lib::Z))
-t12 = _Call [C::id2] (_T (#lib::C<#lib::Y*>), _T (#lib::Z))
-t13 = _Call direct [C2::] (_T (#lib::C2<dart.core::num*>))
-t14 = _Call [C2::id3] (_T (#lib::C2<dart.core::num*>), _T (dart.core::_Double, 3.0))
-t15 = _Call direct [K::] (_T (#lib::K<#lib::J*>))
-t16 = _Call [C2::id4] (_T (#lib::C2<dart.core::num*>), _T (#lib::K<#lib::J*>))
+t0 = _Call direct [#lib::C.] (_T (#lib::C<dart.core::int*>))
+t1 = _Call [#lib::C.foo] (_T (#lib::C<dart.core::int*>))
+t2 = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t3 = _Call [#lib::E.foo] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t4 = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t5 = _Call [#lib::E.bar] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t6 = _Call direct [#lib::E.] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t7* = _Call [#lib::E.baz] (_T (#lib::E<dart.core::int*, dart.core::String*>))
+t8 = _Call direct [#lib::C.] (_T (#lib::C<#lib::Y*>))
+t9 = _Call direct [#lib::Y.] (_T (#lib::Y))
+t10 = _Call [#lib::C.id1] (_T (#lib::C<#lib::Y*>), _T (#lib::Y))
+t11 = _Call direct [#lib::Z.] (_T (#lib::Z))
+t12 = _Call [#lib::C.id2] (_T (#lib::C<#lib::Y*>), _T (#lib::Z))
+t13 = _Call direct [#lib::C2.] (_T (#lib::C2<dart.core::num*>))
+t14 = _Call [#lib::C2.id3] (_T (#lib::C2<dart.core::num*>), _T (dart.core::_Double, 3.0))
+t15 = _Call direct [#lib::K.] (_T (#lib::K<#lib::J*>))
+t16 = _Call [#lib::C2.id4] (_T (#lib::C2<dart.core::num*>), _T (#lib::K<#lib::J*>))
RESULT: t7
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
index 67839f0..18b1677 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect
@@ -1,18 +1,18 @@
------------- Element:: ------------
+------------ Element. ------------
%this = _Parameter #0 [_T (#lib::Element)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- MockHashMap:: ------------
+------------ MockHashMap. ------------
%K = _Parameter #0
%V = _Parameter #1
t2 = _CreateConcreteType (#lib::_NotRealHashMap @ (%K, %V))
-t3 = _Call direct [_NotRealHashMap::] (t2)
+t3 = _Call direct [#lib::_NotRealHashMap.] (t2)
RESULT: t2
------------- _NotRealHashMap:: ------------
+------------ _NotRealHashMap. ------------
%this = _Parameter #0 [_T (#lib::_NotRealHashMap)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- _NotRealHashMap::setEntry ------------
+------------ _NotRealHashMap.setEntry ------------
%this = _Parameter #0 [_T (#lib::_NotRealHashMap)+]
%key = _Parameter #1
%value = _Parameter #2
@@ -21,24 +21,24 @@
t5 = _Extract (%this[#lib::_NotRealHashMap/1]*)
t6 = _TypeCheck (%value against t5) (for VariableDeclaration(value))
RESULT: _T {}?
------------- InheritedElement:: ------------
+------------ InheritedElement. ------------
%this = _Parameter #0 [_T (#lib::InheritedElement)+]
-t1 = _Call direct [Element::] (%this)
+t1 = _Call direct [#lib::Element.] (%this)
RESULT: _T {}?
------------- InheritedElement::setDependencies ------------
+------------ InheritedElement.setDependencies ------------
%this = _Parameter #0 [_T (#lib::InheritedElement)+]
%dependent = _Parameter #1 [_T (#lib::Element)+?]
%value = _Parameter #2 [_T (dart.core::Object)+?]
-t3* = _Call virtual get [InheritedElement::_dependents] (%this)
-t4 = _Call [MockHashMap::setEntry] (t3, %dependent, %value)
+t3* = _Call virtual get [#lib::InheritedElement._dependents] (%this)
+t4 = _Call [#lib::MockHashMap.setEntry] (t3, %dependent, %value)
RESULT: _T {}?
------------- InheritedElement::_dependents ------------
+------------ InheritedElement._dependents ------------
%this = _Parameter #0 [_T (#lib::InheritedElement)+]
-t1* = _Call direct [MockHashMap::] (#lib::Element*, dart.core::Object*)
+t1* = _Call direct [#lib::MockHashMap.] (#lib::Element*, dart.core::Object*)
RESULT: t1
------------ main ------------
-t0 = _Call direct [InheritedElement::] (_T (#lib::InheritedElement))
-t1 = _Call [InheritedElement::setDependencies] (_T (#lib::InheritedElement), _T (#lib::InheritedElement), _T (dart.core::_Smi, 0))
-t2 = _Call direct [Element::] (_T (#lib::Element))
-t3 = _Call [InheritedElement::setDependencies] (_T (#lib::InheritedElement), _T (#lib::Element), _T {}?)
+t0 = _Call direct [#lib::InheritedElement.] (_T (#lib::InheritedElement))
+t1 = _Call [#lib::InheritedElement.setDependencies] (_T (#lib::InheritedElement), _T (#lib::InheritedElement), _T (dart.core::_Smi, 0))
+t2 = _Call direct [#lib::Element.] (_T (#lib::Element))
+t3 = _Call [#lib::InheritedElement.setDependencies] (_T (#lib::InheritedElement), _T (#lib::Element), _T {}?)
RESULT: _T {}?
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/constants.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/constants.dart.expect
index bf8b008..f1be001 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/constants.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/constants.dart.expect
@@ -9,11 +9,11 @@
RESULT: _T (dart.core::_OneByteString, abc)
------------ indexingIntoConstantList1 ------------
%i = _Parameter #0 [_T (dart.core::int)+?]
-t1 = _Join [InterfaceType(int*)] (_T (dart.core::_Smi, 1), _T (dart.core::_Smi, 2), _T (dart.core::_Smi, 3))
+t1 = _Join [dart.core::int*] (_T (dart.core::_Smi, 1), _T (dart.core::_Smi, 2), _T (dart.core::_Smi, 3))
RESULT: t1
------------ indexingIntoConstantList2 ------------
%i = _Parameter #0 [_T (dart.core::int)+?]
-t1 = _Join [InterfaceType(Object*)] (_T (dart.core::_OneByteString, hi), _T (dart.core::_Smi, 33), _T {}?, _T (dart.core::_Smi, -5))
+t1 = _Join [dart.core::Object*] (_T (dart.core::_OneByteString, hi), _T (dart.core::_Smi, 33), _T {}?, _T (dart.core::_Smi, -5))
RESULT: t1
------------ main ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
index cc1c945..740ae32 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
@@ -1,38 +1,38 @@
------------- C1:: ------------
+------------ C1. ------------
%this = _Parameter #0 [_T (#lib::C1)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- C2:: ------------
+------------ C2. ------------
%this = _Parameter #0 [_T (#lib::C2)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- C3:: ------------
+------------ C3. ------------
%this = _Parameter #0 [_T (#lib::C3)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- C4:: ------------
+------------ C4. ------------
%this = _Parameter #0 [_T (#lib::C4)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- TestEnum:: ------------
+------------ TestEnum. ------------
%this = _Parameter #0 [_T (#lib::TestEnum)+]
%index = _Parameter #1 [_T (dart.core::int)+?]
%_name = _Parameter #2 [_T (dart.core::String)+?]
-t3 = _Call direct set [TestEnum::index] (%this, %index)
-t4 = _Call direct set [TestEnum::_name] (%this, %_name)
-t5 = _Call direct [Object::] (%this)
+t3 = _Call direct set [#lib::TestEnum.index] (%this, %index)
+t4 = _Call direct set [#lib::TestEnum._name] (%this, %_name)
+t5 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- TestEnum::toString ------------
+------------ TestEnum.toString ------------
%this = _Parameter #0 [_T (#lib::TestEnum)+]
-t1* = _Call direct get [TestEnum::_name] (%this)
+t1* = _Call direct get [#lib::TestEnum._name] (%this)
RESULT: t1
------------- TestEnum::values ------------
+------------ TestEnum.values ------------
RESULT: _T (dart.core::_ImmutableList, ListConstant<TestEnum*>([#lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, }, #lib::TestEnum {index: 1, #lib::_name: TestEnum.v2, }]))
------------- TestEnum::v1 ------------
+------------ TestEnum.v1 ------------
RESULT: _T (#lib::TestEnum, #lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, })
------------- TestEnum::v2 ------------
+------------ TestEnum.v2 ------------
RESULT: _T (#lib::TestEnum, #lib::TestEnum {index: 1, #lib::_name: TestEnum.v2, })
------------ foo ------------
@@ -45,235 +45,235 @@
%x = _Parameter #0 [_T ANY?]
RESULT: _T {}?
------------ sequence ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-t1 = _Call direct [C2::] (_T (#lib::C2))
-t2 = _Call direct [C3::] (_T (#lib::C3))
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t2 = _Call direct [#lib::C3.] (_T (#lib::C3))
RESULT: _T (#lib::C3)
------------ if1 ------------
%cond = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [C1::] (_T (#lib::C1))
-t2 = _Call direct [C2::] (_T (#lib::C2))
-t3 = _Call direct [foo] (_T (#lib::C2))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C2), _T (#lib::C1))
+t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t3 = _Call direct [#lib::foo] (_T (#lib::C2))
+x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C1))
RESULT: x_0
------------ if2 ------------
%cond1 = _Parameter #0 [_T (dart.core::bool)+?]
%cond2 = _Parameter #1 [_T (dart.core::bool)+?]
-t2 = _Call direct [C1::] (_T (#lib::C1))
-t3 = _Call direct [foo] (_T (#lib::C1))
-t4 = _Call direct [C2::] (_T (#lib::C2))
-t5 = _Call direct [bar] (_T (#lib::C2))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C2))
+t2 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t3 = _Call direct [#lib::foo] (_T (#lib::C1))
+t4 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t5 = _Call direct [#lib::bar] (_T (#lib::C2))
+x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
RESULT: x_0
------------ if3 ------------
%cond1 = _Parameter #0 [_T (dart.core::bool)+?]
%cond2 = _Parameter #1 [_T (dart.core::bool)+?]
-t2 = _Call direct [C1::] (_T (#lib::C1))
-t3 = _Call direct [C2::] (_T (#lib::C2))
-t4* = _Call direct [foo] (_T (#lib::C2))
+t2 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t4* = _Call direct [#lib::foo] (_T (#lib::C2))
t5 = _TypeCheck (t4 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t6 = _Call direct [C3::] (_T (#lib::C3))
-t7* = _Call direct [foo] (_T (#lib::C3))
+t6 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t7* = _Call direct [#lib::foo] (_T (#lib::C3))
t8 = _TypeCheck (t7 against dart.core::bool*) (for AsExpression(foo, as bool*))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C2), _T (#lib::C3))
-t10 = _Call direct [bar] (x_0)
+x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C3))
+t10 = _Call direct [#lib::bar] (x_0)
RESULT: x_0
------------ if4 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-t1 = _Call direct [C2::] (_T (#lib::C2))
-t2* = _Call direct [foo] (_T (#lib::C2))
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t2* = _Call direct [#lib::foo] (_T (#lib::C2))
t3 = _TypeCheck (t2 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t4 = _Call direct [C3::] (_T (#lib::C3))
-t5* = _Call direct [foo] (_T (#lib::C3))
+t4 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t5* = _Call direct [#lib::foo] (_T (#lib::C3))
t6 = _TypeCheck (t5 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t7 = _Call direct [bar] (_T (#lib::C3))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C2), _T (#lib::C3))
+t7 = _Call direct [#lib::bar] (_T (#lib::C3))
+x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C3))
RESULT: x_0
------------ if5 ------------
%cond = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [C1::] (_T (#lib::C1))
-t2 = _Call direct [C2::] (_T (#lib::C2))
-t3 = _Call direct [foo] (_T (#lib::C1))
+t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t3 = _Call direct [#lib::foo] (_T (#lib::C1))
RESULT: _T {}?
------------ if6a ------------
%x = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [foo] (_T (dart.core::bool, true))
-t2 = _Call direct [bar] (_T (dart.core::bool, false))
-x_0 = _Join [InterfaceType(bool*)] (_T (dart.core::bool, true), _T (dart.core::bool, false))
-t4 = _Call direct [baz] (x_0)
+t1 = _Call direct [#lib::foo] (_T (dart.core::bool, true))
+t2 = _Call direct [#lib::bar] (_T (dart.core::bool, false))
+x_0 = _Join [dart.core::bool*] (_T (dart.core::bool, true), _T (dart.core::bool, false))
+t4 = _Call direct [#lib::baz] (x_0)
RESULT: _T {}?
------------ if6b ------------
%x = _Parameter #0 [_T ANY?]
t1 = _TypeCheck (%x against dart.core::bool*) (for AsExpression( as bool*))
-t2 = _Call direct [foo] (_T (dart.core::bool, true))
-t3 = _Call direct [bar] (_T (dart.core::bool, false))
-x_0 = _Join [DynamicType(dynamic)] (_T (dart.core::bool, true), _T (dart.core::bool, false))
-t5 = _Call direct [baz] (x_0)
+t2 = _Call direct [#lib::foo] (_T (dart.core::bool, true))
+t3 = _Call direct [#lib::bar] (_T (dart.core::bool, false))
+x_0 = _Join [dynamic] (_T (dart.core::bool, true), _T (dart.core::bool, false))
+t5 = _Call direct [#lib::baz] (x_0)
RESULT: _T {}?
------------ if7 ------------
%x = _Parameter #0 [_T (dart.core::int)+?]
%y = _Parameter #1 [_T (dart.core::String)+?]
%z = _Parameter #2 [_T ANY?]
-t3* = _Call [num::==] (%x, _T (dart.core::_Smi, 5))
-t4* = _Call [String::==] (%y, _T (dart.core::_OneByteString, hi))
-t5 = _Call direct [Object::==] (%z, _T {}?)
+t3* = _Call [dart.core::num.==] (%x, _T (dart.core::_Smi, 5))
+t4* = _Call [dart.core::String.==] (%y, _T (dart.core::_OneByteString, hi))
+t5 = _Call direct [dart.core::Object.==] (%z, _T {}?)
t6 = _Narrow (%z to _T ANY)
-t7 = _Call direct [foo] (_T (dart.core::_Smi, 5))
-t8 = _Call direct [foo] (_T (dart.core::_OneByteString, hi))
-t9 = _Call direct [foo] (t6)
+t7 = _Call direct [#lib::foo] (_T (dart.core::_Smi, 5))
+t8 = _Call direct [#lib::foo] (_T (dart.core::_OneByteString, hi))
+t9 = _Call direct [#lib::foo] (t6)
RESULT: _T {}?
------------ if8 ------------
%x = _Parameter #0 [_T ANY?]
t1 = _Narrow (%x to _T (dart.core::String)+)
-t2 = _Call direct [foo] (t1)
+t2 = _Call direct [#lib::foo] (t1)
RESULT: _T {}?
------------ if9 ------------
%x = _Parameter #0 [_T (#lib::TestEnum)+?]
-t1* = _Call [TestEnum::==] (%x, _T (#lib::TestEnum, #lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, }))
-t2 = _Call direct [foo] (_T (#lib::TestEnum, #lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, }))
+t1* = _Call [#lib::TestEnum.==] (%x, _T (#lib::TestEnum, #lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, }))
+t2 = _Call direct [#lib::foo] (_T (#lib::TestEnum, #lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, }))
RESULT: _T {}?
------------ conditional1 ------------
%cond1 = _Parameter #0 [_T (dart.core::bool)+?]
%cond2 = _Parameter #1 [_T (dart.core::bool)+?]
-t2 = _Call direct [C1::] (_T (#lib::C1))
-t3 = _Call direct [C2::] (_T (#lib::C2))
-t4* = _Call direct [foo] (_T (#lib::C2))
+t2 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t4* = _Call direct [#lib::foo] (_T (#lib::C2))
t5 = _TypeCheck (t4 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t6 = _Call direct [C3::] (_T (#lib::C3))
-t7 = _Call direct [C4::] (_T (#lib::C4))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C3), _T (#lib::C4))
-t9 = _Call direct [foo] (x_0)
-t10 = _Join [InterfaceType(Object*)] (_T (#lib::C3), _T (#lib::C4))
+t6 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t7 = _Call direct [#lib::C4.] (_T (#lib::C4))
+x_0 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C4))
+t9 = _Call direct [#lib::foo] (x_0)
+t10 = _Join [dart.core::Object*] (_T (#lib::C3), _T (#lib::C4))
t11 = _Narrow (t10 to _T (dart.core::Object)+?)
-t12 = _Call direct [bar] (t11)
+t12 = _Call direct [#lib::bar] (t11)
RESULT: _T {}?
------------ conditional2 ------------
%cond1 = _Parameter #0 [_T (dart.core::bool)+?]
%cond2 = _Parameter #1 [_T (dart.core::bool)+?]
-t2 = _Call direct [C1::] (_T (#lib::C1))
-t3 = _Call direct [C2::] (_T (#lib::C2))
-t4* = _Call direct [foo] (_T (#lib::C2))
+t2 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t4* = _Call direct [#lib::foo] (_T (#lib::C2))
t5 = _TypeCheck (t4 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t6 = _Call direct [C3::] (_T (#lib::C3))
-t7 = _Call direct [C4::] (_T (#lib::C4))
-t8* = _Call direct [foo] (_T (dart.core::_GrowableList<#lib::C4*>))
-t9 = _Call direct [foo] (_T (#lib::C3))
-t10 = _Join [DynamicType(dynamic)] (_T (#lib::C3), t8)
-t11 = _Call direct [bar] (t10)
+t6 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t7 = _Call direct [#lib::C4.] (_T (#lib::C4))
+t8* = _Call direct [#lib::foo] (_T (dart.core::_GrowableList<#lib::C4*>))
+t9 = _Call direct [#lib::foo] (_T (#lib::C3))
+t10 = _Join [dynamic] (_T (#lib::C3), t8)
+t11 = _Call direct [#lib::bar] (t10)
RESULT: _T {}?
------------ loop1 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C2))
-t2* = _Call direct [foo] (x_0)
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
+t2* = _Call direct [#lib::foo] (x_0)
t3 = _TypeCheck (t2 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t4 = _Call direct [C2::] (_T (#lib::C2))
-t5 = _Call direct [bar] (x_0)
+t4 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t5 = _Call direct [#lib::bar] (x_0)
RESULT: x_0
------------ loop2 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C3))
-t2 = _Call direct [foo] (x_0)
-t3 = _Call direct [C2::] (_T (#lib::C2))
-t4 = _Call direct [bar] (_T (#lib::C2))
-t5 = _Call direct [C3::] (_T (#lib::C3))
-t6* = _Call direct [bar] (_T (#lib::C3))
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C3))
+t2 = _Call direct [#lib::foo] (x_0)
+t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t4 = _Call direct [#lib::bar] (_T (#lib::C2))
+t5 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t6* = _Call direct [#lib::bar] (_T (#lib::C3))
t7 = _TypeCheck (t6 against dart.core::bool*) (for AsExpression(bar, as bool*))
RESULT: _T (#lib::C3)
------------ loop3 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-t1 = _Call direct [C2::] (_T (#lib::C2))
-t2* = _Call direct [foo] (_T (#lib::C2))
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t2* = _Call direct [#lib::foo] (_T (#lib::C2))
t3 = _TypeCheck (t2 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t4 = _Call direct [C3::] (_T (#lib::C3))
-t5 = _Call direct [bar] (_T (#lib::C2))
+t4 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t5 = _Call direct [#lib::bar] (_T (#lib::C2))
RESULT: _T (#lib::C2)
------------ loop4 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-t1 = _Call direct [C2::] (_T (#lib::C2))
-t2 = _Call direct [foo] (_T (#lib::C2))
-t3* = _Call get [Iterable::iterator] (_T (dart.core::_GrowableList<DynamicType(dynamic)?>))
-t4* = _Call [Iterator::moveNext] (t3)
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t2 = _Call direct [#lib::foo] (_T (#lib::C2))
+t3* = _Call get [dart.core::Iterable.iterator] (_T (dart.core::_GrowableList<DynamicType(dynamic)?>))
+t4* = _Call [dart.core::Iterator.moveNext] (t3)
t5 = _Narrow (t3 to _T ANY)
-t6 = _Call get [Iterator::current] (t5)
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C2), _T (#lib::C3))
-t8 = _Call direct [foo] (x_0)
-t9 = _Call direct [C3::] (_T (#lib::C3))
+t6 = _Call get [dart.core::Iterator.current] (t5)
+x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C3))
+t8 = _Call direct [#lib::foo] (x_0)
+t9 = _Call direct [#lib::C3.] (_T (#lib::C3))
RESULT: x_0
------------ loop5 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C3))
-t2* = _Call direct [foo] (x_0)
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C3))
+t2* = _Call direct [#lib::foo] (x_0)
t3 = _TypeCheck (t2 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t4 = _Call direct [C2::] (_T (#lib::C2))
-t5* = _Call direct [bar] (_T (#lib::C2))
+t4 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t5* = _Call direct [#lib::bar] (_T (#lib::C2))
t6 = _TypeCheck (t5 against dart.core::bool*) (for AsExpression(bar, as bool*))
-t7 = _Call direct [C3::] (_T (#lib::C3))
-x_1 = _Join [DynamicType(dynamic)] (x_0, _T (#lib::C2))
+t7 = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_1 = _Join [dynamic] (x_0, _T (#lib::C2))
RESULT: x_1
------------ loop6 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-x_1 = _Join [DynamicType(dynamic)] (_T (#lib::C3), _T (#lib::C2))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C1), x_1)
-t3* = _Call direct [foo] (x_0)
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+x_1 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C2))
+x_0 = _Join [dynamic] (_T (#lib::C1), x_1)
+t3* = _Call direct [#lib::foo] (x_0)
t4 = _TypeCheck (t3 against dart.core::bool*) (for AsExpression(foo, as bool*))
-t5 = _Call direct [C2::] (_T (#lib::C2))
-t6* = _Call direct [bar] (_T (#lib::C2))
+t5 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t6* = _Call direct [#lib::bar] (_T (#lib::C2))
t7 = _TypeCheck (t6 against dart.core::bool*) (for AsExpression(bar, as bool*))
-t8 = _Call direct [C3::] (_T (#lib::C3))
+t8 = _Call direct [#lib::C3.] (_T (#lib::C3))
RESULT: x_0
------------ try1 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-t1 = _Call direct [C2::] (_T (#lib::C2))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C2), _T (#lib::C3))
-t3 = _Call direct [foo] (x_0)
-t4 = _Call direct [C3::] (_T (#lib::C3))
-t5 = _Call direct [bar] (x_0)
-t6 = _Call direct [C4::] (_T (#lib::C4))
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t1 = _Call direct [#lib::C2.] (_T (#lib::C2))
+x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2), _T (#lib::C3))
+t3 = _Call direct [#lib::foo] (x_0)
+t4 = _Call direct [#lib::C3.] (_T (#lib::C3))
+t5 = _Call direct [#lib::bar] (x_0)
+t6 = _Call direct [#lib::C4.] (_T (#lib::C4))
RESULT: _T (#lib::C4)
------------ closure1 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C2))
-t2 = _Call direct [foo] (x_0)
-t3 = _Call direct [bar] (x_0)
-t4 = _Call direct [foo] (_T ANY?)
-t5 = _Call direct [C2::] (_T (#lib::C2))
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
+t2 = _Call direct [#lib::foo] (x_0)
+t3 = _Call direct [#lib::bar] (x_0)
+t4 = _Call direct [#lib::foo] (_T ANY?)
+t5 = _Call direct [#lib::C2.] (_T (#lib::C2))
RESULT: _T {}?
------------ closure2 ------------
-t0 = _Call direct [C1::] (_T (#lib::C1))
-x_0 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C2))
-t2 = _Call direct [foo] (x_0)
-t3 = _Call direct [C2::] (_T (#lib::C2))
-t4 = _Call direct [foo] (_T ANY?)
+t0 = _Call direct [#lib::C1.] (_T (#lib::C1))
+x_0 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
+t2 = _Call direct [#lib::foo] (x_0)
+t3 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t4 = _Call direct [#lib::foo] (_T ANY?)
RESULT: x_0
------------ switch1 ------------
%selector = _Parameter #0 [_T (dart.core::int)+?]
-t1 = _Call direct [C1::] (_T (#lib::C1))
-t2 = _Call direct [C2::] (_T (#lib::C2))
-t3 = _Call direct [C3::] (_T (#lib::C3))
-x_2 = _Join [DynamicType(dynamic)] (_T (#lib::C3), _T (#lib::C1))
-x_3 = _Join [DynamicType(dynamic)] (x_2, _T (#lib::C2))
+t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t3 = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_2 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C1))
+x_3 = _Join [dynamic] (x_2, _T (#lib::C2))
RESULT: x_3
------------ switch2 ------------
%selector = _Parameter #0 [_T (dart.core::int)+?]
-t1 = _Call direct [C1::] (_T (#lib::C1))
-t2 = _Call direct [C2::] (_T (#lib::C2))
-t3 = _Call direct [C3::] (_T (#lib::C3))
-x_2 = _Join [DynamicType(dynamic)] (_T (#lib::C3), _T (#lib::C2))
+t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
+t3 = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_2 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C2))
RESULT: x_2
------------ switch3 ------------
%selector = _Parameter #0 [_T (dart.core::int)+?]
-t1 = _Call direct [C1::] (_T (#lib::C1))
-t2 = _Call direct [C2::] (_T (#lib::C2))
-x_1 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C2))
-t4 = _Call direct [foo] (x_1)
-t5 = _Call direct [C3::] (_T (#lib::C3))
-x_2 = _Join [DynamicType(dynamic)] (_T (#lib::C1), _T (#lib::C3))
+t1 = _Call direct [#lib::C1.] (_T (#lib::C1))
+t2 = _Call direct [#lib::C2.] (_T (#lib::C2))
+x_1 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C2))
+t4 = _Call direct [#lib::foo] (x_1)
+t5 = _Call direct [#lib::C3.] (_T (#lib::C3))
+x_2 = _Join [dynamic] (_T (#lib::C1), _T (#lib::C3))
RESULT: x_2
------------ cast1 ------------
%x = _Parameter #0 [_T ANY?]
t1 = _TypeCheck (%x against #lib::C1*) (for AsExpression( as C1*))
-t2 = _Call direct [foo] (t1)
-t3 = _Call direct [bar] (t1)
+t2 = _Call direct [#lib::foo] (t1)
+t3 = _Call direct [#lib::bar] (t1)
RESULT: _T {}?
------------ main ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart.expect
index c7ac584..436841d 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart.expect
@@ -1,4 +1,4 @@
------------ main ------------
%args = _Parameter #0 [_T (dart.core::List)+?]
-t1 = _Call direct [print] (_T (dart.core::_OneByteString, Hello, world!))
+t1 = _Call direct [dart.core::print] (_T (dart.core::_OneByteString, Hello, world!))
RESULT: _T {}?
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
index 5e1a025..b584c86 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
@@ -1,6 +1,6 @@
------------- T:: ------------
+------------ T. ------------
%this = _Parameter #0 [_T (#lib::T)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------ empty1 ------------
@@ -15,34 +15,34 @@
RESULT: _T {}?
------------ return1 ------------
-t0 = _Call direct [T::] (_T (#lib::T))
+t0 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T (#lib::T)
------------ return2 ------------
%i = _Parameter #0 [_T (dart.core::int)+?]
-t1* = _Call [num::-] (%i, _T (dart.core::_Smi, 1))
-t2* = _Call direct [return2] (t1)
+t1* = _Call [dart.core::num.-] (%i, _T (dart.core::_Smi, 1))
+t2* = _Call direct [#lib::return2] (t1)
RESULT: t2
------------ return3 ------------
-t0 = _Call direct [T::] (_T (#lib::T))
+t0 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T (#lib::T)
------------ return4 ------------
RESULT: _T {}?
------------ expr1 ------------
-t0 = _Call direct [T::] (_T (#lib::T))
+t0 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T {}?
------------ expr2 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [T::] (_T (#lib::T))
-t2 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t1 = _Call direct [#lib::T.] (_T (#lib::T))
+t2 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ expr3 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
%x = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [T::] (_T (#lib::T))
-t3 = _Call [Object::toString] (%x)
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t2 = _Call direct [#lib::T.] (_T (#lib::T))
+t3 = _Call [dart.core::Object.toString] (%x)
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ throw1 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
@@ -51,7 +51,7 @@
------------ throw2 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
%x = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [T::] (_T (#lib::T))
+t2 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T (#lib::T)
------------ loop1 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
@@ -60,29 +60,29 @@
------------ loop2 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
%x = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t2 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ loop3 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
%x = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t2 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ switch_ ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
%i = _Parameter #1 [_T (dart.core::int)+?]
-t2 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t2 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ if1 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [T::] (_T (#lib::T))
+t1 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T (#lib::T)
------------ if2 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t1 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ if3 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
@@ -92,41 +92,41 @@
RESULT: _T {}?
------------ if5 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
-t1* = _Call direct [if5] (_T (dart.core::bool, true))
-t2* = _Call direct [if5] (_T (dart.core::bool))
-%result = _Join [VoidType(void)] (t1, t2, _T {}?)
+t1* = _Call direct [#lib::if5] (_T (dart.core::bool, true))
+t2* = _Call direct [#lib::if5] (_T (dart.core::bool))
+%result = _Join [void] (t1, t2, _T {}?)
RESULT: %result
------------ label1 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t1 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ try1 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t1 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ try2 ------------
-t0 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t0 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ try3 ------------
-t0 = _Call direct [T::] (_T (#lib::T))
+t0 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T (#lib::T)
------------ try4 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [T::] (_T (#lib::T))
-%result = _Join [DynamicType(dynamic)] (_T (#lib::T), _T {}?)
+t1 = _Call direct [#lib::T.] (_T (#lib::T))
+%result = _Join [dynamic] (_T (#lib::T), _T {}?)
RESULT: %result
------------ try5 ------------
-t0 = _Call direct [T::] (_T (#lib::T))
+t0 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T (#lib::T)
------------ try6 ------------
-t0 = _Call direct [T::] (_T (#lib::T))
+t0 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T (#lib::T)
------------ try7 ------------
%c = _Parameter #0 [_T (dart.core::bool)+?]
-t1 = _Call direct [T::] (_T (#lib::T))
+t1 = _Call direct [#lib::T.] (_T (#lib::T))
RESULT: _T (#lib::T)
------------ main ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/params.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/params.dart.expect
index 9de3345..2ec35bd 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/params.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/params.dart.expect
@@ -123,18 +123,18 @@
%x7 = _Parameter #6 [_T ANY?]
%x8 = _Parameter #7 [_T ANY?]
%x9 = _Parameter #8 [_T ANY?]
-t9 = _Call direct [t1] (%x1, %x2, %x3)
-t10 = _Call direct [t2] (%x1, %x2, %x3)
-t11 = _Call direct [t3] (%x1, %x2, %x3)
-t12 = _Call direct [t3] (%x1, %x2, %x3, %x4)
-t13 = _Call direct [t4] (%x1, %x2, %x3, %x4, %x5)
-t14 = _Call direct [t5] (%x1, %x2, %x3)
-t15 = _Call direct [t5] (%x1, %x2, %x3, a4: %x4)
-t16 = _Call direct [t5] (%x1, %x2, %x3, a5: %x4)
-t17 = _Call direct [t5] (%x1, %x2, %x3, a5: %x5, a6: %x4)
-t18 = _Call direct [t6] (%x1, %x2, %x3, a4: %x4, a6: %x5)
-t19 = _Call direct [t6] (%x1, %x2, %x3, a4: %x4, a5: %x5, a6: %x6)
-t20 = _Call direct [t7] (%x1, %x2, %x3, a4: %x4, a5: %x6, a6: %x5)
+t9 = _Call direct [#lib::t1] (%x1, %x2, %x3)
+t10 = _Call direct [#lib::t2] (%x1, %x2, %x3)
+t11 = _Call direct [#lib::t3] (%x1, %x2, %x3)
+t12 = _Call direct [#lib::t3] (%x1, %x2, %x3, %x4)
+t13 = _Call direct [#lib::t4] (%x1, %x2, %x3, %x4, %x5)
+t14 = _Call direct [#lib::t5] (%x1, %x2, %x3)
+t15 = _Call direct [#lib::t5] (%x1, %x2, %x3, a4: %x4)
+t16 = _Call direct [#lib::t5] (%x1, %x2, %x3, a5: %x4)
+t17 = _Call direct [#lib::t5] (%x1, %x2, %x3, a5: %x5, a6: %x4)
+t18 = _Call direct [#lib::t6] (%x1, %x2, %x3, a4: %x4, a6: %x5)
+t19 = _Call direct [#lib::t6] (%x1, %x2, %x3, a4: %x4, a5: %x5, a6: %x6)
+t20 = _Call direct [#lib::t7] (%x1, %x2, %x3, a4: %x4, a5: %x6, a6: %x5)
RESULT: _T {}?
------------ main ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
index f2ab39c..fd53b5e 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/setter_result.dart.expect
@@ -1,48 +1,48 @@
------------- T:: ------------
+------------ T. ------------
%this = _Parameter #0 [_T (#lib::T)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- A:: ------------
+------------ A. ------------
%this = _Parameter #0 [_T (#lib::A)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- A::foo ------------
+------------ A.foo ------------
%this = _Parameter #0 [_T (#lib::A)+]
RESULT: _T {}?
------------- B:: ------------
+------------ B. ------------
%this = _Parameter #0 [_T (#lib::B)+]
-t1 = _Call direct [A::] (%this)
+t1 = _Call direct [#lib::A.] (%this)
RESULT: _T {}?
------------- B::foo ------------
+------------ B.foo ------------
%this = _Parameter #0 [_T (#lib::B)+]
%x = _Parameter #1 [_T ANY?]
RESULT: _T {}?
------------- B::testPropertySet ------------
+------------ B.testPropertySet ------------
%this = _Parameter #0 [_T (#lib::B)+]
%x = _Parameter #1 [_T ANY?]
-t2 = _Call virtual set [B::foo] (%this, %x)
-t3 = _Call direct [use] (%x)
+t2 = _Call virtual set [#lib::B.foo] (%this, %x)
+t3 = _Call direct [#lib::use] (%x)
RESULT: _T {}?
------------- B::testDynamicPropertySet ------------
+------------ B.testDynamicPropertySet ------------
%this = _Parameter #0 [_T (#lib::B)+]
%x = _Parameter #1 [_T ANY?]
%y = _Parameter #2 [_T ANY?]
t3 = _Call dynamic set [foo] (%x, %y)
-t4 = _Call direct [use] (%y)
+t4 = _Call direct [#lib::use] (%y)
RESULT: _T {}?
------------- B::testSuperPropertySet ------------
+------------ B.testSuperPropertySet ------------
%this = _Parameter #0 [_T (#lib::B)+]
%x = _Parameter #1 [_T ANY?]
-t2 = _Call direct set [A::foo] (%this, %x)
-t3 = _Call direct [use] (%x)
+t2 = _Call direct set [#lib::A.foo] (%this, %x)
+t3 = _Call direct [#lib::use] (%x)
RESULT: _T {}?
------------- B::testStaticPropertySet ------------
+------------ B.testStaticPropertySet ------------
%this = _Parameter #0 [_T (#lib::B)+]
%x = _Parameter #1 [_T ANY?]
-t2 = _Call direct set [B::bar] (%x)
-t3 = _Call direct [use] (%x)
+t2 = _Call direct set [#lib::B.bar] (%x)
+t3 = _Call direct [#lib::use] (%x)
RESULT: _T {}?
------------- B::bar ------------
+------------ B.bar ------------
RESULT: _T {}?
------------ use ------------
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
index c1d9b3f..d46d957 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
@@ -1,44 +1,44 @@
------------- A:: ------------
+------------ A. ------------
%this = _Parameter #0 [_T (#lib::A)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------- B:: ------------
+------------ B. ------------
%this = _Parameter #0 [_T (#lib::B)+]
-t1 = _Call direct [Object::] (%this)
+t1 = _Call direct [dart.core::Object.] (%this)
RESULT: _T {}?
------------ foo ------------
%a1 = _Parameter #0 [_T (dart.core::Object)+?]
%a2 = _Parameter #1 [_T (dart.core::Object)+?]
-t2* = _Call direct get [someStatic] ()
-t3 = _Call direct [A::] (_T (#lib::A))
-a1_0 = _Join [InterfaceType(Object*)] (_T (#lib::A), %a1)
-t5 = _Call direct [bar] (a1_0, _T (dart.core::_Smi, 42))
-t6 = _Call direct [B::] (_T (#lib::B))
-t7* = _Call [Object::==] (_T (#lib::B), %a2)
-t8 = _Join [InterfaceType(Object*)] (_T (#lib::B), %a2)
+t2* = _Call direct get [#lib::someStatic] ()
+t3 = _Call direct [#lib::A.] (_T (#lib::A))
+a1_0 = _Join [dart.core::Object*] (_T (#lib::A), %a1)
+t5 = _Call direct [#lib::bar] (a1_0, _T (dart.core::_Smi, 42))
+t6 = _Call direct [#lib::B.] (_T (#lib::B))
+t7* = _Call [dart.core::Object.==] (_T (#lib::B), %a2)
+t8 = _Join [dart.core::Object*] (_T (#lib::B), %a2)
t9 = _Narrow (t8 to _T (dart.core::Object)+?)
RESULT: t9
------------ bar ------------
%a1 = _Parameter #0 [_T (dart.core::Object)+?]
%a2 = _Parameter #1 [_T (dart.core::int)+?]
t2 = _Narrow (%a1 to _T (dart.core::int)+)
-t3* = _Call [num::+] (t2, %a2)
-t4* = _Call [num::*] (t3, _T (dart.core::_Smi, 3))
-t5* = _Call [int::unary-] (_T (dart.core::_Smi, 1))
-%result = _Join [InterfaceType(int*)] (t4, t5)
+t3* = _Call [dart.core::num.+] (t2, %a2)
+t4* = _Call [dart.core::num.*] (t3, _T (dart.core::_Smi, 3))
+t5* = _Call [dart.core::int.unary-] (_T (dart.core::_Smi, 1))
+%result = _Join [dart.core::int*] (t4, t5)
RESULT: %result
------------ loop1 ------------
%a1 = _Parameter #0 [_T (dart.core::Object)+?]
%a2 = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct [loop1] (%a1, %a1)
+t2 = _Call direct [#lib::loop1] (%a1, %a1)
RESULT: %a2
------------ loop2 ------------
%x = _Parameter #0 [_T (dart.core::int)+?]
-t1* = _Call [num::+] (_T (dart.core::int)+, _T (dart.core::_Smi, 1))
-i_0 = _Join [InterfaceType(int*)] (_T (dart.core::_Smi, 0), t1)
-t3* = _Call [num::<] (i_0, _T (dart.core::_Smi, 5))
-t4* = _Call [num::+] (_T (dart.core::int)+?, _T (dart.core::_Smi, 10))
-x_0 = _Join [InterfaceType(int*)] (%x, t4)
+t1* = _Call [dart.core::num.+] (_T (dart.core::int)+, _T (dart.core::_Smi, 1))
+i_0 = _Join [dart.core::int*] (_T (dart.core::_Smi, 0), t1)
+t3* = _Call [dart.core::num.<] (i_0, _T (dart.core::_Smi, 5))
+t4* = _Call [dart.core::num.+] (_T (dart.core::int)+?, _T (dart.core::_Smi, 10))
+x_0 = _Join [dart.core::int*] (%x, t4)
RESULT: x_0
------------ main ------------
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 fca9065..8d458eb 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -30,11 +30,11 @@
}
[@vm.unboxing-info.metadata=(b)->i]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=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] x.{core::num::+}(2);
+ return [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] x.{core::num::+}(2);
}
@#C11
static method main(core::List<core::String*>* args) → dynamic {
self::A::staticMethod();
- [@vm.direct-call.metadata=B::instanceMethod] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::instanceMethod}();
+ [@vm.direct-call.metadata=B.instanceMethod] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::instanceMethod}();
self::foo(null);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
index a00d5c0..f0189f9 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
@@ -27,13 +27,13 @@
return;
}
on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
- [@vm.direct-call.metadata=_AsyncAwaitCompleter::completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+ [@vm.direct-call.metadata=_AsyncAwaitCompleter.completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
}
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
:async_op_then = asy::_asyncThenWrapperHelper(:async_op);
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
- [@vm.direct-call.metadata=_AsyncAwaitCompleter::start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
- return [@vm.direct-call.metadata=_AsyncAwaitCompleter::future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+ [@vm.direct-call.metadata=_AsyncAwaitCompleter.start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return [@vm.direct-call.metadata=_AsyncAwaitCompleter.future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
}
}
class B extends core::Object {
@@ -62,13 +62,13 @@
return;
}
on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
- [@vm.direct-call.metadata=_AsyncAwaitCompleter::completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+ [@vm.direct-call.metadata=_AsyncAwaitCompleter.completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
}
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
:async_op_then = asy::_asyncThenWrapperHelper(:async_op);
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
- [@vm.direct-call.metadata=_AsyncAwaitCompleter::start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
- return [@vm.direct-call.metadata=_AsyncAwaitCompleter::future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+ [@vm.direct-call.metadata=_AsyncAwaitCompleter.start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return [@vm.direct-call.metadata=_AsyncAwaitCompleter.future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
}
static method main() → dynamic /* originally async */ {
final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
@@ -86,18 +86,18 @@
{
:async_temporary_0 = [@vm.inferred-type.metadata=#lib::A] self::foo();
[yield] let dynamic #t1 = asy::_awaitHelper([@vm.inferred-type.metadata=dart.async::_Future] self::baz(), :async_op_then, :async_op_error, :async_op) in null;
- [yield] let dynamic #t2 = asy::_awaitHelper([@vm.direct-call.metadata=A::bar??] [@vm.inferred-type.metadata=dart.async::_Future (receiver not int)] _in::unsafeCast<dynamic>(:async_temporary_0).bar(:result), :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t2 = asy::_awaitHelper([@vm.direct-call.metadata=A.bar??] [@vm.inferred-type.metadata=dart.async::_Future (receiver not int)] _in::unsafeCast<dynamic>(:async_temporary_0).bar(:result), :async_op_then, :async_op_error, :async_op) in null;
:result;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
return;
}
on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
- [@vm.direct-call.metadata=_AsyncAwaitCompleter::completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+ [@vm.direct-call.metadata=_AsyncAwaitCompleter.completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
}
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
:async_op_then = asy::_asyncThenWrapperHelper(:async_op);
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
- [@vm.direct-call.metadata=_AsyncAwaitCompleter::start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
- return [@vm.direct-call.metadata=_AsyncAwaitCompleter::future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+ [@vm.direct-call.metadata=_AsyncAwaitCompleter.start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return [@vm.direct-call.metadata=_AsyncAwaitCompleter.future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
}
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 839a730..7857d67 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
@@ -4,19 +4,19 @@
import "dart:_internal" as _in;
[@vm.unboxing-info.metadata=(i)->b]static method isPrime([@vm.inferred-type.metadata=int] dynamic n) → core::bool* {
- if(_in::unsafeCast<core::bool*>([@vm.direct-call.metadata=_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool] n.<(2)))
+ if(_in::unsafeCast<core::bool*>([@vm.direct-call.metadata=_IntegerImplementation.<] [@vm.inferred-type.metadata=dart.core::bool] n.<(2)))
return false;
- for (core::int* i = 2; [@vm.direct-call.metadata=_IntegerImplementation::<=] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=_IntegerImplementation::*] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::*}(i).{core::num::<=}(_in::unsafeCast<core::num>(n)); i = [@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
- if([@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=_IntegerImplementation::%] [@vm.inferred-type.metadata=int] n.%(i).{core::Object::==}(0))
+ for (core::int* i = 2; [@vm.direct-call.metadata=_IntegerImplementation.<=] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=_IntegerImplementation.*] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::*}(i).{core::num::<=}(_in::unsafeCast<core::num>(n)); i = [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
+ if([@vm.direct-call.metadata=_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=_IntegerImplementation.%] [@vm.inferred-type.metadata=int] n.%(i).{core::Object::==}(0))
return false;
}
return true;
}
[@vm.unboxing-info.metadata=(i)->b]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=_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
+ for (core::int* i = 1; ; i = [@vm.direct-call.metadata=_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
if([@vm.inferred-type.metadata=dart.core::bool] self::isPrime(i))
- counter = [@vm.direct-call.metadata=_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] counter.{core::num::+}(1);
+ counter = [@vm.direct-call.metadata=_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] counter.{core::num::+}(1);
if([@vm.inferred-type.metadata=dart.core::bool] counter.{core::num::==}(n)) {
return i;
}
@@ -30,10 +30,10 @@
}
}
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=Stopwatch::start] [@vm.inferred-type.metadata=!? (skip check)] #t1.{core::Stopwatch::start}() in #t1;
- for (core::int* i = 0; [@vm.direct-call.metadata=_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100); i = [@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
+ core::Stopwatch* timer = let final core::Stopwatch #t1 = new core::Stopwatch::•() in let final void #t2 = [@vm.direct-call.metadata=Stopwatch.start] [@vm.inferred-type.metadata=!? (skip check)] #t1.{core::Stopwatch::start}() in #t1;
+ for (core::int* i = 0; [@vm.direct-call.metadata=_IntegerImplementation.<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100); i = [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
self::run();
}
- [@vm.direct-call.metadata=Stopwatch::stop] [@vm.inferred-type.metadata=!? (skip check)] timer.{core::Stopwatch::stop}();
- core::print("Elapsed ${[@vm.direct-call.metadata=Stopwatch::elapsedMilliseconds] timer.{core::Stopwatch::elapsedMilliseconds}}ms");
+ [@vm.direct-call.metadata=Stopwatch.stop] [@vm.inferred-type.metadata=!? (skip check)] timer.{core::Stopwatch::stop}();
+ core::print("Elapsed ${[@vm.direct-call.metadata=Stopwatch.elapsedMilliseconds] timer.{core::Stopwatch::elapsedMilliseconds}}ms");
}
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 e934ac4..d40f897 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
@@ -13,24 +13,24 @@
: 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] [@vm.unboxing-info.metadata=(b)->d] operator []([@vm.inferred-type.metadata=!] core::int* i) → core::double*
- return [@vm.direct-call.metadata=_Float64List::[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}([@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}([@vm.direct-call.metadata=_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi (value: 0)] this.{self::_Vector::_offset}));
+ return [@vm.direct-call.metadata=_Float64List.[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=_Vector._elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}([@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}([@vm.direct-call.metadata=_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 {
- let dynamic #t1 = [@vm.direct-call.metadata=_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements} in let dynamic #t2 = [@vm.direct-call.metadata=_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)";
+ let dynamic #t1 = [@vm.direct-call.metadata=_Vector._elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements} in let dynamic #t2 = [@vm.direct-call.metadata=_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] [@vm.unboxing-info.metadata=(b)->d] 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=_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}([@vm.direct-call.metadata=_Vector::_length] [@vm.inferred-type.metadata=dart.core::_Smi (value: 10)] this.{self::_Vector::_length}); i = [@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1))
- result = [@vm.direct-call.metadata=_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] result.{core::double::+}([@vm.direct-call.metadata=_Double::*] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=_Vector::[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] this.{self::_Vector::[]}(i).{core::double::*}([@vm.direct-call.metadata=_Vector::[]??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] a.{self::_Vector::[]}(i)));
+ for (core::int* i = 0; [@vm.direct-call.metadata=_IntegerImplementation.<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}([@vm.direct-call.metadata=_Vector._length] [@vm.inferred-type.metadata=dart.core::_Smi (value: 10)] this.{self::_Vector::_length}); i = [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1))
+ result = [@vm.direct-call.metadata=_Double.+??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] result.{core::double::+}([@vm.direct-call.metadata=_Double.*] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=_Vector.[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] this.{self::_Vector::[]}(i).{core::double::*}([@vm.direct-call.metadata=_Vector.[]??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] a.{self::_Vector::[]}(i)));
return result;
}
}
[@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 {
- core::Stopwatch* timer = let final core::Stopwatch #t3 = new core::Stopwatch::•() in let final void #t4 = [@vm.direct-call.metadata=Stopwatch::start] [@vm.inferred-type.metadata=!? (skip check)] #t3.{core::Stopwatch::start}() in #t3;
- for (core::int* i = 0; [@vm.direct-call.metadata=_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100000000); i = [@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
- self::x = [@vm.direct-call.metadata=_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=_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));
+ core::Stopwatch* timer = let final core::Stopwatch #t3 = new core::Stopwatch::•() in let final void #t4 = [@vm.direct-call.metadata=Stopwatch.start] [@vm.inferred-type.metadata=!? (skip check)] #t3.{core::Stopwatch::start}() in #t3;
+ for (core::int* i = 0; [@vm.direct-call.metadata=_IntegerImplementation.<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100000000); i = [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
+ self::x = [@vm.direct-call.metadata=_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=_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));
}
- [@vm.direct-call.metadata=Stopwatch::stop] [@vm.inferred-type.metadata=!? (skip check)] timer.{core::Stopwatch::stop}();
- core::print("Elapsed ${[@vm.direct-call.metadata=Stopwatch::elapsedMilliseconds] timer.{core::Stopwatch::elapsedMilliseconds}}ms, result ${self::x}");
+ [@vm.direct-call.metadata=Stopwatch.stop] [@vm.inferred-type.metadata=!? (skip check)] timer.{core::Stopwatch::stop}();
+ core::print("Elapsed ${[@vm.direct-call.metadata=Stopwatch.elapsedMilliseconds] timer.{core::Stopwatch::elapsedMilliseconds}}ms, result ${self::x}");
}
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 7598d3f..bb31725 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
@@ -63,14 +63,14 @@
return x;
}
static method main() → dynamic {
- core::print([@vm.direct-call.metadata=C::foo] [@vm.inferred-type.metadata=#lib::D<InterfaceType(int*)> (skip check)] new self::C::•<core::int*>().{self::C::foo}());
- core::print([@vm.direct-call.metadata=E::foo] [@vm.inferred-type.metadata=#lib::D<InterfaceType(String*)> (skip check)] new self::E::•<core::int*, core::String*>().{self::E::foo}());
- core::print([@vm.direct-call.metadata=E::bar] [@vm.inferred-type.metadata=#lib::D<InterfaceType(int*)> (skip check)] new self::E::•<core::int*, core::String*>().{self::E::bar}());
- core::print([@vm.direct-call.metadata=E::baz] [@vm.inferred-type.metadata=#lib::D<InterfaceType(String*)> (skip check)] new self::E::•<core::int*, core::String*>().{self::E::baz}());
+ core::print([@vm.direct-call.metadata=C.foo] [@vm.inferred-type.metadata=#lib::D<InterfaceType(int*)> (skip check)] new self::C::•<core::int*>().{self::C::foo}());
+ core::print([@vm.direct-call.metadata=E.foo] [@vm.inferred-type.metadata=#lib::D<InterfaceType(String*)> (skip check)] new self::E::•<core::int*, core::String*>().{self::E::foo}());
+ core::print([@vm.direct-call.metadata=E.bar] [@vm.inferred-type.metadata=#lib::D<InterfaceType(int*)> (skip check)] new self::E::•<core::int*, core::String*>().{self::E::bar}());
+ core::print([@vm.direct-call.metadata=E.baz] [@vm.inferred-type.metadata=#lib::D<InterfaceType(String*)> (skip check)] new self::E::•<core::int*, core::String*>().{self::E::baz}());
self::C<self::X*>* c = new self::C::•<self::Y*>();
- [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C<X*>*)] [@vm.direct-call.metadata=C::id1] [@vm.inferred-type.metadata=!? (skip check)] c.{self::C::id1}(new self::Y::•());
- [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C<X*>*)] [@vm.direct-call.metadata=C::id2] c.{self::C::id2}(new self::Z::•());
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C<X*>*)] [@vm.direct-call.metadata=C.id1] [@vm.inferred-type.metadata=!? (skip check)] c.{self::C::id1}(new self::Y::•());
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C<X*>*)] [@vm.direct-call.metadata=C.id2] c.{self::C::id2}(new self::Z::•());
self::C2<core::num*>* c2 = new self::C2::•<core::num*>();
- [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C2<num*>*)] [@vm.direct-call.metadata=C2::id3] [@vm.inferred-type.metadata=!? (skip check)] c2.{self::C2::id3}(3.0);
- [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C2<num*>*)] [@vm.direct-call.metadata=C2::id4] [@vm.inferred-type.metadata=!? (skip check)] c2.{self::C2::id4}(new self::K::•<self::J*>());
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C2<num*>*)] [@vm.direct-call.metadata=C2.id3] [@vm.inferred-type.metadata=!? (skip check)] c2.{self::C2::id3}(3.0);
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C2<num*>*)] [@vm.direct-call.metadata=C2.id4] [@vm.inferred-type.metadata=!? (skip check)] c2.{self::C2::id4}(new self::K::•<self::J*>());
}
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 ae04116..31c6266 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
@@ -15,11 +15,11 @@
: 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.call-site-attributes.metadata=receiverType:InterfaceType(Map<Element*, Object*>*)] [@vm.direct-call.metadata=__InternalLinkedHashMap&_HashVMBase&MapMixin&_LinkedHashMapMixin::[]=] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=InheritedElement::_dependents] [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<InterfaceType(Element*), InterfaceType(Object*)>] this.{self::InheritedElement::_dependents}.{core::Map::[]=}(dependent, value);
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(Map<Element*, Object*>*)] [@vm.direct-call.metadata=__InternalLinkedHashMap&_HashVMBase&MapMixin&_LinkedHashMapMixin.[]=] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=InheritedElement._dependents] [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<InterfaceType(Element*), InterfaceType(Object*)>] this.{self::InheritedElement::_dependents}.{core::Map::[]=}(dependent, value);
}
}
static method main() → dynamic {
self::InheritedElement* ie = new self::InheritedElement::•();
- [@vm.direct-call.metadata=InheritedElement::setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(ie, 0);
- [@vm.direct-call.metadata=InheritedElement::setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(new self::Element::•(), null);
+ [@vm.direct-call.metadata=InheritedElement.setDependencies] [@vm.inferred-type.metadata=!? (skip check)] ie.{self::InheritedElement::setDependencies}(ie, 0);
+ [@vm.direct-call.metadata=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 a06f14d..4df916d 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
@@ -33,8 +33,8 @@
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 {
- core::print([@vm.direct-call.metadata=A::foo] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: foo)] a0.{self::A::foo});
- core::print([@vm.direct-call.metadata=A::getBar] [@vm.inferred-type.metadata=dart.core::_OneByteString (skip check) (value: bar)] a0.{self::A::getBar}());
+ core::print([@vm.direct-call.metadata=A.foo] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: foo)] a0.{self::A::foo});
+ core::print([@vm.direct-call.metadata=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 {
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 87813fc..0c61a33 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -40,16 +40,16 @@
[@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
static method callerA2([@vm.inferred-type.metadata=#lib::B] self::A* aa) → void {
- [@vm.direct-call.metadata=B::foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
+ [@vm.direct-call.metadata=B.foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
static method callerA3([@vm.inferred-type.metadata=#lib::C] self::A* aa) → void {
- [@vm.direct-call.metadata=C::foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
+ [@vm.direct-call.metadata=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.direct-call.metadata=C::foo??] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
+ [@vm.direct-call.metadata=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.direct-call.metadata=_StringBase::toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)] x.{core::Object::toString}();
+ [@vm.direct-call.metadata=_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.inferred-type.metadata=!? (receiver not int)] x.{core::Object::toString}();
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 311cf20..edfeb7b 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
@@ -4,5 +4,5 @@
static method main() → dynamic {
dynamic x = [@vm.inferred-type.metadata=dart.core::_List<InterfaceType(int*)>] core::_List::•<core::int*>(10);
- [@vm.direct-call.metadata=_IntegerImplementation::+??] [@vm.direct-call.metadata=_List::[]] [@vm.inferred-type.metadata=int? (receiver not int)] x.[](0).+(10);
+ [@vm.direct-call.metadata=_IntegerImplementation.+??] [@vm.direct-call.metadata=_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 a5252eb..a75a010 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect
@@ -22,14 +22,14 @@
}
static method main() → dynamic {
dynamic c = new self::C::•<core::int*>();
- [@vm.direct-call.metadata=C::test2c] [@vm.inferred-type.metadata=!? (receiver not int)] c.test2c(3);
- [@vm.direct-call.metadata=C::test3c] [@vm.inferred-type.metadata=!? (receiver not int)] c.test3c([@vm.inferred-type.metadata=dart.async::_Future<InterfaceType(int*)>] asy::Future::value<core::int*>(3));
- [@vm.direct-call.metadata=C::test4c] [@vm.inferred-type.metadata=!? (receiver not int)] c.test4c([@vm.inferred-type.metadata=dart.async::_Future<InterfaceType(int*)>] asy::Future::value<core::int*>(3));
- [@vm.direct-call.metadata=C::test2r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test2r(new self::C::•<core::int*>());
- [@vm.direct-call.metadata=C::test3r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test3r(new self::C::•<asy::Future<core::int*>*>());
- [@vm.direct-call.metadata=C::test4r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test4r(new self::C::•<asy::Future<core::int*>*>());
- [@vm.direct-call.metadata=C::test5r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test5r(new self::C::•<asy::FutureOr<core::int*>*>());
- [@vm.direct-call.metadata=C::test6r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test6r(new self::C::•<asy::FutureOr<core::int*>*>());
- [@vm.direct-call.metadata=C::test7r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test7r(new self::C::•<asy::FutureOr<core::int*>*>());
- [@vm.direct-call.metadata=C::test8r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test8r(new self::C::•<asy::Future<core::int*>*>());
+ [@vm.direct-call.metadata=C.test2c] [@vm.inferred-type.metadata=!? (receiver not int)] c.test2c(3);
+ [@vm.direct-call.metadata=C.test3c] [@vm.inferred-type.metadata=!? (receiver not int)] c.test3c([@vm.inferred-type.metadata=dart.async::_Future<InterfaceType(int*)>] asy::Future::value<core::int*>(3));
+ [@vm.direct-call.metadata=C.test4c] [@vm.inferred-type.metadata=!? (receiver not int)] c.test4c([@vm.inferred-type.metadata=dart.async::_Future<InterfaceType(int*)>] asy::Future::value<core::int*>(3));
+ [@vm.direct-call.metadata=C.test2r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test2r(new self::C::•<core::int*>());
+ [@vm.direct-call.metadata=C.test3r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test3r(new self::C::•<asy::Future<core::int*>*>());
+ [@vm.direct-call.metadata=C.test4r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test4r(new self::C::•<asy::Future<core::int*>*>());
+ [@vm.direct-call.metadata=C.test5r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test5r(new self::C::•<asy::FutureOr<core::int*>*>());
+ [@vm.direct-call.metadata=C.test6r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test6r(new self::C::•<asy::FutureOr<core::int*>*>());
+ [@vm.direct-call.metadata=C.test7r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test7r(new self::C::•<asy::FutureOr<core::int*>*>());
+ [@vm.direct-call.metadata=C.test8r] [@vm.inferred-type.metadata=!? (receiver not int)] c.test8r(new self::C::•<asy::Future<core::int*>*>());
}
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 4b9e704..49806f3 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
@@ -54,7 +54,7 @@
: 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* {
- return [@vm.direct-call.metadata=StreamView::_stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}.{self::Stream::foobar}(onData, onError: onError);
+ return [@vm.direct-call.metadata=StreamView._stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}.{self::Stream::foobar}(onData, onError: onError);
}
}
class ByteStream extends self::StreamView {
@@ -83,32 +83,32 @@
}
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=ByteStream::super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}(onData);
+ [@vm.direct-call.metadata=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 {
new self::_ControllerStream::•();
self::Stream* x = new self::_GeneratedStreamImpl::•();
x = new self::ByteStream::•(x);
- [@vm.direct-call.metadata=StreamView::foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(onData, onError: onError);
+ [@vm.direct-call.metadata=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 {
self::Stream* x = new self::_GeneratedStreamImpl::•();
x = new self::ByteStream::•(x);
x = new self::_ControllerStream::•();
- [@vm.direct-call.metadata=_StreamImpl::foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(onData, onError: onError);
+ [@vm.direct-call.metadata=_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 {
self::ByteStream* x = new self::ByteStream::•(new self::_ControllerStream::•());
- self::Stream* y = [@vm.direct-call.metadata=ByteStream::super_stream] [@vm.inferred-type.metadata=!] x.{self::ByteStream::super_stream};
- self::Stream* z = [@vm.direct-call.metadata=StreamView::_stream] [@vm.inferred-type.metadata=!] x.{self::StreamView::_stream};
- if([@vm.direct-call.metadata=Object::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] y.{self::Stream::==}(z)) {
- [@vm.direct-call.metadata=ByteStream::super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}(onData);
+ self::Stream* y = [@vm.direct-call.metadata=ByteStream.super_stream] [@vm.inferred-type.metadata=!] x.{self::ByteStream::super_stream};
+ self::Stream* z = [@vm.direct-call.metadata=StreamView._stream] [@vm.inferred-type.metadata=!] x.{self::StreamView::_stream};
+ if([@vm.direct-call.metadata=Object.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] y.{self::Stream::==}(z)) {
+ [@vm.direct-call.metadata=ByteStream.super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}(onData);
}
}
static method round5() → void {
self::ByteStream* x = new self::ByteStream::•(new self::_GeneratedStreamImpl::•());
new self::_HandleErrorStream::•();
- [@vm.direct-call.metadata=ByteStream::super_foobar3] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar3}();
+ [@vm.direct-call.metadata=ByteStream.super_foobar3] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar3}();
}
static method main(core::List<core::String*>* args) → dynamic {
new self::_GeneratedStreamImpl::•();
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 cd7fc10..1d52abd 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
@@ -34,11 +34,11 @@
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method barL1() → dynamic
- return [@vm.direct-call.metadata=DeepCaller1::barL2] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL2}();
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller1::barL3] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL3}();
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller1::barL4] [@vm.inferred-type.metadata=!? (skip check)] this.{self::DeepCaller1::barL4}();
+ return [@vm.direct-call.metadata=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
return self::field1;
}
@@ -53,13 +53,13 @@
: 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
- return [@vm.direct-call.metadata=DeepCaller2::barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(dd);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller2::barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(dd);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller2::barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(dd);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=D::field2] [@vm.inferred-type.metadata=!] dd.{self::D::field2};
+ return [@vm.direct-call.metadata=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();
@@ -70,9 +70,9 @@
return [@vm.inferred-type.metadata=!] aa.{self::A::foo}();
}
static method use1([@vm.inferred-type.metadata=#lib::DeepCaller1] self::DeepCaller1* x) → dynamic
- return [@vm.direct-call.metadata=DeepCaller1::barL1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::DeepCaller1::barL1}();
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller2::barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(new self::D::•());
+ return [@vm.direct-call.metadata=DeepCaller2.barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(new self::D::•());
static method createC() → dynamic {
new self::C::•();
}
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 afe3fb1..116da4d 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
@@ -25,13 +25,13 @@
: 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
- return [@vm.direct-call.metadata=B::foo??] [@vm.inferred-type.metadata=#lib::T1 (skip check)] aa.{self::A::foo}();
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=Intermediate::bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=Intermediate::bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa);
+ return [@vm.direct-call.metadata=Intermediate.bar] [@vm.inferred-type.metadata=#lib::T1 (skip check)] i.{self::Intermediate::bar}(aa);
static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:InterfaceType(Function*)] self::unknown.call();
static method allocateB() → dynamic {
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 9f0d0f1..370c5fa 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
@@ -53,11 +53,11 @@
}
[@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
- return [@vm.direct-call.metadata=Intermediate::bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=Intermediate::bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=Intermediate::bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa);
+ return [@vm.direct-call.metadata=Intermediate.bar] [@vm.inferred-type.metadata=! (skip check)] i.{self::Intermediate::bar}(aa);
static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:InterfaceType(Function*)] self::unknown.call();
static method allocateB() → dynamic {
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 2caaaea..4a4b80c 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
@@ -24,36 +24,36 @@
: 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
- return [@vm.direct-call.metadata=DeepCaller1::barL2] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL2}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller1::barL3] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL3}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller1::barL4] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::DeepCaller1::barL4}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=A::field1??] [@vm.inferred-type.metadata=#lib::T1] aa.{self::A::field1};
+ return [@vm.direct-call.metadata=A.field1??] [@vm.inferred-type.metadata=#lib::T1] aa.{self::A::field1};
}
class DeepCaller2 extends core::Object {
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
- return [@vm.direct-call.metadata=DeepCaller2::barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller2::barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller2::barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=A::field2??] [@vm.inferred-type.metadata=!] aa.{self::A::field2};
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller1::barL1] [@vm.inferred-type.metadata=#lib::T1 (skip check)] x.{self::DeepCaller1::barL1}(aa);
+ return [@vm.direct-call.metadata=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
- return [@vm.direct-call.metadata=DeepCaller2::barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(aa);
+ return [@vm.direct-call.metadata=DeepCaller2.barL1] [@vm.inferred-type.metadata=! (skip check)] x.{self::DeepCaller2::barL1}(aa);
static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:InterfaceType(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.direct-call.metadata=A::field2] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::field2} = value;
+ [@vm.direct-call.metadata=A.field2] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::field2} = value;
}
static method main(core::List<core::String*>* args) → dynamic {
new self::A::•();
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 8b5b231..744a7c2 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
@@ -29,7 +29,7 @@
;
}
static method foo1([@vm.inferred-type.metadata=dart.core::_GrowableList<InterfaceType(T1*)>] core::List<self::T1*>* list) → dynamic {
- [@vm.direct-call.metadata=T3::run] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=T1::go??] [@vm.inferred-type.metadata=#lib::T3 (skip check)] [@vm.direct-call.metadata=Q::result??] [@vm.direct-call.metadata=ListIterable::first] [@vm.inferred-type.metadata=#lib::Q?] [@vm.direct-call.metadata=_ListBase&Object&ListMixin::map] [@vm.inferred-type.metadata=dart._internal::MappedListIterable<InterfaceType(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}();
+ [@vm.direct-call.metadata=T3.run] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=T1.go??] [@vm.inferred-type.metadata=#lib::T3 (skip check)] [@vm.direct-call.metadata=Q.result??] [@vm.direct-call.metadata=ListIterable.first] [@vm.inferred-type.metadata=#lib::Q?] [@vm.direct-call.metadata=_ListBase&Object&ListMixin.map] [@vm.inferred-type.metadata=dart._internal::MappedListIterable<InterfaceType(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>*
return new self::Q::•<self::T2*>(new self::T2::•());
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 40d6b7d..da42b86 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
@@ -23,18 +23,18 @@
: 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*
- return new self::Point::•([@vm.direct-call.metadata=Point::x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
+ return new self::Point::•([@vm.direct-call.metadata=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*
- return new self::Point::•([@vm.direct-call.metadata=Point::x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
+ return new self::Point::•([@vm.direct-call.metadata=Point.x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
}
static method getX([@vm.inferred-type.metadata=#lib::Point] dynamic point) → dynamic {
- [@vm.direct-call.metadata=Point::x] [@vm.inferred-type.metadata=!? (receiver not int)] point.x;
+ [@vm.direct-call.metadata=Point.x] [@vm.inferred-type.metadata=!? (receiver not int)] point.x;
}
static method main() → dynamic {
self::Point* a = new self::Point::•(new self::T1::•());
- core::print([@vm.direct-call.metadata=Point::x] [@vm.inferred-type.metadata=!] a.{self::Point::x});
+ core::print([@vm.direct-call.metadata=Point.x] [@vm.inferred-type.metadata=!] a.{self::Point::x});
self::Point* c = new self::Point::•(new self::T2::•());
- [@vm.direct-call.metadata=Point::x] [@vm.inferred-type.metadata=!] c.{self::Point::x}.{self::I::foo}();
- self::getX([@vm.direct-call.metadata=Point::newPoint1] [@vm.inferred-type.metadata=#lib::Point (skip check)] a.{self::Point::newPoint1}());
- self::getX([@vm.direct-call.metadata=Point::newPoint2] [@vm.inferred-type.metadata=#lib::Point (skip check)] a.{self::Point::newPoint2}());
+ [@vm.direct-call.metadata=Point.x] [@vm.inferred-type.metadata=!] c.{self::Point::x}.{self::I::foo}();
+ self::getX([@vm.direct-call.metadata=Point.newPoint1] [@vm.inferred-type.metadata=#lib::Point (skip check)] a.{self::Point::newPoint1}());
+ self::getX([@vm.direct-call.metadata=Point.newPoint2] [@vm.inferred-type.metadata=#lib::Point (skip check)] a.{self::Point::newPoint2}());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
index 208399d..4adf524 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
@@ -18,14 +18,14 @@
[@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] field core::int* x;
constructor •() → self::TestNamedOrderSub*
: self::TestNamedOrderSub::x = [@vm.inferred-type.metadata=int] self::dec(), dynamic #t5 = [@vm.inferred-type.metadata=int] self::inc(), dynamic #t6 = [@vm.inferred-type.metadata=int] self::inc(), dynamic #t7 = [@vm.inferred-type.metadata=int] self::inc(), dynamic #t8 = [@vm.inferred-type.metadata=int] self::dec(), super self::TestNamedOrderBase::•(#t5, #t8, #t7, #t6) {
- exp::Expect::equals([@vm.direct-call.metadata=TestNamedOrderSub::x] [@vm.inferred-type.metadata=int] this.{self::TestNamedOrderSub::x}, 0);
+ exp::Expect::equals([@vm.direct-call.metadata=TestNamedOrderSub.x] [@vm.inferred-type.metadata=int] this.{self::TestNamedOrderSub::x}, 0);
}
}
[@vm.inferred-type.metadata=int?]static field core::int* global = 0;
[@vm.unboxing-info.metadata=()->i]static method inc() → core::int*
- return self::global = [@vm.direct-call.metadata=_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::+}(1);
+ return self::global = [@vm.direct-call.metadata=_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::+}(1);
[@vm.unboxing-info.metadata=()->i]static method dec() → core::int*
- return self::global = [@vm.inferred-type.metadata=int] math::max<core::int*>(0, self::global = [@vm.direct-call.metadata=_IntegerImplementation::-??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::-}(1));
+ return self::global = [@vm.inferred-type.metadata=int] math::max<core::int*>(0, self::global = [@vm.direct-call.metadata=_IntegerImplementation.-??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::-}(1));
[@vm.unboxing-info.metadata=(i)->b]static method testNamedOrder([@vm.inferred-type.metadata=int] core::int* w, [@vm.inferred-type.metadata=int] core::int* x, [@vm.inferred-type.metadata=int] core::int* y, [@vm.inferred-type.metadata=int] core::int* z) → void {
exp::Expect::equals(w, 1);
exp::Expect::equals(z, 2);
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 3bc87ba..aabf974 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
@@ -49,11 +49,11 @@
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=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(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
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(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
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
}
abstract class C extends core::Object {
synthetic constructor •() → self::C*
@@ -68,11 +68,11 @@
: 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=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(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
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(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
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
}
class E extends core::Object implements self::A {
synthetic constructor •() → self::E*
@@ -82,7 +82,7 @@
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=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=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<InterfaceType(Symbol*), DynamicType(dynamic)>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
}
class F extends core::Object {
synthetic constructor •() → self::F*
@@ -116,12 +116,12 @@
static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:InterfaceType(Function*)] self::unknown.call();
static method main(core::List<core::String*>* args) → dynamic {
- core::print([@vm.direct-call.metadata=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=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=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));
- core::print([@vm.direct-call.metadata=D::foo??] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::foo}());
- core::print([@vm.direct-call.metadata=D::bar??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bar});
- core::print([@vm.direct-call.metadata=D::bazz??] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bazz}(1, 2, 3, 4));
+ core::print([@vm.direct-call.metadata=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=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=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));
+ core::print([@vm.direct-call.metadata=D.foo??] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::foo}());
+ core::print([@vm.direct-call.metadata=D.bar??] [@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bar});
+ core::print([@vm.direct-call.metadata=D.bazz??] [@vm.inferred-type.metadata=#lib::T2 (skip check)] [@vm.inferred-type.metadata=#lib::D?] self::dd.{self::A::bazz}(1, 2, 3, 4));
new self::E::•();
self::A* xx = self::getDynamic() as{TypeError,ForDynamic} self::A*;
core::print([@vm.inferred-type.metadata=!] xx.{self::A::bar});
@@ -131,6 +131,6 @@
dynamic gg = new self::G::•();
core::print([@vm.inferred-type.metadata=#lib::T5 (receiver not int)] gg.noSuchMethod(null, null));
dynamic hh = new self::H::•();
- core::print([@vm.direct-call.metadata=H::foo] [@vm.inferred-type.metadata=#lib::T6 (receiver not int)] hh.foo(right: 2, left: 1));
+ core::print([@vm.direct-call.metadata=H.foo] [@vm.inferred-type.metadata=#lib::T6 (receiver not int)] hh.foo(right: 2, left: 1));
core::print([@vm.inferred-type.metadata=#lib::T7 (receiver not int)] hh.foo(left: 1, top: 2));
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
index b7eefb1..424703b 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
@@ -13,17 +13,17 @@
}
[@vm.inferred-type.metadata=#lib::A?]static field self::A staticField = let core::String #t1 = "hi" in let core::String #t2 = "bye" in new self::A::•(#t1, #t2);
static method testNonNullable([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
- return _in::unsafeCast<core::String>([@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable});
+ return _in::unsafeCast<core::String>([@vm.direct-call.metadata=A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable});
static method testNullable([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
- return [@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}!;
+ return [@vm.direct-call.metadata=A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}!;
static method testAlwaysNull([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
- return [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}!;
+ return [@vm.direct-call.metadata=A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}!;
static method main() → void {
final core::List<self::A> list = <self::A>[let core::String #t3 = "foo" in let core::Null? #t4 = null in let core::Null? #t5 = null in new self::A::•(#t3, #t4, alwaysNull: #t5), self::staticField];
{
- core::Iterator<self::A> :sync-for-iterator = [@vm.direct-call.metadata=_GrowableList::iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(A)>] list.{core::Iterable::iterator};
- for (; [@vm.direct-call.metadata=ListIterator::moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- self::A a = [@vm.direct-call.metadata=ListIterator::current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current};
+ core::Iterator<self::A> :sync-for-iterator = [@vm.direct-call.metadata=_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(A)>] list.{core::Iterable::iterator};
+ for (; [@vm.direct-call.metadata=ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+ self::A a = [@vm.direct-call.metadata=ListIterator.current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current};
{
self::testNonNullable(a);
self::testNullable(a);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
index a6b4bb5..efdb843 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
@@ -13,49 +13,49 @@
}
[@vm.inferred-type.metadata=#lib::A?]static field self::A* staticField = let core::String* #t1 = "hi" in let core::String* #t2 = "bye" in new self::A::•(#t1, #t2);
static method testNonNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
- if(let dynamic #t3 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) {
+ if(let dynamic #t3 = [@vm.direct-call.metadata=A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) {
core::print("null");
}
}
static method testNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
- if([@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null)) {
+ if([@vm.direct-call.metadata=A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null)) {
core::print("null");
}
}
static method testAlwaysNullIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
- if(let dynamic #t4 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) {
+ if(let dynamic #t4 = [@vm.direct-call.metadata=A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) {
core::print("null");
}
}
static method testNonNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
- if(!(let dynamic #t5 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+ if(!(let dynamic #t5 = [@vm.direct-call.metadata=A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
core::print("not null");
}
}
static method testNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
- if(![@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+ if(![@vm.direct-call.metadata=A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
core::print("not null");
}
}
static method testAlwaysNullIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
- if(!(let dynamic #t6 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+ if(!(let dynamic #t6 = [@vm.direct-call.metadata=A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
core::print("not null");
}
}
static method testNonNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
- return !(let dynamic #t7 = [@vm.direct-call.metadata=A::nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) ?{core::String*} "not null" : "null";
+ return !(let dynamic #t7 = [@vm.direct-call.metadata=A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) ?{core::String*} "not null" : "null";
static method testNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
- return ![@vm.direct-call.metadata=A::nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) ?{core::String*} "not null" : "null";
+ return ![@vm.direct-call.metadata=A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) ?{core::String*} "not null" : "null";
static method testAlwaysNullCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
- return !(let dynamic #t8 = [@vm.direct-call.metadata=A::alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) ?{core::String*} "not null" : "null";
+ return !(let dynamic #t8 = [@vm.direct-call.metadata=A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) ?{core::String*} "not null" : "null";
static method someCondition() → dynamic
- return [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1);
+ return [@vm.direct-call.metadata=_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1);
static method main() → void {
final core::List<self::A*>* list = <self::A*>[let core::String* #t9 = "foo" in let core::Null? #t10 = null in let core::Null? #t11 = null in new self::A::•(#t9, #t10, alwaysNull: #t11), self::staticField];
{
- core::Iterator<self::A*>* :sync-for-iterator = [@vm.direct-call.metadata=_GrowableList::iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(A*)>] list.{core::Iterable::iterator};
- for (; [@vm.direct-call.metadata=ListIterator::moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- self::A* a = [@vm.direct-call.metadata=ListIterator::current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current};
+ core::Iterator<self::A*>* :sync-for-iterator = [@vm.direct-call.metadata=_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(A*)>] list.{core::Iterable::iterator};
+ for (; [@vm.direct-call.metadata=ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+ self::A* a = [@vm.direct-call.metadata=ListIterator.current] [@vm.inferred-type.metadata=#lib::A?] :sync-for-iterator.{core::Iterator::current};
{
self::testNonNullableIf1(a);
self::testNullableIf1(a);
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 ad4d6c9..34c4097 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
@@ -19,7 +19,7 @@
: 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.direct-call.metadata=T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
+ [@vm.direct-call.metadata=T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
}
abstract class B extends core::Object {
@@ -30,7 +30,7 @@
: 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.direct-call.metadata=T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
+ [@vm.direct-call.metadata=T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
}
class D extends core::Object {
@@ -38,15 +38,15 @@
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method method3(self::T0* t0) → void {
- [@vm.direct-call.metadata=T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
+ [@vm.direct-call.metadata=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.direct-call.metadata=T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
+ [@vm.direct-call.metadata=T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
static method func2(self::T0* t0) → void {
- [@vm.direct-call.metadata=T2::foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
+ [@vm.direct-call.metadata=T2.foo??] [@vm.inferred-type.metadata=!? (skip check)] t0.{self::T0::foo}();
}
static method getDynamic() → dynamic
return [@vm.call-site-attributes.metadata=receiverType:InterfaceType(Function*)] self::unknown.call();
@@ -57,7 +57,7 @@
self::use(#C1);
self::use(new self::A::•().{self::A::method1});
self::B* bb = self::getDynamic() as{TypeError,ForDynamic} self::B*;
- [@vm.direct-call.metadata=C::method2??] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B::method2}(self::getDynamic());
+ [@vm.direct-call.metadata=C.method2??] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B::method2}(self::getDynamic());
self::getDynamic().method3(self::getDynamic());
new self::T2::•();
new self::A::•();
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 f29e5b1..f9547a9 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
@@ -8,7 +8,7 @@
: 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*
- return [@vm.direct-call.metadata=_GrowableList::toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)] [@vm.direct-call.metadata=A::afield] [@vm.inferred-type.metadata=dart.core::_GrowableList<DynamicType(dynamic)>] this.{self::A::afield}.{core::Object::toString}();
+ return [@vm.direct-call.metadata=_GrowableList.toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)] [@vm.direct-call.metadata=A.afield] [@vm.inferred-type.metadata=dart.core::_GrowableList<DynamicType(dynamic)>] this.{self::A::afield}.{core::Object::toString}();
}
class B extends core::Object {
synthetic constructor •() → self::B*
@@ -16,16 +16,16 @@
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method _foo([@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(int*)>] core::Iterator<core::int*>* iter) → core::List<dynamic>* {
core::List<dynamic>* result = <dynamic>[];
- while ([@vm.direct-call.metadata=ListIterator::moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] iter.{core::Iterator::moveNext}()) {
- if([@vm.direct-call.metadata=_IntegerImplementation::<??] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=ListIterator::current] [@vm.inferred-type.metadata=int?] iter.{core::Iterator::current}.{core::num::<}(0)) {
+ while ([@vm.direct-call.metadata=ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] iter.{core::Iterator::moveNext}()) {
+ if([@vm.direct-call.metadata=_IntegerImplementation.<??] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=ListIterator.current] [@vm.inferred-type.metadata=int?] iter.{core::Iterator::current}.{core::num::<}(0)) {
return result;
}
- [@vm.call-site-attributes.metadata=receiverType:InterfaceType(List<dynamic>*)] [@vm.direct-call.metadata=_GrowableList::add] [@vm.inferred-type.metadata=!? (skip check)] result.{core::List::add}(new self::A::•([@vm.direct-call.metadata=B::_foo] [@vm.inferred-type.metadata=dart.core::_GrowableList<DynamicType(dynamic)> (skip check)] this.{self::B::_foo}(iter)));
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(List<dynamic>*)] [@vm.direct-call.metadata=_GrowableList.add] [@vm.inferred-type.metadata=!? (skip check)] result.{core::List::add}(new self::A::•([@vm.direct-call.metadata=B._foo] [@vm.inferred-type.metadata=dart.core::_GrowableList<DynamicType(dynamic)> (skip check)] this.{self::B::_foo}(iter)));
}
return result;
}
}
static method main() → void {
- core::List<dynamic>* list = [@vm.direct-call.metadata=B::_foo] [@vm.inferred-type.metadata=dart.core::_GrowableList<DynamicType(dynamic)> (skip check)] new self::B::•().{self::B::_foo}([@vm.direct-call.metadata=_GrowableList::iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(int*)>]<core::int*>[1, 2, 3].{core::Iterable::iterator});
+ core::List<dynamic>* list = [@vm.direct-call.metadata=B._foo] [@vm.inferred-type.metadata=dart.core::_GrowableList<DynamicType(dynamic)> (skip check)] new self::B::•().{self::B::_foo}([@vm.direct-call.metadata=_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<InterfaceType(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 4ff5384..b0e917f 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
@@ -3,6 +3,6 @@
import "dart:core" as core;
[@vm.unboxing-info.metadata=(b)->i]static method foo([@vm.inferred-type.metadata=dart.core::_GrowableList<InterfaceType(int*)>] core::List<core::int*>* x) → dynamic
- return [@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=int? (skip check)] x.{core::List::[]}(0));
+ return [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=int? (skip check)] x.{core::List::[]}(0));
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_41452_nnbd_strong.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
index 31685ef..e32f219 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_41452_nnbd_strong.dart.expect
@@ -18,10 +18,10 @@
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method add(generic-covariant-impl self::_SplayTree::Node n) → dynamic {
- self::_SplayTree::Node? root = [@vm.direct-call.metadata=SplayTreeMap::_root] [@vm.inferred-type.metadata=#lib::_SplayTreeMapNode] this.{self::_SplayTree::_root};
+ self::_SplayTree::Node? root = [@vm.direct-call.metadata=SplayTreeMap._root] [@vm.inferred-type.metadata=#lib::_SplayTreeMapNode] this.{self::_SplayTree::_root};
if(false)
return;
- core::print([@vm.direct-call.metadata=_SplayTreeNode::left] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] root{self::_SplayTree::Node}.{self::_SplayTreeNode::left});
+ core::print([@vm.direct-call.metadata=_SplayTreeNode.left] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] root{self::_SplayTree::Node}.{self::_SplayTreeNode::left});
}
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5] abstract get /*isNullableByDefault*/ _root() → self::_SplayTree::Node?;
}
@@ -32,5 +32,5 @@
;
}
static method main() → void {
- [@vm.call-site-attributes.metadata=receiverType:InterfaceType(SplayTreeMap<dynamic>)] [@vm.direct-call.metadata=_SplayTree::add] new self::SplayTreeMap::•<dynamic>().{self::_SplayTree::add}(new self::_SplayTreeMapNode::•<dynamic>());
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(SplayTreeMap<dynamic>)] [@vm.direct-call.metadata=_SplayTree.add] new self::SplayTreeMap::•<dynamic>().{self::_SplayTree::add}(new self::_SplayTreeMapNode::•<dynamic>());
}
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 b39b249..9dfc5b4 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
@@ -20,7 +20,7 @@
: 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.direct-call.metadata=A1::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A1::foo} = _in::unsafeCast<self::T1*>(a5);
+ [@vm.direct-call.metadata=A1.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A1::foo} = _in::unsafeCast<self::T1*>(a5);
}
}
class B1 extends core::Object {
@@ -43,7 +43,7 @@
: 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.direct-call.metadata=A2::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A2::foo} = a6;
+ [@vm.direct-call.metadata=A2.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A2::foo} = a6;
}
}
abstract class B2Base extends core::Object {
@@ -52,14 +52,14 @@
: 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=B2Base::_aa] [@vm.inferred-type.metadata=#lib::A2] this.{self::B2Base::_aa};
+ return [@vm.direct-call.metadata=B2Base._aa] [@vm.inferred-type.metadata=#lib::A2] this.{self::B2Base::_aa};
}
class B2 extends self::B2Base {
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.call-site-attributes.metadata=receiverType:DynamicType(dynamic)] [@vm.direct-call.metadata=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::•());
+ [@vm.call-site-attributes.metadata=receiverType:DynamicType(dynamic)] [@vm.direct-call.metadata=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 {
@@ -76,7 +76,7 @@
: 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.direct-call.metadata=A3::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A3::foo} = a7;
+ [@vm.direct-call.metadata=A3.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A3::foo} = a7;
}
}
class B3 extends core::Object {
@@ -99,7 +99,7 @@
: 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.direct-call.metadata=A4::foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A4::foo} = a8;
+ [@vm.direct-call.metadata=A4.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A4::foo} = a8;
}
}
class B4 extends core::Object {
@@ -108,7 +108,7 @@
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,getterSelectorId:22] get aa4() → dynamic
- return [@vm.direct-call.metadata=B4::_aa] [@vm.inferred-type.metadata=#lib::A4] this.{self::B4::_aa};
+ return [@vm.direct-call.metadata=B4._aa] [@vm.inferred-type.metadata=#lib::A4] this.{self::B4::_aa};
}
[@vm.inferred-type.metadata=dart.core::bool?]static field core::bool* ok;
[@vm.inferred-type.metadata=#lib::B3?]static field dynamic bb3 = new self::B3::•();
@@ -117,16 +117,16 @@
[@vm.inferred-type.metadata=dart.core::_Closure?]static field core::Function* unknown4 = () → dynamic => self::bb4;
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:InterfaceType(A1*)] [@vm.direct-call.metadata=A1::call] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=B1::aa1] [@vm.inferred-type.metadata=#lib::A1] #t1.{self::B1::aa1}.{self::A1::call}(#t2, #t3, #t4, #t5, #t6);
+ 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:InterfaceType(A1*)] [@vm.direct-call.metadata=A1.call] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=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=T1::doTest1??] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=A1::foo] [@vm.inferred-type.metadata=#lib::T1?] [@vm.direct-call.metadata=B1::aa1] [@vm.inferred-type.metadata=#lib::A1] bb.{self::B1::aa1}.{self::A1::foo}.{self::T1::doTest1}();
+ [@vm.direct-call.metadata=T1.doTest1??] [@vm.inferred-type.metadata=!? (skip check)] [@vm.direct-call.metadata=A1.foo] [@vm.inferred-type.metadata=#lib::T1?] [@vm.direct-call.metadata=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 {
self::B2* bb = new self::B2::•();
- [@vm.direct-call.metadata=B2::doSuperCall] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B2::doSuperCall}();
+ [@vm.direct-call.metadata=B2.doSuperCall] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B2::doSuperCall}();
self::ok = false;
- [@vm.direct-call.metadata=T2::doTest2??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=A2::foo] [@vm.inferred-type.metadata=#lib::T2? (receiver not int)] [@vm.direct-call.metadata=B2Base::aa2] [@vm.inferred-type.metadata=#lib::A2] bb.{self::B2Base::aa2}.foo.doTest2();
+ [@vm.direct-call.metadata=T2.doTest2??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=A2.foo] [@vm.inferred-type.metadata=#lib::T2? (receiver not int)] [@vm.direct-call.metadata=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
@@ -134,7 +134,7 @@
static method test3() → void {
self::getDynamic3().aa3(1, 2, 3, 4, 5, 6, new self::T3::•());
self::ok = false;
- [@vm.direct-call.metadata=T3::doTest3??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=A3::foo] [@vm.inferred-type.metadata=#lib::T3? (receiver not int)] [@vm.direct-call.metadata=B3::aa3??] [@vm.inferred-type.metadata=#lib::A3 (receiver not int)] [@vm.inferred-type.metadata=#lib::B3?] self::bb3.aa3.foo.doTest3();
+ [@vm.direct-call.metadata=T3.doTest3??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=A3.foo] [@vm.inferred-type.metadata=#lib::T3? (receiver not int)] [@vm.direct-call.metadata=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
@@ -142,7 +142,7 @@
static method test4() → void {
self::getDynamic4().aa4(1, 2, 3, 4, 5, 6, 7, new self::T4::•());
self::ok = false;
- [@vm.direct-call.metadata=T4::doTest4??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=A4::foo] [@vm.inferred-type.metadata=#lib::T4? (receiver not int)] [@vm.inferred-type.metadata=#lib::A4] self::getDynamic4().aa4.foo.doTest4();
+ [@vm.direct-call.metadata=T4.doTest4??] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.direct-call.metadata=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 {
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 1eaa0f9..59dd25e 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
@@ -12,13 +12,13 @@
: super self::A::•()
;
[@vm.procedure-attributes.metadata=hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
- return [@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=! (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=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*;
+ return [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=! (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=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*
: self::TearOffDynamicMethod::bazz = arg.foo, super core::Object::•() {
- [@vm.call-site-attributes.metadata=receiverType:DynamicType(dynamic)] [@vm.direct-call.metadata=TearOffDynamicMethod::bazz] this.{self::TearOffDynamicMethod::bazz}.call();
+ [@vm.call-site-attributes.metadata=receiverType:DynamicType(dynamic)] [@vm.direct-call.metadata=TearOffDynamicMethod.bazz] this.{self::TearOffDynamicMethod::bazz}.call();
}
}
static method knownResult() → dynamic
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 66ded4c..3f099e3 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
@@ -14,7 +14,7 @@
: super self::A::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
- return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=B::bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 3) (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult().bar())));
+ return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=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*
return 3;
}
@@ -27,5 +27,5 @@
static method knownResult() → dynamic
return new self::B::•();
static method main(core::List<core::String*>* args) → dynamic {
- [@vm.call-site-attributes.metadata=receiverType:DynamicType(dynamic)] [@vm.direct-call.metadata=TearOffInterfaceMethod::bazz] new self::TearOffInterfaceMethod::•(new self::B::•()).{self::TearOffInterfaceMethod::bazz}.call();
+ [@vm.call-site-attributes.metadata=receiverType:DynamicType(dynamic)] [@vm.direct-call.metadata=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 475df5a..56f16ba 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
@@ -14,14 +14,14 @@
: super self::A::•()
;
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
- return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=B::foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
+ return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=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*
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
- return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 3.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=B::foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
+ return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 3.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=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*
return [@vm.call-site-attributes.metadata=receiverType:DynamicType(dynamic)] x.call() as{TypeError,ForDynamic} core::int*;
}
@@ -30,12 +30,12 @@
: super self::Base::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method bar() → core::int*
- return [@vm.direct-call.metadata=Base::doCall] [@vm.inferred-type.metadata=int? (skip check)] this.{self::Base::doCall}(super.{self::Base::foo});
+ return [@vm.direct-call.metadata=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
return new self::B::•();
static method main(core::List<core::String*>* args) → dynamic {
- [@vm.direct-call.metadata=TearOffSuperMethod::bar] [@vm.inferred-type.metadata=!? (skip check)] new self::TearOffSuperMethod::•().{self::TearOffSuperMethod::bar}();
- [@vm.direct-call.metadata=B::foo??] [@vm.inferred-type.metadata=!? (skip check)] [@vm.inferred-type.metadata=#lib::B?] self::aa.{self::A::foo}();
+ [@vm.direct-call.metadata=TearOffSuperMethod.bar] [@vm.inferred-type.metadata=!? (skip check)] new self::TearOffSuperMethod::•().{self::TearOffSuperMethod::bar}();
+ [@vm.direct-call.metadata=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/type_cast_elimination.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination.dart.expect
index 043ff26..98de328 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination.dart.expect
@@ -28,7 +28,7 @@
static method testDynamic([@vm.inferred-type.metadata=dart.core::_OneByteString (value: hi)] dynamic x) → dynamic
return _in::unsafeCast<dynamic>(x);
static method testObject([@vm.inferred-type.metadata=dart.core::_OneByteString (value: bye)] dynamic x) → dynamic
- return _in::unsafeCast<core::Object*>(x);
+ return x;
static method testBOfInt([@vm.inferred-type.metadata=#lib::B<InterfaceType(int*)>] dynamic x) → dynamic
return _in::unsafeCast<self::B<core::int*>*>(x);
static method testAOfInt([@vm.inferred-type.metadata=#lib::B<InterfaceType(int*)>] dynamic x) → dynamic
@@ -49,8 +49,8 @@
self::testAOfNum(new self::B::•<core::int*>());
self::testAOfAOfB1(new self::A::•<self::A<self::B<dynamic>*>*>());
self::testAOfAOfB2negative(new self::A::•<self::A<self::A<dynamic>*>*>());
- [@vm.direct-call.metadata=B::testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int*>().{self::B::testT1}(42);
- [@vm.direct-call.metadata=B::testT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testT2negative}(new self::A::•<core::String*>());
- [@vm.direct-call.metadata=B::testAOfT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testAOfT1}(new self::A::•<self::A<core::int*>*>());
- [@vm.direct-call.metadata=B::testAOfT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testAOfT2negative}(new self::A::•<self::A<core::num*>*>());
+ [@vm.direct-call.metadata=B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int*>().{self::B::testT1}(42);
+ [@vm.direct-call.metadata=B.testT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testT2negative}(new self::A::•<core::String*>());
+ [@vm.direct-call.metadata=B.testAOfT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testAOfT1}(new self::A::•<self::A<core::int*>*>());
+ [@vm.direct-call.metadata=B.testAOfT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<self::A<core::int*>*>().{self::B::testAOfT2negative}(new self::A::•<self::A<core::num*>*>());
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart.expect
index fa9c724..638caae 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd.dart.expect
@@ -34,9 +34,9 @@
static method testDynamic([@vm.inferred-type.metadata=dart.core::_OneByteString (value: hi)] dynamic x) → dynamic
return _in::unsafeCast<dynamic>(x);
static method testObject([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
- return _in::unsafeCast<core::Object>(x);
+ return x;
static method testNullableObject([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
- return _in::unsafeCast<core::Object?>(x);
+ return x;
static method testAOfNum1([@vm.inferred-type.metadata=#lib::B<InterfaceType(int)>] dynamic x) → dynamic
return _in::unsafeCast<self::A<core::num>>(x);
static method testAOfNum2([@vm.inferred-type.metadata=#lib::B<InterfaceType(int?)>] dynamic x) → dynamic
@@ -63,9 +63,9 @@
self::testAOfNullableNum(new self::B::•<core::int?>());
self::testNullableAOfNum(null);
self::testNullableAOfNullableNum(new self::B::•<core::int?>());
- [@vm.direct-call.metadata=B::testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT1}(42);
- [@vm.direct-call.metadata=B::testT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT2}(null);
- [@vm.direct-call.metadata=B::testT3] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int?>().{self::B::testT3}(null);
- [@vm.direct-call.metadata=B::testNullableT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT1}(42);
- [@vm.direct-call.metadata=B::testNullableT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT2}(null);
+ [@vm.direct-call.metadata=B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT1}(42);
+ [@vm.direct-call.metadata=B.testT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT2}(null);
+ [@vm.direct-call.metadata=B.testT3] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int?>().{self::B::testT3}(null);
+ [@vm.direct-call.metadata=B.testNullableT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT1}(42);
+ [@vm.direct-call.metadata=B.testNullableT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT2}(null);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart.expect
index 30e95fb..0cfc7fb 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/type_cast_elimination_nnbd_strong.dart.expect
@@ -34,9 +34,9 @@
static method testDynamic([@vm.inferred-type.metadata=dart.core::_OneByteString (value: hi)] dynamic x) → dynamic
return _in::unsafeCast<dynamic>(x);
static method testObjectNegative([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
- return x as{ForNonNullableByDefault} core::Object;
+ return let dynamic #t1 = x in true ?{core::Object} #t1 as{ForNonNullableByDefault} core::Object : #t1{core::Object};
static method testNullableObject([@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic x) → dynamic
- return _in::unsafeCast<core::Object?>(x);
+ return x;
static method testAOfNum1([@vm.inferred-type.metadata=#lib::B<InterfaceType(int)>] dynamic x) → dynamic
return _in::unsafeCast<self::A<core::num>>(x);
static method testAOfNum2negative([@vm.inferred-type.metadata=#lib::B<InterfaceType(int?)>] dynamic x) → dynamic
@@ -66,9 +66,9 @@
self::testNullableAOfNum(null);
self::testNullableAOfNumNegative(new self::B::•<core::int?>());
self::testNullableAOfNullableNum(new self::B::•<core::int?>());
- [@vm.direct-call.metadata=B::testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT1}(42);
- [@vm.direct-call.metadata=B::testT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT2negative}(null);
- [@vm.direct-call.metadata=B::testT3] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int?>().{self::B::testT3}(null);
- [@vm.direct-call.metadata=B::testNullableT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT1}(42);
- [@vm.direct-call.metadata=B::testNullableT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT2}(null);
+ [@vm.direct-call.metadata=B.testT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT1}(42);
+ [@vm.direct-call.metadata=B.testT2negative] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testT2negative}(null);
+ [@vm.direct-call.metadata=B.testT3] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int?>().{self::B::testT3}(null);
+ [@vm.direct-call.metadata=B.testNullableT1] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT1}(42);
+ [@vm.direct-call.metadata=B.testNullableT2] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•<core::int>().{self::B::testNullableT2}(null);
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart.expect
index 4fb58cc..1d98d02 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart.expect
@@ -21,31 +21,31 @@
: self::A::unboxedSmi = unboxedSmi, self::A::unboxedInt = unboxedInt, self::A::unboxedDouble = unboxedDouble, self::A::boxedNullableInt = boxedNullableInt, self::A::boxedNullableDouble = boxedNullableDouble, self::A::boxedNonNullableIntOrDouble = boxedNonNullableIntOrDouble, self::A::boxedNullableIntOrDouble = boxedNullableIntOrDouble, self::A::boxedNullableX = boxedNullableX, self::A::boxedX = boxedX, super core::Object::•()
;
}
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
static get mint() → core::int*
return -6144092014192636707;
static get smiOrMint() → core::int*
return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : [@vm.inferred-type.metadata=int] self::mint;
static method main() → dynamic {
final self::A* a = new self::A::•([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
- [@vm.direct-call.metadata=A::unboxedSmi] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::unboxedSmi} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
- [@vm.direct-call.metadata=A::unboxedInt] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::unboxedInt} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2;
- [@vm.direct-call.metadata=A::unboxedDouble] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::unboxedDouble} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2;
- [@vm.direct-call.metadata=A::boxedNullableInt] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNullableInt} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null;
- [@vm.direct-call.metadata=A::boxedNullableDouble] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNullableDouble} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null;
- [@vm.direct-call.metadata=A::boxedNonNullableIntOrDouble] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNonNullableIntOrDouble} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1;
- [@vm.direct-call.metadata=A::boxedNullableIntOrDouble] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNullableIntOrDouble} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null;
- [@vm.direct-call.metadata=A::boxedNullableX] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNullableX} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null;
- [@vm.direct-call.metadata=A::boxedX] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedX} = new self::X::•();
- self::use([@vm.direct-call.metadata=A::unboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi] a.{self::A::unboxedSmi});
- self::use([@vm.direct-call.metadata=A::unboxedInt] [@vm.inferred-type.metadata=int] a.{self::A::unboxedInt});
- self::use([@vm.direct-call.metadata=A::unboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double] a.{self::A::unboxedDouble});
- self::use([@vm.direct-call.metadata=A::boxedNullableInt] [@vm.inferred-type.metadata=int?] a.{self::A::boxedNullableInt});
- self::use([@vm.direct-call.metadata=A::boxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double?] a.{self::A::boxedNullableDouble});
- self::use([@vm.direct-call.metadata=A::boxedNonNullableIntOrDouble] [@vm.inferred-type.metadata=!] a.{self::A::boxedNonNullableIntOrDouble});
- self::use([@vm.direct-call.metadata=A::boxedNullableIntOrDouble] a.{self::A::boxedNullableIntOrDouble});
- self::use([@vm.direct-call.metadata=A::boxedNullableX] [@vm.inferred-type.metadata=#lib::X?] a.{self::A::boxedNullableX});
- self::use([@vm.direct-call.metadata=A::boxedX] [@vm.inferred-type.metadata=#lib::X] a.{self::A::boxedX});
+ [@vm.direct-call.metadata=A.unboxedSmi] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::unboxedSmi} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
+ [@vm.direct-call.metadata=A.unboxedInt] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::unboxedInt} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2;
+ [@vm.direct-call.metadata=A.unboxedDouble] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::unboxedDouble} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2;
+ [@vm.direct-call.metadata=A.boxedNullableInt] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNullableInt} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null;
+ [@vm.direct-call.metadata=A.boxedNullableDouble] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNullableDouble} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null;
+ [@vm.direct-call.metadata=A.boxedNonNullableIntOrDouble] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNonNullableIntOrDouble} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1;
+ [@vm.direct-call.metadata=A.boxedNullableIntOrDouble] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNullableIntOrDouble} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null;
+ [@vm.direct-call.metadata=A.boxedNullableX] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedNullableX} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null;
+ [@vm.direct-call.metadata=A.boxedX] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::boxedX} = new self::X::•();
+ self::use([@vm.direct-call.metadata=A.unboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi] a.{self::A::unboxedSmi});
+ self::use([@vm.direct-call.metadata=A.unboxedInt] [@vm.inferred-type.metadata=int] a.{self::A::unboxedInt});
+ self::use([@vm.direct-call.metadata=A.unboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double] a.{self::A::unboxedDouble});
+ self::use([@vm.direct-call.metadata=A.boxedNullableInt] [@vm.inferred-type.metadata=int?] a.{self::A::boxedNullableInt});
+ self::use([@vm.direct-call.metadata=A.boxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double?] a.{self::A::boxedNullableDouble});
+ self::use([@vm.direct-call.metadata=A.boxedNonNullableIntOrDouble] [@vm.inferred-type.metadata=!] a.{self::A::boxedNonNullableIntOrDouble});
+ self::use([@vm.direct-call.metadata=A.boxedNullableIntOrDouble] a.{self::A::boxedNullableIntOrDouble});
+ self::use([@vm.direct-call.metadata=A.boxedNullableX] [@vm.inferred-type.metadata=#lib::X?] a.{self::A::boxedNullableX});
+ self::use([@vm.direct-call.metadata=A.boxedX] [@vm.inferred-type.metadata=#lib::X] a.{self::A::boxedX});
}
static method use(dynamic object) → void {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
index 458b82d..c268813 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
@@ -95,23 +95,23 @@
return -6144092014192636707;
static method main() → dynamic {
final core::List<core::Object*>* values = <core::Object*>[new self::Impl1::•(), new self::BaseImpl2::•(), new self::SubImpl3::•()];
- final self::Impl1* a = [@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("0")) as self::Impl1*;
- final self::BaseImpl2* b = [@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("1")) as self::BaseImpl2*;
- final self::SubImpl3* c = [@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::SubImpl3*;
- final self::Interface* d = [@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::Interface*;
- [@vm.direct-call.metadata=Impl1::takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1, 1.1, null, null, 1, null, null, new self::X::•());
+ final self::Impl1* a = [@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("0")) as self::Impl1*;
+ final self::BaseImpl2* b = [@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("1")) as self::BaseImpl2*;
+ final self::SubImpl3* c = [@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::SubImpl3*;
+ final self::Interface* d = [@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::Interface*;
+ [@vm.direct-call.metadata=Impl1.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1, 1.1, null, null, 1, null, null, new self::X::•());
b.{self::BaseImpl2::takePositional}(2, 2, 2.2, 2, 2.2, 2.2, 2, new self::X::•(), new self::X::•());
- [@vm.direct-call.metadata=SubImpl3::takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
+ [@vm.direct-call.metadata=SubImpl3.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
d.{self::Interface::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
- self::use([@vm.direct-call.metadata=Impl1::returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(null));
self::use([@vm.inferred-type.metadata=dart.core::_Smi] b.{self::BaseImpl2::returnUnboxedSmi}(null));
self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnUnboxedInt}(null));
self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnUnboxedDouble}(null));
@@ -121,15 +121,15 @@
self::use([@vm.inferred-type.metadata=!] b.{self::BaseImpl2::returnBoxedNullableIntOrDouble}(null));
self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedNullableX}(null));
self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedX}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(null));
self::use([@vm.inferred-type.metadata=dart.core::_Smi] d.{self::Interface::returnUnboxedSmi}(null));
self::use([@vm.inferred-type.metadata=int] d.{self::Interface::returnUnboxedInt}(null));
self::use([@vm.inferred-type.metadata=dart.core::_Double] d.{self::Interface::returnUnboxedDouble}(null));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
index e0c5315..aa41317 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
@@ -95,23 +95,23 @@
return -6144092014192636707;
static method main() → dynamic {
final core::List<core::Object*>* values = <core::Object*>[new self::Impl1::•(), new self::BaseImpl2::•(), new self::SubImpl3::•()];
- final self::Impl1* a = [@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("0")) as self::Impl1*;
- final self::BaseImpl2* b = [@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("1")) as self::BaseImpl2*;
- final self::SubImpl3* c = [@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::SubImpl3*;
- final self::Interface* d = [@vm.direct-call.metadata=_GrowableList::[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::Interface*;
- [@vm.direct-call.metadata=Impl1::takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1, 1.1, null, null, 1, null, null, new self::X::•());
+ final self::Impl1* a = [@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("0")) as self::Impl1*;
+ final self::BaseImpl2* b = [@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("1")) as self::BaseImpl2*;
+ final self::SubImpl3* c = [@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::SubImpl3*;
+ final self::Interface* d = [@vm.direct-call.metadata=_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::Interface*;
+ [@vm.direct-call.metadata=Impl1.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1, 1.1, null, null, 1, null, null, new self::X::•());
b.{self::BaseImpl2::takePositional}(2, 2, 2.2, 2, 2.2, 2.2, 2, new self::X::•(), new self::X::•());
- [@vm.direct-call.metadata=SubImpl3::takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
+ [@vm.direct-call.metadata=SubImpl3.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
d.{self::Interface::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
- self::use([@vm.direct-call.metadata=Impl1::returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(null));
- self::use([@vm.direct-call.metadata=Impl1::returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(null));
+ self::use([@vm.direct-call.metadata=Impl1.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(null));
self::use([@vm.inferred-type.metadata=dart.core::_Smi] b.{self::BaseImpl2::returnUnboxedSmi}(null));
self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnUnboxedInt}(null));
self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnUnboxedDouble}(null));
@@ -121,15 +121,15 @@
self::use([@vm.inferred-type.metadata=!] b.{self::BaseImpl2::returnBoxedNullableIntOrDouble}(null));
self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedNullableX}(null));
self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedX}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(null));
- self::use([@vm.direct-call.metadata=SubImpl3::returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(null));
+ self::use([@vm.direct-call.metadata=SubImpl3.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(null));
self::use([@vm.inferred-type.metadata=dart.core::_Smi] d.{self::Interface::returnUnboxedSmi}(null));
self::use([@vm.inferred-type.metadata=int] d.{self::Interface::returnUnboxedInt}(null));
self::use([@vm.inferred-type.metadata=dart.core::_Double] d.{self::Interface::returnUnboxedDouble}(null));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
index 1d4ae0d..a5bf511 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
@@ -7,8 +7,8 @@
: super core::Object::•()
;
}
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
static get mint() → core::int*
return -6144092014192636707;
static get smiOrMint() → core::int*
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
index 04e9c52..965f2d6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
@@ -7,8 +7,8 @@
: super core::Object::•()
;
}
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
-[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
static get mint() → core::int*
return -6144092014192636707;
static get smiOrMint() → core::int*
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 3ba876c..3da3b64 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
@@ -16,5 +16,5 @@
}
static method main() → void {
null;
- [@vm.direct-call.metadata=C::instanceField] [@vm.inferred-type.metadata=!? (skip check)] new self::C::•().{self::C::instanceField} = null;
+ [@vm.direct-call.metadata=C.instanceField] [@vm.inferred-type.metadata=!? (skip check)] new self::C::•().{self::C::instanceField} = null;
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
index db8220b..a5fe581 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
@@ -58,11 +58,11 @@
new self::B::•("hi");
self::C<core::num*>* c = new self::D::•();
exp::Expect::throws<dynamic>(() → core::Null? {
- [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C<num*>*)] [@vm.direct-call.metadata=D::bar] c.{self::C::bar} = 3.14;
+ [@vm.call-site-attributes.metadata=receiverType:InterfaceType(C<num*>*)] [@vm.direct-call.metadata=D.bar] c.{self::C::bar} = 3.14;
});
self::E* e = new self::F::•();
- exp::Expect::equals(42, [@vm.direct-call.metadata=F::bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] e.{self::E::bar});
+ exp::Expect::equals(42, [@vm.direct-call.metadata=F.bar] [@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] e.{self::E::bar});
exp::Expect::isTrue(![@vm.inferred-type.metadata=dart.core::bool] core::identical(#C2, #C4));
- [@vm.direct-call.metadata=I::foo] [@vm.inferred-type.metadata=!? (skip check)] new self::I::•().{self::I::foo}();
+ [@vm.direct-call.metadata=I.foo] [@vm.inferred-type.metadata=!? (skip check)] new self::I::•().{self::I::foo}();
5;
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect
index fd4556d..18bfd33 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field3_nnbd.dart.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method use() → dynamic {
- [@vm.direct-call.metadata=A::x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A::x} = 3;
+ [@vm.direct-call.metadata=A.x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A::x} = 3;
}
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3] set /*isNullableByDefault*/ x(core::int value) → void;
}
@@ -17,13 +17,13 @@
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method use() → dynamic {
- [@vm.direct-call.metadata=B::x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::B::x} = 3;
+ [@vm.direct-call.metadata=B.x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::B::x} = 3;
}
}
[@vm.inferred-type.metadata=dart.core::_Smi?]late static final field core::int staticLateB;
static method main() → void {
- [@vm.direct-call.metadata=A::use] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::use}();
- [@vm.direct-call.metadata=B::use] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::use}();
+ [@vm.direct-call.metadata=A.use] [@vm.inferred-type.metadata=!? (skip check)] new self::A::•().{self::A::use}();
+ [@vm.direct-call.metadata=B.use] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::use}();
4;
self::staticLateB = 4;
}
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 745a6e2..01f4ea3 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -4328,7 +4328,7 @@
kind = json['kind'];
classRef = createServiceObject(json['class'], const ['ClassRef']);
valueAsString = json['valueAsString'];
- valueAsStringIsTruncated = json['valueAsStringIsTruncated'] ?? false;
+ valueAsStringIsTruncated = json['valueAsStringIsTruncated'];
length = json['length'];
name = json['name'];
typeClass = createServiceObject(json['typeClass'], const ['ClassRef']);
@@ -4350,8 +4350,7 @@
'class': classRef.toJson(),
});
_setIfNotNull(json, 'valueAsString', valueAsString);
- _setIfNotNull(
- json, 'valueAsStringIsTruncated', valueAsStringIsTruncated ?? false);
+ _setIfNotNull(json, 'valueAsStringIsTruncated', valueAsStringIsTruncated);
_setIfNotNull(json, 'length', length);
_setIfNotNull(json, 'name', name);
_setIfNotNull(json, 'typeClass', typeClass?.toJson());
@@ -4658,7 +4657,7 @@
kind = json['kind'];
classRef = createServiceObject(json['class'], const ['ClassRef']);
valueAsString = json['valueAsString'];
- valueAsStringIsTruncated = json['valueAsStringIsTruncated'] ?? false;
+ valueAsStringIsTruncated = json['valueAsStringIsTruncated'];
length = json['length'];
offset = json['offset'];
count = json['count'];
@@ -4708,8 +4707,7 @@
'class': classRef.toJson(),
});
_setIfNotNull(json, 'valueAsString', valueAsString);
- _setIfNotNull(
- json, 'valueAsStringIsTruncated', valueAsStringIsTruncated ?? false);
+ _setIfNotNull(json, 'valueAsStringIsTruncated', valueAsStringIsTruncated);
_setIfNotNull(json, 'length', length);
_setIfNotNull(json, 'offset', offset);
_setIfNotNull(json, 'count', count);
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index a45d705..146ec47 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -503,10 +503,6 @@
}
void generate(DartGenerator gen) {
- // Set default value for unspecified property
- setDefaultValue('Instance', 'valueAsStringIsTruncated', 'false');
- setDefaultValue('InstanceRef', 'valueAsStringIsTruncated', 'false');
-
gen.out(_headerCode);
gen.writeln("const String vmServiceVersion = '${serviceVersion}';");
gen.writeln();
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 55668ad..3ec3471 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -967,7 +967,7 @@
if (is_fuchsia) {
if (!using_fuchsia_sdk) {
- deps += [ "//zircon/public/lib/trace" ]
+ deps += [ "//zircon/system/ulib/trace" ]
}
}
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 1017655..23aab21 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -201,13 +201,25 @@
bool shared) {
MutexLocker ml(&mutex_);
- if (unix_domain_sockets_ != NULL && File::Exists(namespc, path)) {
+ RawAddr addr;
+ Dart_Handle result =
+ SocketAddress::GetUnixDomainSockAddr(path, namespc, &addr);
+ if (!Dart_IsNull(result)) {
+ return result;
+ }
+
+ if (unix_domain_sockets_ != NULL &&
+#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
+ // Abstract unix domain socket doesn't exist in file system.
+ path[0] != '@' &&
+#endif // defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
+ File::Exists(namespc, addr.un.sun_path)) {
// If there is a socket listening on this file. Ensure
// that it was created with `shared` mode and current `shared`
// is also true.
OSSocket* os_socket = unix_domain_sockets_;
OSSocket* os_socket_same_addr =
- FindOSSocketWithPath(os_socket, namespc, path);
+ FindOSSocketWithPath(os_socket, namespc, addr.un.sun_path);
if (os_socket_same_addr != NULL) {
if (!os_socket_same_addr->shared || !shared) {
OSError os_error(-1,
@@ -232,13 +244,6 @@
}
}
- RawAddr addr;
- Dart_Handle result =
- SocketAddress::GetUnixDomainSockAddr(path, namespc, &addr);
- if (!Dart_IsNull(result)) {
- return result;
- }
-
// There is no socket listening on that path, so we create new one.
intptr_t fd = ServerSocket::CreateUnixDomainBindListen(addr, backlog);
@@ -272,7 +277,15 @@
}
// Unlink the socket file, if os_socket contains unix domain sockets.
if (os_socket->address.addr.sa_family == AF_UNIX) {
+#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
+ // If the socket is abstract, which has a path starting with a null byte,
+ // unlink() is not necessary because the file doesn't exist.
+ if (os_socket->address.un.sun_path[0] != '\0') {
+ unlink(os_socket->address.un.sun_path);
+ }
+#else
unlink(os_socket->address.un.sun_path);
+#endif // defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
delete os_socket;
return true;
}
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index d2c36b1..d7fc972 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -262,10 +262,25 @@
const char* path) {
while (current != NULL) {
ASSERT(current->address.addr.sa_family == AF_UNIX);
+#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
+ bool condition;
+ if (path[0] == '\0') {
+ condition = current->address.un.sun_path[0] == '\0' &&
+ strcmp(&(current->address.un.sun_path[1]), path + 1) == 0;
+ } else {
+ condition =
+ File::AreIdentical(current->namespc, current->address.un.sun_path,
+ namespc, path) == File::kIdentical;
+ }
+ if (condition) {
+ return current;
+ }
+#else
if (File::AreIdentical(current->namespc, current->address.un.sun_path,
namespc, path) == File::kIdentical) {
return current;
}
+#endif // defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
current = current->next;
}
return NULL;
diff --git a/runtime/bin/socket_base.cc b/runtime/bin/socket_base.cc
index 6fb402c..9fdd8ba 100644
--- a/runtime/bin/socket_base.cc
+++ b/runtime/bin/socket_base.cc
@@ -112,6 +112,14 @@
#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
NamespaceScope ns(namespc, path);
path = ns.path();
+ bool is_abstract = (path[0] == '@');
+ if (is_abstract) {
+ // The following 107 bytes after the leading null byte represents the name
+ // of unix domain socket. Without reseting, even users provide the same path
+ // for bind and connect, they actually represent two different address and
+ // connection will be rejected.
+ bzero(addr->un.sun_path, sizeof(addr->un.sun_path));
+ }
#endif // defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
if (sizeof(path) > sizeof(addr->un.sun_path)) {
OSError os_error(-1,
@@ -122,6 +130,12 @@
}
addr->un.sun_family = AF_UNIX;
Utils::SNPrint(addr->un.sun_path, sizeof(addr->un.sun_path), "%s", path);
+#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
+ // In case of abstract namespace, transfer the leading '@' into a null byte.
+ if (is_abstract) {
+ addr->un.sun_path[0] = '\0';
+ }
+#endif // defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
return Dart_Null();
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index f0951db..66221bf 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -570,11 +570,10 @@
* improve debugging messages. The main function is not invoked by
* this function.
* \param package_root Ignored.
- * \param package_map The package map for this isolate to resolve package
- * imports against. The array contains alternating keys and values,
- * terminated by a NULL key. Only one of package_root and package_map
- * parameters is non-NULL. If neither parameter is passed the package
- * resolution of the parent isolate should be used.
+ * \param package_config Uri of the package configuration file (either in format
+ * of .packages or .dart_tool/package_config.json) for this isolate
+ * to resolve package imports against. If this parameter is not passed the
+ * package resolution of the parent isolate should be used.
* \param flags Default flags for this isolate being spawned. Either inherited
* from the spawning isolate or passed as parameters when spawning the
* isolate from Dart code.
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index bc22233..4aee1fd 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -213,6 +213,11 @@
return Object::null();
}
+DEFINE_NATIVE_ENTRY(Internal_collectAllGarbage, 0, 0) {
+ isolate->heap()->CollectAllGarbage();
+ return Object::null();
+}
+
static bool ExtractInterfaceTypeArgs(Zone* zone,
const Class& instance_cls,
const TypeArguments& instance_type_args,
diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
index 4ca3b75..0349bb9 100644
--- a/runtime/observatory/lib/src/elements/class_view.dart
+++ b/runtime/observatory/lib/src/elements/class_view.dart
@@ -227,9 +227,7 @@
..children = _createElements(),
new HRElement(),
new HeadingElement.h2()..text = 'Instances',
- new DivElement()
- ..children =
- _cls.hasAllocations ? [_classInstances.element] : const [],
+ new DivElement()..children = [_classInstances.element],
new HRElement(),
new HeadingElement.h2()..text = 'Allocations',
new DivElement()
diff --git a/runtime/observatory/lib/src/elements/helpers/any_ref.dart b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
index e69b983..a6ef2e9 100644
--- a/runtime/observatory/lib/src/elements/helpers/any_ref.dart
+++ b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
@@ -29,6 +29,9 @@
Element anyRef(M.IsolateRef isolate, ref, M.ObjectRepository objects,
{RenderingQueue queue, bool expandable: true}) {
+ if (ref == null) {
+ return new SpanElement()..text = "???";
+ }
if (ref is M.Guarded) {
if (ref.isSentinel) {
return anyRef(isolate, ref.asSentinel, objects,
diff --git a/runtime/observatory/lib/src/elements/instance_view.dart b/runtime/observatory/lib/src/elements/instance_view.dart
index 6540562..596585e 100644
--- a/runtime/observatory/lib/src/elements/instance_view.dart
+++ b/runtime/observatory/lib/src/elements/instance_view.dart
@@ -218,40 +218,41 @@
return menu;
}
+ Element memberHalf(String cssClass, dynamic half) {
+ var result = new DivElement()..classes = [cssClass];
+ if (half is String) {
+ result.text = half;
+ } else {
+ result.children = <Element>[
+ anyRef(_isolate, half, _objects, queue: _r.queue)
+ ];
+ }
+ return result;
+ }
+
+ Element member(dynamic name, dynamic value) {
+ return new DivElement()
+ ..classes = ['memberItem']
+ ..children = <Element>[
+ memberHalf('memberName', name),
+ memberHalf('memberValue', value),
+ ];
+ }
+
List<Element> _createMembers() {
final members = <Element>[];
if (_instance.valueAsString != null) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = _instance.kind == M.InstanceKind.string
- ? 'value as literal'
- : 'value',
- new DivElement()
- ..classes = ['memberValue']
- ..text = _instance.kind == M.InstanceKind.string
- ? Utils.formatStringAsLiteral(
- _instance.valueAsString, _instance.valueAsStringIsTruncated)
- : _instance.valueAsString
- ]);
+ if (_instance.kind == M.InstanceKind.string) {
+ members.add(member(
+ 'value as literal',
+ Utils.formatStringAsLiteral(
+ _instance.valueAsString, _instance.valueAsStringIsTruncated)));
+ } else {
+ members.add(member('value', _instance.valueAsString));
+ }
}
if (_instance.typeClass != null) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'type class',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new ClassRefElement(_isolate, _instance.typeClass,
- queue: _r.queue)
- .element
- ]
- ]);
+ members.add(member('type class', _instance.typeClass));
}
if (_typeArguments != null && _typeArguments.types.isNotEmpty) {
members.add(new DivElement()
@@ -274,97 +275,22 @@
]);
}
if (_instance.parameterizedClass != null) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'parameterized class',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new ClassRefElement(_isolate, _instance.parameterizedClass,
- queue: _r.queue)
- .element
- ]
- ]);
+ members.add(member('parameterized class', _instance.parameterizedClass));
}
if (_instance.parameterIndex != null) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'parameter index',
- new DivElement()
- ..classes = ['memberValue']
- ..text = '${_instance.parameterIndex}'
- ]);
+ members.add(member('parameter index', '${_instance.parameterIndex}'));
}
if (_instance.targetType != null) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'target type',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new InstanceRefElement(_isolate, _instance.targetType, _objects,
- queue: _r.queue)
- .element
- ]
- ]);
+ members.add(member('target type', _instance.targetType));
}
if (_instance.bound != null) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'bound',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new InstanceRefElement(_isolate, _instance.bound, _objects,
- queue: _r.queue)
- .element
- ]
- ]);
+ members.add(member('bound', _instance.bound));
}
if (_instance.closureFunction != null) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'closure function',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new FunctionRefElement(_isolate, _instance.closureFunction,
- queue: _r.queue)
- .element
- ]
- ]);
+ members.add(member('closure function', _instance.closureFunction));
}
if (_instance.closureContext != null) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'closure context',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new ContextRefElement(
- _isolate, _instance.closureContext, _objects,
- queue: _r.queue)
- .element
- ]
- ]);
+ members.add(member('closure context', _instance.closureContext));
}
if (_instance.kind == M.InstanceKind.closure) {
ButtonElement btn;
@@ -407,16 +333,8 @@
new DivElement()
..classes = ['memberList']
..children = _instance.nativeFields
- .map<Element>((f) => new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = '[ ${i++} ]',
- new DivElement()
- ..classes = ['memberValue']
- ..text = '[ ${f.value} ]'
- ])
+ .map<Element>(
+ (f) => member('[ ${i++} ]', '[ ${f.value} ]'))
.toList()
])
.element
@@ -441,25 +359,7 @@
new DivElement()
..classes = ['memberList']
..children = fields
- .map<Element>((f) => new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..children = <Element>[
- new FieldRefElement(
- _isolate, f.decl, _objects,
- queue: _r.queue)
- .element
- ],
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new SpanElement()..text = ' = ',
- anyRef(_isolate, f.value, _objects,
- queue: _r.queue)
- ]
- ])
+ .map<Element>((f) => member(f.decl, f.value))
.toList()
])
.element
@@ -485,35 +385,16 @@
new DivElement()
..classes = ['memberList']
..children = elements
- .map<Element>((element) => new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = '[ ${i++} ]',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- anyRef(_isolate, element, _objects,
- queue: _r.queue)
- ]
- ])
+ .map<Element>(
+ (element) => member('[ ${i++} ]', element))
.toList()
])
.element
]
]);
if (_instance.length != elements.length) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = '...',
- new DivElement()
- ..classes = ['memberValue']
- ..text = '${_instance.length - elements.length} omitted elements'
- ]);
+ members.add(member(
+ '...', '${_instance.length - elements.length} omitted elements'));
}
}
@@ -558,17 +439,8 @@
]
]);
if (_instance.length != associations.length) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = '...',
- new DivElement()
- ..classes = ['memberValue']
- ..text = '${_instance.length - associations.length} '
- 'omitted elements'
- ]);
+ members.add(member('...',
+ '${_instance.length - associations.length} omitted elements'));
}
}
@@ -590,207 +462,54 @@
new DivElement()
..classes = ['memberList']
..children = typedElements
- .map<Element>((e) => new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = '[ ${i++} ]',
- new DivElement()
- ..classes = ['memberValue']
- ..text = '$e'
- ])
+ .map<Element>((e) => member('[ ${i++} ]', '$e'))
.toList()
])
.element
]
]);
if (_instance.length != typedElements.length) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = '...',
- new DivElement()
- ..classes = ['memberValue']
- ..text = '${_instance.length - typedElements.length} '
- 'omitted elements'
- ]);
+ members.add(member('...',
+ '${_instance.length - typedElements.length} omitted elements'));
}
}
if (_instance.kind == M.InstanceKind.regExp) {
- members.addAll([
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'pattern',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- anyRef(_isolate, _instance.pattern, _objects, queue: _r.queue)
- ]
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'isCaseSensitive',
- new DivElement()
- ..classes = ['memberValue']
- ..text = _instance.isCaseSensitive ? 'yes' : 'no'
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'isMultiLine',
- new DivElement()
- ..classes = ['memberValue']
- ..text = _instance.isMultiLine ? 'yes' : 'no'
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'oneByteFunction',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new FunctionRefElement(_isolate, _instance.oneByteFunction,
- queue: _r.queue)
- .element
- ]
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'twoByteFunction',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new FunctionRefElement(_isolate, _instance.twoByteFunction,
- queue: _r.queue)
- .element
- ]
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'externalOneByteFunction',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new FunctionRefElement(
- _isolate, _instance.externalOneByteFunction,
- queue: _r.queue)
- .element
- ]
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'externalTwoByteFunction',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new FunctionRefElement(
- _isolate, _instance.externalTwoByteFunction,
- queue: _r.queue)
- .element
- ]
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'oneByteBytecode',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new InstanceRefElement(
- _isolate, _instance.oneByteBytecode, _objects,
- queue: _r.queue)
- .element
- ]
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'twoByteBytecode',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new InstanceRefElement(
- _isolate, _instance.twoByteBytecode, _objects,
- queue: _r.queue)
- .element
- ]
- ]
- ]);
+ members.add(member('pattern', _instance.pattern));
+ members.add(
+ member('isCaseSensitive', _instance.isCaseSensitive ? 'yes' : 'no'));
+ members.add(member('isMultiLine', _instance.isMultiLine ? 'yes' : 'no'));
+ if (_instance.oneByteFunction != null) {
+ members.add(member('oneByteFunction', _instance.oneByteFunction));
+ }
+ if (_instance.twoByteFunction != null) {
+ members.add(member('twoByteFunction', _instance.twoByteFunction));
+ }
+ if (_instance.externalOneByteFunction != null) {
+ members.add(member(
+ 'externalOneByteFunction', _instance.externalOneByteFunction));
+ }
+ if (_instance.externalTwoByteFunction != null) {
+ members.add(member(
+ 'externalTwoByteFunction', _instance.externalTwoByteFunction));
+ }
+ if (_instance.oneByteBytecode != null) {
+ members.add(member('oneByteBytecode', _instance.oneByteBytecode));
+ }
+ if (_instance.twoByteBytecode != null) {
+ members.add(member('twoByteBytecode', _instance.twoByteBytecode));
+ }
}
if (_instance.kind == M.InstanceKind.mirrorReference) {
- members.add(new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'referent',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- anyRef(_isolate, _instance.referent, _objects, queue: _r.queue)
- ]
- ]);
+ members.add(member('referent', _instance.referent));
}
+
if (_instance.kind == M.InstanceKind.weakProperty) {
- members.addAll([
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'key',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new InstanceRefElement(_isolate, _instance.key, _objects,
- queue: _r.queue)
- .element,
- ]
- ],
- new DivElement()
- ..classes = ['memberItem']
- ..children = <Element>[
- new DivElement()
- ..classes = ['memberName']
- ..text = 'value',
- new DivElement()
- ..classes = ['memberValue']
- ..children = <Element>[
- new InstanceRefElement(_isolate, _instance.value, _objects,
- queue: _r.queue)
- .element,
- ]
- ]
- ]);
+ members.add(member('key', _instance.key));
+ members.add(member('value', _instance.value));
}
+
return members;
}
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index e11a833..091ad8fd 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -679,6 +679,9 @@
#define PATH_MAX MAX_PATH
#endif
+// Undefine math.h definition which clashes with our condition names.
+#undef OVERFLOW
+
} // namespace dart
#endif // RUNTIME_PLATFORM_GLOBALS_H_
diff --git a/runtime/tests/vm/dart/unboxed_many_fields_test.dart b/runtime/tests/vm/dart/unboxed_many_fields_test.dart
new file mode 100644
index 0000000..84b4f1d
--- /dev/null
+++ b/runtime/tests/vm/dart/unboxed_many_fields_test.dart
@@ -0,0 +1,281 @@
+// 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:_internal' show VMInternalsForTesting;
+
+import 'package:expect/expect.dart';
+
+// The VM class finalizer ensures that we only unbox fields which can be
+// represented in the unboxed field bitmap in the target architecture (even when
+// cross-compiling from 64-bit to 32-bit), see `Class::CalculateFieldOffsets()`.
+
+// Make an integer that would look like an object pointer (irrespective of
+// we compile to 32-bit or 64-bit and whether we use little or big endian
+// encoding of the integer).
+int get integerFieldValue =>
+ int.parse('1') == 1 ? constIntegerFieldValue : 0x8000900180009001;
+const int constIntegerFieldValue = 0x8000000180000001;
+
+int i = 0;
+final Object objectFieldValue = Foo('i${i++}');
+
+void main() {
+ final object = buildTargetLayout64Bit();
+
+ // Ensure all fields of the class are used.
+ print(object);
+
+ Expect.identical(object.field1, objectFieldValue);
+ Expect.identical(object.field2, constIntegerFieldValue);
+ Expect.identical(object.field64, objectFieldValue);
+ Expect.identical(object.field65, constIntegerFieldValue);
+ Expect.identical(object.field66, objectFieldValue);
+ Expect.equals('i0', object.field66.value);
+
+ // Forcefully cause a GC.
+ VMInternalsForTesting.collectAllGarbage();
+
+ Expect.identical(object.field1, objectFieldValue);
+ Expect.identical(object.field2, constIntegerFieldValue);
+ Expect.identical(object.field64, objectFieldValue);
+ Expect.identical(object.field65, constIntegerFieldValue);
+ Expect.identical(object.field66, objectFieldValue);
+ Expect.equals('i0', object.field66.value);
+
+ print(object);
+}
+
+class Foo {
+ final String value;
+ Foo(this.value);
+}
+
+class TargetLayout64Bit {
+ // field0 is header word.
+ final Object field1;
+ final int field2;
+ final int field3;
+ final int field4;
+ final int field5;
+ final int field6;
+ final int field7;
+ final int field8;
+ final int field9;
+ final int field10;
+ final int field11;
+ final int field12;
+ final int field13;
+ final int field14;
+ final int field15;
+ final int field16;
+ final int field17;
+ final int field18;
+ final int field19;
+ final int field20;
+ final int field21;
+ final int field22;
+ final int field23;
+ final int field24;
+ final int field25;
+ final int field26;
+ final int field27;
+ final int field28;
+ final int field29;
+ final int field30;
+ final int field31;
+ final int field32;
+ final int field33;
+ final int field34;
+ final int field35;
+ final int field36;
+ final int field37;
+ final int field38;
+ final int field39;
+ final int field40;
+ final int field41;
+ final int field42;
+ final int field43;
+ final int field44;
+ final int field45;
+ final int field46;
+ final int field47;
+ final int field48;
+ final int field49;
+ final int field50;
+ final int field51;
+ final int field52;
+ final int field53;
+ final int field54;
+ final int field55;
+ final int field56;
+ final int field57;
+ final int field58;
+ final int field59;
+ final int field60;
+ final int field61;
+ final int field62;
+ final int field63;
+
+ // For 64-bit targets there are no more bits available so we need to start
+ // boxing all fields from here (this is performed in the class finalizer).
+
+ final Object field64;
+
+ // If GC incorrectly uses (bitmap & (1 << 65)) then will access bit of
+ // [field1] and incorrectly think it is an object pointer.
+ final int field65;
+
+ // If GC incorrectly uses (bitmap & (1 << 66)) then will access bit of
+ // [field2] and incorrectly think it is a unboxed value.
+ final Object field66;
+
+ const TargetLayout64Bit(
+ this.field1,
+ this.field2,
+ this.field3,
+ this.field4,
+ this.field5,
+ this.field6,
+ this.field7,
+ this.field8,
+ this.field9,
+ this.field10,
+ this.field11,
+ this.field12,
+ this.field13,
+ this.field14,
+ this.field15,
+ this.field16,
+ this.field17,
+ this.field18,
+ this.field19,
+ this.field20,
+ this.field21,
+ this.field22,
+ this.field23,
+ this.field24,
+ this.field25,
+ this.field26,
+ this.field27,
+ this.field28,
+ this.field29,
+ this.field30,
+ this.field31,
+ this.field32,
+ this.field33,
+ this.field34,
+ this.field35,
+ this.field36,
+ this.field37,
+ this.field38,
+ this.field39,
+ this.field40,
+ this.field41,
+ this.field42,
+ this.field43,
+ this.field44,
+ this.field45,
+ this.field46,
+ this.field47,
+ this.field48,
+ this.field49,
+ this.field50,
+ this.field51,
+ this.field52,
+ this.field53,
+ this.field54,
+ this.field55,
+ this.field56,
+ this.field57,
+ this.field58,
+ this.field59,
+ this.field60,
+ this.field61,
+ this.field62,
+ this.field63,
+ this.field64,
+ this.field65,
+ this.field66);
+
+ // Ensure all fields are used.
+ String toString() => '''
+ <header>, $field1, $field2, $field3, $field4, $field5, $field6, $field7,
+ $field8, $field9, $field10, $field11, $field12, $field13, $field14, $field15,
+ $field16, $field17, $field18, $field19, $field20, $field21, $field22, $field23,
+ $field24, $field25, $field26, $field27, $field28, $field29, $field30, $field31,
+ $field32, $field33, $field34, $field35, $field36, $field37, $field38, $field39,
+ $field40, $field41, $field42, $field43, $field44, $field45, $field46, $field47,
+ $field48, $field49, $field50, $field51, $field52, $field53, $field54, $field55,
+ $field56, $field57, $field58, $field59, $field60, $field61, $field62, $field63,
+ $field64, $field65, $field66''';
+}
+
+@pragma('vm:never-inline')
+buildTargetLayout64Bit() => TargetLayout64Bit(
+ objectFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ integerFieldValue,
+ objectFieldValue,
+ integerFieldValue,
+ objectFieldValue);
diff --git a/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart b/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
index 04c06e6..c67b5ef 100644
--- a/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
+++ b/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
@@ -134,16 +134,38 @@
Expect.deepEquals(translatedStackFrames, originalStackFrames);
- // Since we compiled directly to ELF, there should be 'virt' markers in the
- // stack traces. Make sure the address following the marker matches the
- // relocated address calculated from the PCOffset for each frame.
+ // Since we compiled directly to ELF, there should be a DSO base address
+ // in the stack trace header and 'virt' markers in the stack frames.
+
+ // The offsets of absolute addresses from their respective DSO base
+ // should be the same for both traces.
+ final dsoBase1 = dsoBaseAddresses(dwarfTrace1).single;
+ final dsoBase2 = dsoBaseAddresses(dwarfTrace2).single;
+
+ final absTrace1 = absoluteAddresses(dwarfTrace1);
+ final absTrace2 = absoluteAddresses(dwarfTrace2);
+
+ final relocatedFromDso1 = absTrace1.map((a) => a - dsoBase1);
+ final relocatedFromDso2 = absTrace2.map((a) => a - dsoBase2);
+
+ Expect.deepEquals(relocatedFromDso1, relocatedFromDso2);
+
+ // The relocated addresses marked with 'virt' should match between the
+ // different runs, and they should also match the relocated address
+ // calculated from the PCOffset for each frame as well as the relocated
+ // address for each frame calculated using the respective DSO base.
final virtTrace1 = explicitVirtualAddresses(dwarfTrace1);
final virtTrace2 = explicitVirtualAddresses(dwarfTrace2);
+ Expect.deepEquals(virtTrace1, virtTrace2);
+
Expect.deepEquals(
virtTrace1, tracePCOffsets1.map((o) => o.virtualAddressIn(dwarf)));
Expect.deepEquals(
virtTrace2, tracePCOffsets2.map((o) => o.virtualAddressIn(dwarf)));
+
+ Expect.deepEquals(virtTrace1, relocatedFromDso1);
+ Expect.deepEquals(virtTrace2, relocatedFromDso2);
});
}
@@ -153,13 +175,26 @@
return lines.where((line) => _symbolicFrameRE.hasMatch(line));
}
-final _virtRE = RegExp(r'virt ([a-f\d]+)');
-
-Iterable<int> explicitVirtualAddresses(Iterable<String> lines) sync* {
+Iterable<int> parseUsingAddressRegExp(RegExp re, Iterable<String> lines) sync* {
for (final line in lines) {
- final match = _virtRE.firstMatch(line);
+ final match = re.firstMatch(line);
if (match != null) {
yield int.parse(match.group(1), radix: 16);
}
}
}
+
+final _absRE = RegExp(r'abs ([a-f\d]+)');
+
+Iterable<int> absoluteAddresses(Iterable<String> lines) =>
+ parseUsingAddressRegExp(_absRE, lines);
+
+final _virtRE = RegExp(r'virt ([a-f\d]+)');
+
+Iterable<int> explicitVirtualAddresses(Iterable<String> lines) =>
+ parseUsingAddressRegExp(_virtRE, lines);
+
+final _dsoBaseRE = RegExp(r'isolate_dso_base: ([a-f\d]+)');
+
+Iterable<int> dsoBaseAddresses(Iterable<String> lines) =>
+ parseUsingAddressRegExp(_dsoBaseRE, lines);
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index f8d4cdf..56d9a7c 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -115,7 +115,7 @@
} else {
extra_deps = [
"//zircon/public/lib/fbl",
- "//zircon/public/lib/trace-engine",
+ "//zircon/system/ulib/trace-engine",
]
}
}
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 8903a2b..62be369 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -15,6 +15,7 @@
#include "vm/kernel.h"
#include "vm/kernel_loader.h"
#endif
+#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/symbols.h"
@@ -105,40 +106,49 @@
const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
return ApiError::New(msg, Heap::kOld);
}
- program->AutoDetectNullSafety(thread->isolate());
- kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
- Isolate* isolate = thread->isolate();
+ LongJumpScope jump;
+ if (setjmp(*jump.Set()) == 0) {
+ program->AutoDetectNullSafety(thread->isolate());
+ kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
- if (isolate->obfuscate()) {
- loader.ReadObfuscationProhibitions();
+ Isolate* isolate = thread->isolate();
+
+ if (isolate->obfuscate()) {
+ loader.ReadObfuscationProhibitions();
+ }
+
+ // Load the bootstrap libraries in order (see object_store.h).
+ Library& library = Library::Handle(zone);
+ for (intptr_t i = 0; i < kBootstrapLibraryCount; ++i) {
+ ObjectStore::BootstrapLibraryId id = bootstrap_libraries[i].index;
+ library = isolate->object_store()->bootstrap_library(id);
+ loader.LoadLibrary(library);
+ }
+
+ // Finish bootstrapping, including class finalization.
+ Finish(thread);
+
+ // The platform binary may contain other libraries (e.g., dart:_builtin or
+ // dart:io) that will not be bundled with application. Load them now.
+ const Object& result = Object::Handle(zone, loader.LoadProgram());
+ program.reset();
+ if (result.IsError()) {
+ return Error::Cast(result).raw();
+ }
+
+ // The builtin library should be registered with the VM.
+ const auto& dart_builtin =
+ String::Handle(zone, String::New("dart:_builtin"));
+ library = Library::LookupLibrary(thread, dart_builtin);
+ isolate->object_store()->set_builtin_library(library);
+
+ return Error::null();
}
- // Load the bootstrap libraries in order (see object_store.h).
- Library& library = Library::Handle(zone);
- for (intptr_t i = 0; i < kBootstrapLibraryCount; ++i) {
- ObjectStore::BootstrapLibraryId id = bootstrap_libraries[i].index;
- library = isolate->object_store()->bootstrap_library(id);
- loader.LoadLibrary(library);
- }
-
- // Finish bootstrapping, including class finalization.
- Finish(thread);
-
- // The platform binary may contain other libraries (e.g., dart:_builtin or
- // dart:io) that will not be bundled with application. Load them now.
- const Object& result = Object::Handle(zone, loader.LoadProgram());
- program.reset();
- if (result.IsError()) {
- return Error::Cast(result).raw();
- }
-
- // The builtin library should be registered with the VM.
- const auto& dart_builtin = String::Handle(zone, String::New("dart:_builtin"));
- library = Library::LookupLibrary(thread, dart_builtin);
- isolate->object_store()->set_builtin_library(library);
-
- return Error::null();
+ // Either class finalization failed or we caught a compile-time error.
+ // In both cases sticky error would be set.
+ return Thread::Current()->StealStickyError();
}
ErrorPtr Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer,
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 7246a53..2460846 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -330,6 +330,7 @@
V(GrowableList_setData, 2) \
V(Internal_unsafeCast, 1) \
V(Internal_reachabilityFence, 1) \
+ V(Internal_collectAllGarbage, 0) \
V(Internal_makeListFixedLength, 1) \
V(Internal_makeFixedListUnmodifiable, 1) \
V(Internal_inquireIs64Bit, 0) \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 007eb2b..ec53422 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -1497,7 +1497,8 @@
class CodeSerializationCluster : public SerializationCluster {
public:
- CodeSerializationCluster() : SerializationCluster("Code") {}
+ explicit CodeSerializationCluster(Heap* heap)
+ : SerializationCluster("Code") {}
~CodeSerializationCluster() {}
void Trace(Serializer* s, ObjectPtr object) {
@@ -1632,6 +1633,24 @@
GrowableArray<CodePtr>* discovered_objects() { return &objects_; }
+ // Some code objects would have their owners dropped from the snapshot,
+ // which makes it is impossible to recover program structure when
+ // analysing snapshot profile. To facilitate analysis of snapshot profiles
+ // we include artificial nodes into profile representing such dropped
+ // owners.
+ void WriteDroppedOwnersIntoProfile(Serializer* s) {
+ ASSERT(s->profile_writer() != nullptr);
+
+ for (auto code : objects_) {
+ ObjectPtr owner = WeakSerializationReference::Unwrap(code->ptr()->owner_);
+ if (s->CreateArtificalNodeIfNeeded(owner)) {
+ AutoTraceObject(code);
+ s->AttributePropertyRef(owner, ":owner_",
+ /*permit_artificial_ref=*/true);
+ }
+ }
+ }
+
private:
GrowableArray<CodePtr> objects_;
};
@@ -2025,7 +2044,7 @@
ASSERT(Serializer::IsReachableReference(heap_->GetObjectId(ref)));
if (ShouldDrop(ref)) {
// For dropped references, reset their ID to be the unreachable
- // reference value, so WriteRefId retrieves the target ID instead.
+ // reference value, so RefId retrieves the target ID instead.
heap_->SetObjectId(ref, Serializer::kUnreachableReference);
continue;
}
@@ -4734,6 +4753,9 @@
id = smi_ids_.Lookup(Smi::RawCast(obj))->id_;
cid = Smi::kClassId;
}
+ if (IsArtificialReference(id)) {
+ id = -id;
+ }
ASSERT(IsAllocatedReference(id));
const char* name_str = nullptr;
@@ -4761,6 +4783,67 @@
}
}
+bool Serializer::CreateArtificalNodeIfNeeded(ObjectPtr obj) {
+ ASSERT(profile_writer() != nullptr);
+
+ intptr_t id = heap_->GetObjectId(obj);
+ if (Serializer::IsAllocatedReference(id)) {
+ return false;
+ }
+ if (Serializer::IsArtificialReference(id)) {
+ return true;
+ }
+ ASSERT(id == Serializer::kUnreachableReference);
+ id = AssignArtificialRef(obj);
+
+ const char* type = nullptr;
+ StringPtr name = nullptr;
+ ObjectPtr owner = nullptr;
+ const char* owner_ref_name = nullptr;
+ switch (obj->GetClassId()) {
+ case kFunctionCid: {
+ FunctionPtr func = static_cast<FunctionPtr>(obj);
+ type = "Function";
+ name = func->ptr()->name_;
+ owner_ref_name = "owner_";
+ owner = func->ptr()->owner_;
+ break;
+ }
+ case kClassCid: {
+ ClassPtr cls = static_cast<ClassPtr>(obj);
+ type = "Class";
+ name = cls->ptr()->name_;
+ owner_ref_name = "library_";
+ owner = cls->ptr()->library_;
+ break;
+ }
+ case kPatchClassCid: {
+ PatchClassPtr patch_cls = static_cast<PatchClassPtr>(obj);
+ type = "PatchClass";
+ owner_ref_name = "patched_class_";
+ owner = patch_cls->ptr()->patched_class_;
+ break;
+ }
+ case kLibraryCid: {
+ LibraryPtr lib = static_cast<LibraryPtr>(obj);
+ type = "Library";
+ name = lib->ptr()->url_;
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ TraceStartWritingObject(type, obj, name);
+ if (owner != nullptr) {
+ CreateArtificalNodeIfNeeded(owner);
+ AttributePropertyRef(owner, owner_ref_name,
+ /*permit_artificial_ref=*/true);
+ }
+ TraceEndWritingObject();
+ return true;
+}
+
const char* Serializer::ReadOnlyObjectType(intptr_t cid) {
switch (cid) {
case kPcDescriptorsCid:
@@ -4832,7 +4915,7 @@
case kKernelProgramInfoCid:
return new (Z) KernelProgramInfoSerializationCluster();
case kCodeCid:
- return new (Z) CodeSerializationCluster();
+ return new (Z) CodeSerializationCluster(heap_);
case kBytecodeCid:
return new (Z) BytecodeSerializationCluster();
case kObjectPoolCid:
@@ -5224,6 +5307,16 @@
// We should have assigned a ref to every object we pushed.
ASSERT((next_ref_index_ - 1) == num_objects);
+#if defined(DART_PRECOMPILER)
+ // When writing snapshot profile, we want to retain some of the program
+ // structure information (e.g. information about libraries, classes and
+ // functions - even if it was dropped when writing snapshot itself).
+ if (FLAG_write_v8_snapshot_profile_to != nullptr) {
+ static_cast<CodeSerializationCluster*>(clusters_by_cid_[kCodeCid])
+ ->WriteDroppedOwnersIntoProfile(this);
+ }
+#endif
+
for (intptr_t cid = 1; cid < num_cids_; cid++) {
SerializationCluster* cluster = clusters_by_cid_[cid];
if (cluster != NULL) {
@@ -5279,7 +5372,7 @@
// Reference IDs in a cluster are allocated sequentially, so we can use the
// first code object's reference ID to calculate the cluster index.
const intptr_t first_code_id =
- WriteRefId(code_cluster->discovered_objects()->At(0));
+ RefId(code_cluster->discovered_objects()->At(0));
// The first object in the code cluster must have its reference ID allocated.
ASSERT(IsAllocatedReference(first_code_id));
@@ -5339,7 +5432,7 @@
}
// We have a non-repeated, non-recent entry, so encode the reference ID of
// the code object and emit that.
- auto const object_id = WriteRefId(code);
+ auto const object_id = RefId(code);
// Make sure that this code object has an allocated reference ID.
ASSERT(IsAllocatedReference(object_id));
// Use the index in the code cluster, not in the snapshot..
@@ -5598,7 +5691,7 @@
auto const code = Code::RawCast(dispatch_table_entries.At(i));
if (code == Code::null()) continue;
const V8SnapshotProfileWriter::ObjectId code_id(
- V8SnapshotProfileWriter::kSnapshot, WriteRefId(code));
+ V8SnapshotProfileWriter::kSnapshot, RefId(code));
profile_writer_->AttributeReferenceTo(
dispatch_table_snapshot_id,
{code_id, V8SnapshotProfileWriter::Reference::kElement, i});
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index d9d4123..ddf07cb 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -145,7 +145,7 @@
static const intptr_t kUnreachableReference = 0;
static constexpr bool IsReachableReference(intptr_t ref) {
- return ref != kUnreachableReference;
+ return ref == kUnallocatedReference || IsAllocatedReference(ref);
}
// Reference value for traced objects that have not been allocated their final
@@ -153,7 +153,11 @@
static const intptr_t kUnallocatedReference = -1;
static constexpr bool IsAllocatedReference(intptr_t ref) {
- return IsReachableReference(ref) && ref != kUnallocatedReference;
+ return ref > kUnreachableReference;
+ }
+
+ static constexpr bool IsArtificialReference(intptr_t ref) {
+ return ref < kUnallocatedReference;
}
intptr_t WriteVMSnapshot(const Array& symbols);
@@ -205,6 +209,15 @@
return next_ref_index_++;
}
+ intptr_t AssignArtificialRef(ObjectPtr object) {
+ ASSERT(object.IsHeapObject());
+ const intptr_t ref = -(next_ref_index_++);
+ ASSERT(IsArtificialReference(ref));
+ heap_->SetObjectId(object, ref);
+ ASSERT(heap_->GetObjectId(object) == ref);
+ return ref;
+ }
+
void Push(ObjectPtr object);
void AddUntracedRef() { num_written_objects_++; }
@@ -262,7 +275,7 @@
void Align(intptr_t alignment) { stream_.Align(alignment); }
void WriteRootRef(ObjectPtr object, const char* name = nullptr) {
- intptr_t id = WriteRefId(object);
+ intptr_t id = RefId(object);
WriteUnsigned(id);
if (profile_writer_ != nullptr) {
profile_writer_->AddRoot({V8SnapshotProfileWriter::kSnapshot, id}, name);
@@ -270,25 +283,15 @@
}
void WriteElementRef(ObjectPtr object, intptr_t index) {
- intptr_t id = WriteRefId(object);
- WriteUnsigned(id);
- if (profile_writer_ != nullptr) {
- profile_writer_->AttributeReferenceTo(
- {V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
- {{V8SnapshotProfileWriter::kSnapshot, id},
- V8SnapshotProfileWriter::Reference::kElement,
- index});
- }
+ WriteUnsigned(AttributeElementRef(object, index));
}
// Record a reference from the currently written object to the given object
- // without actually writing the reference into the snapshot.
- // Used to create artificial connection between objects which are not
- // explicitly connected in the heap, for example an object referenced
- // by the global object pool is in reality referenced by the code which
- // caused this reference to be added to the global object pool.
- void AttributeElementRef(ObjectPtr object, intptr_t index) {
- intptr_t id = WriteRefId(object);
+ // and return reference id for the given object.
+ intptr_t AttributeElementRef(ObjectPtr object,
+ intptr_t index,
+ bool permit_artificial_ref = false) {
+ intptr_t id = RefId(object, permit_artificial_ref);
if (profile_writer_ != nullptr) {
profile_writer_->AttributeReferenceTo(
{V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
@@ -296,11 +299,19 @@
V8SnapshotProfileWriter::Reference::kElement,
index});
}
+ return id;
}
void WritePropertyRef(ObjectPtr object, const char* property) {
- intptr_t id = WriteRefId(object);
- WriteUnsigned(id);
+ WriteUnsigned(AttributePropertyRef(object, property));
+ }
+
+ // Record a reference from the currently written object to the given object
+ // and return reference id for the given object.
+ intptr_t AttributePropertyRef(ObjectPtr object,
+ const char* property,
+ bool permit_artificial_ref = false) {
+ intptr_t id = RefId(object, permit_artificial_ref);
if (profile_writer_ != nullptr) {
profile_writer_->AttributeReferenceTo(
{V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
@@ -308,10 +319,11 @@
V8SnapshotProfileWriter::Reference::kProperty,
profile_writer_->EnsureString(property)});
}
+ return id;
}
void WriteOffsetRef(ObjectPtr object, intptr_t offset) {
- intptr_t id = WriteRefId(object);
+ intptr_t id = RefId(object);
WriteUnsigned(id);
if (profile_writer_ != nullptr) {
const char* property = offsets_table_->FieldNameForOffset(
@@ -375,13 +387,21 @@
void DumpCombinedCodeStatistics();
+ V8SnapshotProfileWriter* profile_writer() const { return profile_writer_; }
+
+ // If the given [obj] was not included into the snaposhot and have not
+ // yet gotten an artificial node created for it create an artificial node
+ // in the profile representing this object.
+ // Returns true if [obj] has an artificial profile node associated with it.
+ bool CreateArtificalNodeIfNeeded(ObjectPtr obj);
+
private:
static const char* ReadOnlyObjectType(intptr_t cid);
// Returns the reference ID for the object. Fails for objects that have not
// been allocated a reference ID yet, so should be used only after all
// WriteAlloc calls.
- intptr_t WriteRefId(ObjectPtr object) {
+ intptr_t RefId(ObjectPtr object, bool permit_artificial_ref = false) {
if (!object->IsHeapObject()) {
SmiPtr smi = Smi::RawCast(object);
auto const id = smi_ids_.Lookup(smi)->id_;
@@ -392,6 +412,10 @@
// of ref indices.
ASSERT(!object->IsInstructions());
auto const id = heap_->GetObjectId(object);
+ if (permit_artificial_ref && IsArtificialReference(id)) {
+ return -id;
+ }
+ ASSERT(!IsArtificialReference(id));
if (IsAllocatedReference(id)) return id;
if (object->IsWeakSerializationReference()) {
// If a reachable WSR has an object ID of 0, then its target was marked
@@ -405,11 +429,11 @@
return target_id;
}
if (object->IsCode() && !Snapshot::IncludesCode(kind_)) {
- return WriteRefId(Object::null());
+ return RefId(Object::null());
}
#if !defined(DART_PRECOMPILED_RUNTIME)
if (object->IsBytecode() && !Snapshot::IncludesBytecode(kind_)) {
- return WriteRefId(Object::null());
+ return RefId(Object::null());
}
#endif // !DART_PRECOMPILED_RUNTIME
FATAL("Missing ref");
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index c94d18e..d3b004e 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -3984,10 +3984,11 @@
return;
}
ASSERT(kSmiTag == 0);
- __ LslImmediate(out, in, kSmiTagSize);
+ __ adds(out, in, compiler::Operand(in)); // SmiTag
compiler::Label done;
- __ cmp(in, compiler::Operand(out, ASR, kSmiTagSize));
- __ b(&done, EQ);
+ // If the value doesn't fit in a smi, the tagging changes the sign,
+ // which causes the overflow flag to be set.
+ __ b(&done, NO_OVERFLOW);
Register temp = locs()->temp(0).reg();
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 539abcd..857d0ce 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -4194,6 +4194,8 @@
if (!ValueFitsSmi()) {
const Register temp = locs()->temp(0).reg();
compiler::Label done;
+ // If the value doesn't fit in a smi, the tagging changes the sign,
+ // which causes the overflow flag to be set.
__ j(NO_OVERFLOW, &done);
BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
temp);
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 96c6a3a..499d169 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -276,6 +276,10 @@
const intptr_t vreg = def->ssa_temp_index();
kill_[entry->postorder_number()]->Add(vreg);
live_in_[entry->postorder_number()]->Remove(vreg);
+ if (def->HasPairRepresentation()) {
+ kill_[entry->postorder_number()]->Add(ToSecondPairVreg((vreg)));
+ live_in_[entry->postorder_number()]->Remove(ToSecondPairVreg(vreg));
+ }
}
}
}
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 99cad2f..9817021 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -697,12 +697,14 @@
for (intptr_t i = 0; i < num_type_params; ++i) {
parameter ^= type_parameters.TypeAt(i);
bound ^= ReadObject();
- // Convert dynamic to Object in bounds of type parameters so
+ // Convert dynamic to Object? or Object* in bounds of type parameters so
// they are equivalent when doing subtype checks for function types.
// TODO(https://github.com/dart-lang/language/issues/495): revise this
// when function subtyping is fixed.
if (bound.IsDynamicType()) {
- bound = I->object_store()->object_type();
+ bound = nnbd_mode == NNBDMode::kOptedInLib
+ ? I->object_store()->nullable_object_type()
+ : I->object_store()->legacy_object_type();
}
parameter.set_bound(bound);
}
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 80d6d2c..2a694ee 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -3300,7 +3300,10 @@
const Tag tag = helper_->PeekTag(); // peek ith bound type.
if (tag == kDynamicType) {
helper_->SkipDartType(); // read ith bound.
- parameter.set_bound(Type::Handle(Z, I->object_store()->object_type()));
+ parameter.set_bound(
+ Type::Handle(Z, nnbd_mode == NNBDMode::kOptedInLib
+ ? I->object_store()->nullable_object_type()
+ : I->object_store()->legacy_object_type()));
} else {
AbstractType& bound = BuildTypeWithoutFinalization(); // read ith bound.
parameter.set_bound(bound);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 3abc747..53f4ff6 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -57,7 +57,7 @@
}
// [R0] already contains first argument.
__ mov(R1, Operand(THR));
- __ CallRuntime(kAddAllocatedObjectToRememberedSetRuntimeEntry, 2);
+ __ CallRuntime(kEnsureRememberedAndMarkingDeferredRuntimeEntry, 2);
if (preserve_registers) {
__ LeaveCallRuntimeFrame();
}
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 464f368..5b74a2e 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -55,7 +55,7 @@
}
// [R0] already contains first argument.
__ mov(R1, THR);
- __ CallRuntime(kAddAllocatedObjectToRememberedSetRuntimeEntry, 2);
+ __ CallRuntime(kEnsureRememberedAndMarkingDeferredRuntimeEntry, 2);
if (preserve_registers) {
__ LeaveCallRuntimeFrame();
}
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 6e9e479..d7cbd37 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -55,7 +55,7 @@
}
__ movl(Address(ESP, 1 * target::kWordSize), THR);
__ movl(Address(ESP, 0 * target::kWordSize), EAX);
- __ CallRuntime(kAddAllocatedObjectToRememberedSetRuntimeEntry, 2);
+ __ CallRuntime(kEnsureRememberedAndMarkingDeferredRuntimeEntry, 2);
if (preserve_registers) {
__ LeaveCallRuntimeFrame();
}
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 3f37069..6b8a5b8 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -57,7 +57,7 @@
}
__ movq(CallingConventions::kArg1Reg, RAX);
__ movq(CallingConventions::kArg2Reg, THR);
- __ CallRuntime(kAddAllocatedObjectToRememberedSetRuntimeEntry, 2);
+ __ CallRuntime(kEnsureRememberedAndMarkingDeferredRuntimeEntry, 2);
if (preserve_registers) {
__ LeaveCallRuntimeFrame();
}
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 41807f8..3670ea5 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -524,6 +524,8 @@
UNSIGNED_LESS_EQUAL = LS,
UNSIGNED_GREATER = HI,
UNSIGNED_GREATER_EQUAL = CS,
+ OVERFLOW = VS,
+ NO_OVERFLOW = VC,
kInvalidCondition = 16
};
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 32eed66..859db5b 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -374,6 +374,8 @@
UNSIGNED_LESS_EQUAL = LS,
UNSIGNED_GREATER = HI,
UNSIGNED_GREATER_EQUAL = CS,
+ OVERFLOW = VS,
+ NO_OVERFLOW = VC,
kInvalidCondition = 16
};
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 230d291..6ed8438 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -649,7 +649,8 @@
// Find the relocated base of the loaded ELF snapshot. Returns 0 if there is
// no loaded ELF snapshot.
uword Elf::SnapshotRelocatedBaseAddress(uword vm_start) {
- ASSERT(vm_start > kVmSnapshotOffset);
+ // We can't running from a loaded ELF snapshot if this is the case.
+ if (vm_start < kVmSnapshotOffset) return 0;
const Image vm_instructions_image(reinterpret_cast<const void*>(vm_start));
if (!vm_instructions_image.compiled_to_elf()) return 0;
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index 893a989..3ac014d 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -17,9 +17,6 @@
#undef near
#endif // defined(_WIN32)
-// The following #defines are invalidated.
-#undef OVERFLOW // From math.h conflicts in constants_ia32.h
-
namespace dart {
// Smi value range is from -(2^N) to (2^N)-1.
// N=30 (32-bit build) or N=62 (64-bit build).
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index c99181e..0a36e5e 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -332,21 +332,28 @@
enum RootSlices {
kIsolate = 0,
- kNewSpace = 1,
- kNumRootSlices = 2,
+ kNumFixedRootSlices = 1,
};
void GCMarker::ResetSlices() {
+ ASSERT(Thread::Current()->IsAtSafepoint());
+
root_slices_started_ = 0;
root_slices_finished_ = 0;
+ root_slices_count_ = kNumFixedRootSlices;
+ new_page_ = heap_->new_space()->head();
+ for (NewPage* p = new_page_; p != nullptr; p = p->next()) {
+ root_slices_count_++;
+ }
+
weak_slices_started_ = 0;
}
void GCMarker::IterateRoots(ObjectPointerVisitor* visitor) {
for (;;) {
intptr_t slice = root_slices_started_.fetch_add(1);
- if (slice >= kNumRootSlices) {
- return; // No more slices.
+ if (slice >= root_slices_count_) {
+ break; // No more slices.
}
switch (slice) {
@@ -357,18 +364,22 @@
visitor, ValidationPolicy::kDontValidateFrames);
break;
}
- case kNewSpace: {
+ default: {
+ NewPage* page;
+ {
+ MonitorLocker ml(&root_slices_monitor_);
+ page = new_page_;
+ ASSERT(page != nullptr);
+ new_page_ = page->next();
+ }
TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ProcessNewSpace");
- heap_->new_space()->VisitObjectPointers(visitor);
- break;
+ page->VisitObjectPointers(visitor);
}
- default:
- UNREACHABLE();
}
MonitorLocker ml(&root_slices_monitor_);
root_slices_finished_++;
- if (root_slices_finished_ == kNumRootSlices) {
+ if (root_slices_finished_ == root_slices_count_) {
ml.Notify();
}
}
@@ -759,7 +770,7 @@
// Wait for roots to be marked before exiting safepoint.
MonitorLocker ml(&root_slices_monitor_);
- while (root_slices_finished_ != kNumRootSlices) {
+ while (root_slices_finished_ != root_slices_count_) {
ml.Wait();
}
}
diff --git a/runtime/vm/heap/marker.h b/runtime/vm/heap/marker.h
index 7f78a58..6f9e309 100644
--- a/runtime/vm/heap/marker.h
+++ b/runtime/vm/heap/marker.h
@@ -19,6 +19,7 @@
class PageSpace;
template <bool sync>
class MarkingVisitorBase;
+class NewPage;
class Thread;
// The class GCMarker is used to mark reachable old generation objects as part
@@ -65,9 +66,11 @@
MarkingStack deferred_marking_stack_;
MarkingVisitorBase<true>** visitors_;
+ NewPage* new_page_;
Monitor root_slices_monitor_;
RelaxedAtomic<intptr_t> root_slices_started_;
intptr_t root_slices_finished_;
+ intptr_t root_slices_count_;
RelaxedAtomic<intptr_t> weak_slices_started_;
Mutex stats_mutex_;
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index bcc6fc7..489e47d 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -100,142 +100,6 @@
} while (size > 0);
}
-static constexpr intptr_t kNewPageSize = 512 * KB;
-static constexpr intptr_t kNewPageSizeInWords = kNewPageSize / kWordSize;
-static constexpr intptr_t kNewPageMask = ~(kNewPageSize - 1);
-
-// A page containing new generation objects.
-class NewPage {
- public:
- static NewPage* Allocate();
- void Deallocate();
-
- uword start() const { return memory_->start(); }
- uword end() const { return memory_->end(); }
- bool Contains(uword addr) const { return memory_->Contains(addr); }
- void WriteProtect(bool read_only) {
- memory_->Protect(read_only ? VirtualMemory::kReadOnly
- : VirtualMemory::kReadWrite);
- }
-
- NewPage* next() const { return next_; }
- void set_next(NewPage* next) { next_ = next; }
-
- Thread* owner() const { return owner_; }
-
- uword object_start() const { return start() + ObjectStartOffset(); }
- uword object_end() const { return owner_ != nullptr ? owner_->top() : top_; }
- void VisitObjects(ObjectVisitor* visitor) const {
- uword addr = object_start();
- uword end = object_end();
- while (addr < end) {
- ObjectPtr obj = ObjectLayout::FromAddr(addr);
- visitor->VisitObject(obj);
- addr += obj->ptr()->HeapSize();
- }
- }
- void VisitObjectPointers(ObjectPointerVisitor* visitor) const {
- uword addr = object_start();
- uword end = object_end();
- while (addr < end) {
- ObjectPtr obj = ObjectLayout::FromAddr(addr);
- intptr_t size = obj->ptr()->VisitPointers(visitor);
- addr += size;
- }
- }
-
- static intptr_t ObjectStartOffset() {
- return Utils::RoundUp(sizeof(NewPage), kObjectAlignment) +
- kNewObjectAlignmentOffset;
- }
-
- static NewPage* Of(ObjectPtr obj) {
- ASSERT(obj->IsHeapObject());
- ASSERT(obj->IsNewObject());
- return Of(static_cast<uword>(obj));
- }
- static NewPage* Of(uword addr) {
- return reinterpret_cast<NewPage*>(addr & kNewPageMask);
- }
-
- // Remember the limit to which objects have been copied.
- void RecordSurvivors() { survivor_end_ = object_end(); }
-
- // Move survivor end to the end of the to_ space, making all surviving
- // objects candidates for promotion next time.
- void EarlyTenure() { survivor_end_ = end_; }
-
- uword promo_candidate_words() const {
- return (survivor_end_ - object_start()) / kWordSize;
- }
-
- void Acquire(Thread* thread) {
- ASSERT(owner_ == nullptr);
- owner_ = thread;
- thread->set_top(top_);
- thread->set_end(end_);
- }
- void Release(Thread* thread) {
- ASSERT(owner_ == thread);
- owner_ = nullptr;
- top_ = thread->top();
- thread->set_top(0);
- thread->set_end(0);
- }
- void Release() {
- if (owner_ != nullptr) {
- Release(owner_);
- }
- }
-
- uword TryAllocateGC(intptr_t size) {
- ASSERT(owner_ == nullptr);
- uword result = top_;
- uword new_top = result + size;
- if (LIKELY(new_top < end_)) {
- top_ = new_top;
- return result;
- }
- return 0;
- }
-
- void Unallocate(uword addr, intptr_t size) {
- ASSERT((addr + size) == top_);
- top_ -= size;
- }
-
- bool IsSurvivor(uword raw_addr) const { return raw_addr < survivor_end_; }
- bool IsResolved() const { return top_ == resolved_top_; }
-
- private:
- VirtualMemory* memory_;
- NewPage* next_;
-
- // The thread using this page for allocation, otherwise NULL.
- Thread* owner_;
-
- // The address of the next allocation. If owner is non-NULL, this value is
- // stale and the current value is at owner->top_. Called "NEXT" in the
- // original Cheney paper.
- uword top_;
-
- // The address after the last allocatable byte in this page.
- uword end_;
-
- // Objects below this address have survived a scavenge.
- uword survivor_end_;
-
- // A pointer to the first unprocessed object. Resolution completes when this
- // value meets the allocation top. Called "SCAN" in the original Cheney paper.
- uword resolved_top_;
-
- template <bool>
- friend class ScavengerVisitorBase;
-
- DISALLOW_ALLOCATION();
- DISALLOW_IMPLICIT_CONSTRUCTORS(NewPage);
-};
-
template <bool parallel>
class ScavengerVisitorBase : public ObjectPointerVisitor {
public:
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index 20109fa..098d96f 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -24,11 +24,146 @@
class Heap;
class Isolate;
class JSONObject;
-class NewPage;
class ObjectSet;
template <bool parallel>
class ScavengerVisitorBase;
+static constexpr intptr_t kNewPageSize = 512 * KB;
+static constexpr intptr_t kNewPageSizeInWords = kNewPageSize / kWordSize;
+static constexpr intptr_t kNewPageMask = ~(kNewPageSize - 1);
+
+// A page containing new generation objects.
+class NewPage {
+ public:
+ static NewPage* Allocate();
+ void Deallocate();
+
+ uword start() const { return memory_->start(); }
+ uword end() const { return memory_->end(); }
+ bool Contains(uword addr) const { return memory_->Contains(addr); }
+ void WriteProtect(bool read_only) {
+ memory_->Protect(read_only ? VirtualMemory::kReadOnly
+ : VirtualMemory::kReadWrite);
+ }
+
+ NewPage* next() const { return next_; }
+ void set_next(NewPage* next) { next_ = next; }
+
+ Thread* owner() const { return owner_; }
+
+ uword object_start() const { return start() + ObjectStartOffset(); }
+ uword object_end() const { return owner_ != nullptr ? owner_->top() : top_; }
+ void VisitObjects(ObjectVisitor* visitor) const {
+ uword addr = object_start();
+ uword end = object_end();
+ while (addr < end) {
+ ObjectPtr obj = ObjectLayout::FromAddr(addr);
+ visitor->VisitObject(obj);
+ addr += obj->ptr()->HeapSize();
+ }
+ }
+ void VisitObjectPointers(ObjectPointerVisitor* visitor) const {
+ uword addr = object_start();
+ uword end = object_end();
+ while (addr < end) {
+ ObjectPtr obj = ObjectLayout::FromAddr(addr);
+ intptr_t size = obj->ptr()->VisitPointers(visitor);
+ addr += size;
+ }
+ }
+
+ static intptr_t ObjectStartOffset() {
+ return Utils::RoundUp(sizeof(NewPage), kObjectAlignment) +
+ kNewObjectAlignmentOffset;
+ }
+
+ static NewPage* Of(ObjectPtr obj) {
+ ASSERT(obj->IsHeapObject());
+ ASSERT(obj->IsNewObject());
+ return Of(static_cast<uword>(obj));
+ }
+ static NewPage* Of(uword addr) {
+ return reinterpret_cast<NewPage*>(addr & kNewPageMask);
+ }
+
+ // Remember the limit to which objects have been copied.
+ void RecordSurvivors() { survivor_end_ = object_end(); }
+
+ // Move survivor end to the end of the to_ space, making all surviving
+ // objects candidates for promotion next time.
+ void EarlyTenure() { survivor_end_ = end_; }
+
+ uword promo_candidate_words() const {
+ return (survivor_end_ - object_start()) / kWordSize;
+ }
+
+ void Acquire(Thread* thread) {
+ ASSERT(owner_ == nullptr);
+ owner_ = thread;
+ thread->set_top(top_);
+ thread->set_end(end_);
+ }
+ void Release(Thread* thread) {
+ ASSERT(owner_ == thread);
+ owner_ = nullptr;
+ top_ = thread->top();
+ thread->set_top(0);
+ thread->set_end(0);
+ }
+ void Release() {
+ if (owner_ != nullptr) {
+ Release(owner_);
+ }
+ }
+
+ uword TryAllocateGC(intptr_t size) {
+ ASSERT(owner_ == nullptr);
+ uword result = top_;
+ uword new_top = result + size;
+ if (LIKELY(new_top < end_)) {
+ top_ = new_top;
+ return result;
+ }
+ return 0;
+ }
+
+ void Unallocate(uword addr, intptr_t size) {
+ ASSERT((addr + size) == top_);
+ top_ -= size;
+ }
+
+ bool IsSurvivor(uword raw_addr) const { return raw_addr < survivor_end_; }
+ bool IsResolved() const { return top_ == resolved_top_; }
+
+ private:
+ VirtualMemory* memory_;
+ NewPage* next_;
+
+ // The thread using this page for allocation, otherwise NULL.
+ Thread* owner_;
+
+ // The address of the next allocation. If owner is non-NULL, this value is
+ // stale and the current value is at owner->top_. Called "NEXT" in the
+ // original Cheney paper.
+ uword top_;
+
+ // The address after the last allocatable byte in this page.
+ uword end_;
+
+ // Objects below this address have survived a scavenge.
+ uword survivor_end_;
+
+ // A pointer to the first unprocessed object. Resolution completes when this
+ // value meets the allocation top. Called "SCAN" in the original Cheney paper.
+ uword resolved_top_;
+
+ template <bool>
+ friend class ScavengerVisitorBase;
+
+ DISALLOW_ALLOCATION();
+ DISALLOW_IMPLICIT_CONSTRUCTORS(NewPage);
+};
+
class SemiSpace {
public:
static void Init();
@@ -208,6 +343,8 @@
return max_pool_size > 0 ? max_pool_size : 1;
}
+ NewPage* head() const { return to_->head(); }
+
private:
// Ids for time and data records in Heap::GCStats.
enum {
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index 5899b7c..fcfd87a 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -46,6 +46,11 @@
return snapshot_size - kHeaderSize;
}
+ bool contains(uword address) const {
+ uword start = reinterpret_cast<uword>(object_start());
+ return address >= start && (address - start < object_size());
+ }
+
// Returns the offset of the BSS section from this image. Only has meaning for
// instructions images.
word bss_offset() const {
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index f0bb784..06772b1 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1568,7 +1568,6 @@
start_time_micros_(OS::GetCurrentMonotonicMicros()),
random_(),
mutex_(NOT_IN_PRODUCT("Isolate::mutex_")),
- symbols_lock_(new SafepointRwLock()),
type_canonicalization_mutex_(
NOT_IN_PRODUCT("Isolate::type_canonicalization_mutex_")),
constant_canonicalization_mutex_(
@@ -2800,8 +2799,8 @@
return;
}
- if (thread->IsAtSafepoint() &&
- safepoint_handler()->IsOwnedByTheThread(thread)) {
+ if (thread->IsAtSafepoint()) {
+ RELEASE_ASSERT(safepoint_handler()->IsOwnedByTheThread(thread));
single_current_mutator();
return;
}
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 35d295b..93a99f2 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -738,7 +738,6 @@
static intptr_t cached_object_store_offset() {
return OFFSET_OF(Isolate, cached_object_store_);
}
- SafepointRwLock* symbols_lock() { return symbols_lock_.get(); }
FieldTable* field_table() const { return field_table_; }
void set_field_table(Thread* T, FieldTable* field_table) {
@@ -1473,8 +1472,6 @@
Random random_;
Simulator* simulator_ = nullptr;
Mutex mutex_; // Protects compiler stats.
- std::unique_ptr<SafepointRwLock>
- symbols_lock_; // Protects concurrent access to the symbol table.
Mutex type_canonicalization_mutex_; // Protects type canonicalization.
Mutex constant_canonicalization_mutex_; // Protects const canonicalization.
Mutex megamorphic_mutex_; // Protects the table of megamorphic caches and
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 00dae4c..7bfd7d7 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1038,7 +1038,7 @@
}
if (I->null_safety() && (mode == NNBDCompiledMode::kWeak ||
mode == NNBDCompiledMode::kDisabled)) {
- FATAL1(
+ 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());
diff --git a/runtime/vm/native_symbol_android.cc b/runtime/vm/native_symbol_android.cc
index 34a3492..9d0c245 100644
--- a/runtime/vm/native_symbol_android.cc
+++ b/runtime/vm/native_symbol_android.cc
@@ -51,8 +51,12 @@
if (r == 0) {
return false;
}
- *dso_base = reinterpret_cast<uword>(info.dli_fbase);
- *dso_name = strdup(info.dli_fname);
+ if (dso_base != nullptr) {
+ *dso_base = reinterpret_cast<uword>(info.dli_fbase);
+ }
+ if (dso_name != nullptr) {
+ *dso_name = strdup(info.dli_fname);
+ }
return true;
}
diff --git a/runtime/vm/native_symbol_fuchsia.cc b/runtime/vm/native_symbol_fuchsia.cc
index aed0b2a..12b9249 100644
--- a/runtime/vm/native_symbol_fuchsia.cc
+++ b/runtime/vm/native_symbol_fuchsia.cc
@@ -139,8 +139,12 @@
if (r == 0) {
return false;
}
- *dso_base = reinterpret_cast<uword>(info.dli_fbase);
- *dso_name = strdup(info.dli_fname);
+ if (dso_base != nullptr) {
+ *dso_base = reinterpret_cast<uword>(info.dli_fbase);
+ }
+ if (dso_name != nullptr) {
+ *dso_name = strdup(info.dli_fname);
+ }
return true;
}
diff --git a/runtime/vm/native_symbol_linux.cc b/runtime/vm/native_symbol_linux.cc
index 69fc1df..158a2af 100644
--- a/runtime/vm/native_symbol_linux.cc
+++ b/runtime/vm/native_symbol_linux.cc
@@ -52,8 +52,12 @@
if (r == 0) {
return false;
}
- *dso_base = reinterpret_cast<uword>(info.dli_fbase);
- *dso_name = strdup(info.dli_fname);
+ if (dso_base != nullptr) {
+ *dso_base = reinterpret_cast<uword>(info.dli_fbase);
+ }
+ if (dso_name != nullptr) {
+ *dso_name = strdup(info.dli_fname);
+ }
return true;
}
diff --git a/runtime/vm/native_symbol_macos.cc b/runtime/vm/native_symbol_macos.cc
index 88af47b..262bac5 100644
--- a/runtime/vm/native_symbol_macos.cc
+++ b/runtime/vm/native_symbol_macos.cc
@@ -49,8 +49,12 @@
if (r == 0) {
return false;
}
- *dso_base = reinterpret_cast<uword>(info.dli_fbase);
- *dso_name = strdup(info.dli_fname);
+ if (dso_base != nullptr) {
+ *dso_base = reinterpret_cast<uword>(info.dli_fbase);
+ }
+ if (dso_name != nullptr) {
+ *dso_name = strdup(info.dli_fname);
+ }
return true;
}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index daf079c..d1f78aa 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -19737,8 +19737,19 @@
result = CombineHashes(result, static_cast<uint32_t>(type_nullability));
result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash());
if (IsFunctionType()) {
+ AbstractType& type = AbstractType::Handle();
const Function& sig_fun = Function::Handle(signature());
- AbstractType& type = AbstractType::Handle(sig_fun.result_type());
+ const intptr_t num_type_params = sig_fun.NumTypeParameters();
+ if (num_type_params > 0) {
+ const TypeArguments& type_params =
+ TypeArguments::Handle(sig_fun.type_parameters());
+ for (intptr_t i = 0; i < num_type_params; i++) {
+ type = type_params.TypeAt(i);
+ type = TypeParameter::Cast(type).bound();
+ result = CombineHashes(result, type.Hash());
+ }
+ }
+ type = sig_fun.result_type();
result = CombineHashes(result, type.Hash());
result = CombineHashes(result, sig_fun.NumOptionalPositionalParameters());
const intptr_t num_params = sig_fun.NumParameters();
@@ -19754,7 +19765,6 @@
}
// Required flag is not hashed, see comment above.
}
- // TODO(regis): Missing hash of type parameters.
}
result = FinalizeHash(result, kHashBits);
SetHash(result);
@@ -23611,40 +23621,32 @@
// Prints the best representation(s) for the call address.
static void PrintNonSymbolicStackFrameBody(ZoneTextBuffer* buffer,
uword call_addr,
+ uword isolate_dso_base,
uword isolate_instructions,
uword vm_instructions) {
- const word vm_offset = call_addr - vm_instructions;
- const word isolate_offset = call_addr - isolate_instructions;
- // If the VM instructions image was compiled directly to ELF, we can determine
- // the base address of the snapshot shared object from the section start.
- const uword snapshot_base =
- Elf::SnapshotRelocatedBaseAddress(vm_instructions);
+ const Image vm_image(reinterpret_cast<const void*>(vm_instructions));
+ const Image isolate_image(
+ reinterpret_cast<const void*>(isolate_instructions));
- // Pick the closest instructions section start before the call address.
- if (vm_offset > 0 && (isolate_offset < 0 || vm_offset < isolate_offset)) {
- if (snapshot_base != 0) {
- const uword relocated_section = vm_instructions - snapshot_base;
- buffer->Printf(" virt %" Pp "", relocated_section + vm_offset);
- }
- buffer->Printf(" %s+0x%" Px "", kVmSnapshotInstructionsAsmSymbol,
- vm_offset);
- } else if (isolate_offset > 0) {
- if (snapshot_base != 0) {
- const uword relocated_section = isolate_instructions - snapshot_base;
- buffer->Printf(" virt %" Pp "", relocated_section + isolate_offset);
+ if (isolate_image.contains(call_addr)) {
+ if (isolate_image.compiled_to_elf() && isolate_dso_base != 0) {
+ buffer->Printf(" virt %" Pp "", call_addr - isolate_dso_base);
}
buffer->Printf(" %s+0x%" Px "", kIsolateSnapshotInstructionsAsmSymbol,
- isolate_offset);
+ call_addr - isolate_instructions);
+ } else if (vm_image.contains(call_addr)) {
+ // We currently don't print 'virt' entries for vm addresses, even if
+ // they were compiled to ELF, as we should never encounter these in
+ // non-symbolic stack traces (since stub addresses are stripped).
+ //
+ // In case they leak due to code issues elsewhere, we still print them as
+ // <vm symbol>+<offset>, just to distinguish from other cases.
+ buffer->Printf(" %s+0x%" Px "", kVmSnapshotInstructionsAsmSymbol,
+ call_addr - vm_instructions);
} else {
- uword dso_base;
- char* dso_name;
- if (NativeSymbolResolver::LookupSharedObject(call_addr, &dso_base,
- &dso_name)) {
- buffer->Printf(" %s", dso_name);
- NativeSymbolResolver::FreeSymbolName(dso_name);
- } else {
- buffer->Printf(" <unknown>");
- }
+ // This case should never happen, since these are not addresses within the
+ // VM or app isolate instructions sections, so make it easy to notice.
+ buffer->Printf(" <invalid Dart instruction address>");
}
buffer->Printf("\n");
}
@@ -23719,6 +23721,38 @@
T->isolate_group()->source()->snapshot_instructions);
auto const vm_instructions = reinterpret_cast<uword>(
Dart::vm_isolate()->group()->source()->snapshot_instructions);
+ uword isolate_dso_base;
+ if (!NativeSymbolResolver::LookupSharedObject(isolate_instructions,
+ &isolate_dso_base, nullptr)) {
+ // This isn't a natively loaded snapshot, so try to detect non-natively
+ // loaded compiled-to-ELF snapshots.
+ const Image vm_image(reinterpret_cast<const void*>(vm_instructions));
+ const Image isolate_image(
+ reinterpret_cast<const void*>(isolate_instructions));
+
+ if (vm_image.compiled_to_elf() && isolate_image.compiled_to_elf()) {
+ // If the VM and isolate were loaded from the same snapshot, then the
+ // isolate instructions will immediately follow the VM instructions in
+ // memory, and the VM section is always at a fixed offset from the DSO
+ // base in snapshots we generate.
+ const uword next_section_after_vm =
+ Utils::RoundUp(reinterpret_cast<uword>(vm_image.object_start()) +
+ vm_image.object_size(),
+ Elf::kPageSize);
+ if (isolate_instructions == next_section_after_vm) {
+ isolate_dso_base = Elf::SnapshotRelocatedBaseAddress(vm_instructions);
+ }
+ // If not, then we have no way of reverse-engineering the DSO base for
+ // the isolate without extending the embedder to return this information
+ // or encoding it somehow in the instructions image like the BSS offset.
+ //
+ // For the latter, the Image header size must match the HeapPage header
+ // size, and there's no remaining unused space in the Image header on
+ // 64-bit architectures. Thus, we'd have to increase the header size of
+ // both HeapPage and Image or create a special Object to put in the body
+ // of the Image to store extended header information.
+ }
+ }
if (FLAG_dwarf_stack_traces_mode) {
// The Dart standard requires the output of StackTrace.toString to include
// all pending activations with precise source locations (i.e., to expand
@@ -23734,7 +23768,14 @@
buffer.Printf("pid: %" Pd ", tid: %" Pd ", name %s\n", OS::ProcessId(),
OSThread::ThreadIdToIntPtr(thread->id()), thread->name());
buffer.Printf("isolate_instructions: %" Px "", isolate_instructions);
- buffer.Printf(" vm_instructions: %" Px "\n", vm_instructions);
+ buffer.Printf(" vm_instructions: %" Px "", vm_instructions);
+ // Print the dso_base of the isolate_instructions, since printed stack
+ // traces won't include stub frames. If VM isolates ever start including
+ // Dart code, adjust this appropriately.
+ if (isolate_dso_base != 0) {
+ buffer.Printf(" isolate_dso_base: %" Px "", isolate_dso_base);
+ }
+ buffer.Printf("\n");
}
#endif
@@ -23787,8 +23828,9 @@
// This output is formatted like Android's debuggerd. Note debuggerd
// prints call addresses instead of return addresses.
buffer.Printf(" #%02" Pd " abs %" Pp "", frame_index, call_addr);
- PrintNonSymbolicStackFrameBody(
- &buffer, call_addr, isolate_instructions, vm_instructions);
+ PrintNonSymbolicStackFrameBody(&buffer, call_addr, isolate_dso_base,
+ isolate_instructions,
+ vm_instructions);
frame_index++;
continue;
} else if (function.IsNull()) {
@@ -23796,8 +23838,9 @@
// retained, so instead print the static symbol + offset like the
// non-symbolic stack traces.
PrintSymbolicStackFrameIndex(&buffer, frame_index);
- PrintNonSymbolicStackFrameBody(
- &buffer, call_addr, isolate_instructions, vm_instructions);
+ PrintNonSymbolicStackFrameBody(&buffer, call_addr, isolate_dso_base,
+ isolate_instructions,
+ vm_instructions);
frame_index++;
continue;
}
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 717ff52..510ad0a 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -269,12 +269,12 @@
};
void ObjectGraph::IterateObjectsFrom(intptr_t class_id,
+ HeapIterationScope* iteration,
ObjectGraph::Visitor* visitor) {
- HeapIterationScope iteration(thread());
Stack stack(isolate_group());
InstanceAccumulator accumulator(&stack, class_id);
- iteration.IterateObjectsNoImagePages(&accumulator);
+ iteration->IterateObjectsNoImagePages(&accumulator);
stack.TraverseGraph(visitor);
}
@@ -349,7 +349,7 @@
intptr_t ObjectGraph::SizeReachableByClass(intptr_t class_id) {
HeapIterationScope iteration_scope(Thread::Current(), true);
SizeVisitor total;
- IterateObjectsFrom(class_id, &total);
+ IterateObjectsFrom(class_id, &iteration_scope, &total);
return total.size();
}
diff --git a/runtime/vm/object_graph.h b/runtime/vm/object_graph.h
index 9ce858e..175e084 100644
--- a/runtime/vm/object_graph.h
+++ b/runtime/vm/object_graph.h
@@ -82,7 +82,9 @@
// Like 'IterateObjects', but restricted to objects reachable from 'root'
// (including 'root' itself).
void IterateObjectsFrom(const Object& root, Visitor* visitor);
- void IterateObjectsFrom(intptr_t class_id, Visitor* visitor);
+ void IterateObjectsFrom(intptr_t class_id,
+ HeapIterationScope* iteration,
+ Visitor* visitor);
// The number of bytes retained by 'obj'.
intptr_t SizeRetainedByInstance(const Object& obj);
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 0e49850..3731cb53 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -325,14 +325,14 @@
}
DEFINE_LEAF_RUNTIME_ENTRY(uword /*ObjectPtr*/,
- AddAllocatedObjectToRememberedSet,
+ EnsureRememberedAndMarkingDeferred,
2,
uword /*ObjectPtr*/ object_in,
Thread* thread) {
ObjectPtr object = static_cast<ObjectPtr>(object_in);
- // The allocation stubs in will call this leaf method for newly allocated
+ // The allocation stubs will call this leaf method for newly allocated
// old space objects.
- RELEASE_ASSERT(object->IsOldObject() && !object->ptr()->IsRemembered());
+ RELEASE_ASSERT(object->IsOldObject());
// If we eliminate a generational write barriers on allocations of an object
// we need to ensure it's either a new-space object or it has been added to
@@ -344,7 +344,13 @@
// outermost runtime code (to which the genenerated Dart code might not return
// in a long time).
bool add_to_remembered_set = true;
- if (object->IsArray()) {
+ if (object->ptr()->IsRemembered()) {
+ // Objects must not be added to the remembered set twice because the
+ // scavenger's visitor is not idempotent.
+ // Might already be remembered because of type argument store in
+ // AllocateArray or any field in CloneContext.
+ add_to_remembered_set = false;
+ } else if (object->IsArray()) {
const intptr_t length = Array::LengthOf(static_cast<ArrayPtr>(object));
add_to_remembered_set =
compiler::target::WillAllocateNewOrRememberedArray(length);
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index de86028..b84e6c4 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -68,7 +68,7 @@
V(void, StoreBufferBlockProcess, Thread*) \
V(void, MarkingStackBlockProcess, Thread*) \
V(void, RememberCard, uword /*ObjectPtr*/, ObjectPtr*) \
- V(uword /*ObjectPtr*/, AddAllocatedObjectToRememberedSet, \
+ V(uword /*ObjectPtr*/, EnsureRememberedAndMarkingDeferred, \
uword /*ObjectPtr*/ object, Thread* thread) \
V(double, LibcPow, double, double) \
V(double, DartModulo, double, double) \
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index bf947f5..93d7f36 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3080,9 +3080,11 @@
ZoneGrowableHandlePtrArray<Object> storage(thread->zone(), limit);
GetInstancesVisitor visitor(cls, &storage, limit);
- ObjectGraph graph(thread);
- HeapIterationScope iteration_scope(Thread::Current(), true);
- graph.IterateObjects(&visitor);
+ {
+ ObjectGraph graph(thread);
+ HeapIterationScope iteration_scope(Thread::Current(), true);
+ graph.IterateObjects(&visitor);
+ }
intptr_t count = visitor.count();
JSONObject jsobj(js);
jsobj.AddProperty("type", "InstanceSet");
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index 04339dd..200816c 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -7,6 +7,7 @@
#include "platform/unicode.h"
#include "vm/handles.h"
#include "vm/hash_table.h"
+#include "vm/heap/safepoint.h"
#include "vm/isolate.h"
#include "vm/object.h"
#include "vm/object_store.h"
@@ -581,29 +582,65 @@
if (symbol.IsNull()) {
IsolateGroup* group = thread->isolate_group();
Isolate* isolate = thread->isolate();
- // in JIT object_store lives on isolate, not on isolate group.
+ // In JIT object_store lives on isolate, not on isolate group.
ObjectStore* object_store = group->object_store() == nullptr
? isolate->object_store()
: group->object_store();
- // in AOT no need to worry about background compiler, only about
- // other mutators.
-#if defined(DART_PRECOMPILED_RUNTIME)
- group->RunWithStoppedMutators(
- [&]() {
-#else
- SafepointRwLock* symbols_lock = group->object_store() == nullptr
- ? isolate->symbols_lock()
- : group->symbols_lock();
- SafepointWriteRwLocker sl(thread, symbols_lock);
-#endif
+ if (thread->IsAtSafepoint()) {
+ // There are two cases where we can cause symbol allocation while holding
+ // a safepoint:
+ // - FLAG_enable_isolate_groups in AOT due to the usage of
+ // `RunWithStoppedMutators` in SwitchableCall runtime entry.
+ // - non-PRODUCT mode where the vm-service uses a HeapIterationScope
+ // while building instances
+ // Ideally we should get rid of both cases to avoid this unsafe usage of
+ // the symbol table (we are assuming here that no other thread holds the
+ // symbols_lock).
+ // TODO(https://dartbug.com/41943): Get rid of the symbol table accesses
+ // within safepoint operation scope.
+ RELEASE_ASSERT(group->safepoint_handler()->IsOwnedByTheThread(thread));
+ RELEASE_ASSERT(FLAG_enable_isolate_groups || !USING_PRODUCT);
+
+ // Uncommon case: We are at a safepoint, all mutators are stopped and we
+ // have therefore exclusive access to the symbol table.
+ data = object_store->symbol_table();
+ SymbolTable table(&key, &value, &data);
+ symbol ^= table.InsertNewOrGet(str);
+ object_store->set_symbol_table(table.Release());
+ } else {
+ // Most common case: We are not at a safepoint and the symbol is available
+ // in the symbol table: We require only read access.
+ {
+ SafepointReadRwLocker sl(thread, group->symbols_lock());
+ data = object_store->symbol_table();
+ SymbolTable table(&key, &value, &data);
+ symbol ^= table.GetOrNull(str);
+ table.Release();
+ }
+ // Second common case: We are not at a safepoint and the symbol is not
+ // available in the symbol table: We require only exclusive access.
+ if (symbol.IsNull()) {
+ auto insert_or_get = [&]() {
data = object_store->symbol_table();
SymbolTable table(&key, &value, &data);
symbol ^= table.InsertNewOrGet(str);
object_store->set_symbol_table(table.Release());
-#if defined(DART_PRECOMPILED_RUNTIME)
- },
- /*use_force_growth=*/true);
-#endif
+ };
+
+ SafepointWriteRwLocker sl(thread, group->symbols_lock());
+ if (FLAG_enable_isolate_groups || !USING_PRODUCT) {
+ // NOTE: Strictly speaking we should use a safepoint operation scope
+ // here to ensure the lock-free usage inside safepoint operations (see
+ // above) is safe. Though this would really kill the performance.
+ // TODO(https://dartbug.com/41943): Get rid of the symbol table
+ // accesses within safepoint operation scope.
+ group->RunWithStoppedMutators(insert_or_get,
+ /*force_heap_growth=*/true);
+ } else {
+ insert_or_get();
+ }
+ }
+ }
}
ASSERT(symbol.IsSymbol());
ASSERT(symbol.HasHash());
@@ -629,22 +666,30 @@
if (symbol.IsNull()) {
IsolateGroup* group = thread->isolate_group();
Isolate* isolate = thread->isolate();
- // in JIT object_store lives on isolate, not on isolate group.
+ // In JIT object_store lives on isolate, not on isolate group.
ObjectStore* object_store = group->object_store() == nullptr
? isolate->object_store()
: group->object_store();
- // in AOT no need to worry about background compiler, only about
- // other mutators.
-#if !defined(DART_PRECOMPILED_RUNTIME)
- SafepointRwLock* symbols_lock = group->object_store() == nullptr
- ? isolate->symbols_lock()
- : group->symbols_lock();
- SafepointReadRwLocker sl(thread, symbols_lock);
+ // See `Symbols::NewSymbol` for more information why we separate the two
+ // cases.
+ if (thread->IsAtSafepoint()) {
+ RELEASE_ASSERT(group->safepoint_handler()->IsOwnedByTheThread(thread));
+ // In DEBUG mode the snapshot writer also calls this method inside a
+ // safepoint.
+#if !defined(DEBUG)
+ RELEASE_ASSERT(FLAG_enable_isolate_groups || !USING_PRODUCT);
#endif
- data = object_store->symbol_table();
- SymbolTable table(&key, &value, &data);
- symbol ^= table.GetOrNull(str);
- table.Release();
+ data = object_store->symbol_table();
+ SymbolTable table(&key, &value, &data);
+ symbol ^= table.GetOrNull(str);
+ table.Release();
+ } else {
+ SafepointReadRwLocker sl(thread, group->symbols_lock());
+ data = object_store->symbol_table();
+ SymbolTable table(&key, &value, &data);
+ symbol ^= table.GetOrNull(str);
+ table.Release();
+ }
}
ASSERT(symbol.IsNull() || symbol.IsSymbol());
ASSERT(symbol.IsNull() || symbol.HasHash());
diff --git a/sdk/lib/_http/http_headers.dart b/sdk/lib/_http/http_headers.dart
index 23cd58e..ad887b9 100644
--- a/sdk/lib/_http/http_headers.dart
+++ b/sdk/lib/_http/http_headers.dart
@@ -137,6 +137,7 @@
void set persistentConnection(bool persistentConnection) {
_checkMutable();
if (persistentConnection == _persistentConnection) return;
+ final originalName = _originalHeaderName(HttpHeaders.connectionHeader);
if (persistentConnection) {
if (protocolVersion == "1.1") {
remove(HttpHeaders.connectionHeader, "close");
@@ -146,11 +147,11 @@
"Trying to set 'Connection: Keep-Alive' on HTTP 1.0 headers with "
"no ContentLength");
}
- add(HttpHeaders.connectionHeader, "keep-alive");
+ add(originalName, "keep-alive", preserveHeaderCase: true);
}
} else {
if (protocolVersion == "1.1") {
- add(HttpHeaders.connectionHeader, "close");
+ add(originalName, "close", preserveHeaderCase: true);
} else {
remove(HttpHeaders.connectionHeader, "keep-alive");
}
@@ -489,10 +490,10 @@
}
void _build(BytesBuilder builder) {
- for (String name in _headers.keys) {
- List<String> values = _headers[name];
+ _headers.forEach((String name, List<String> values) {
+ String originalName = _originalHeaderName(name);
bool fold = _foldHeader(name);
- var nameData = name.codeUnits;
+ var nameData = originalName.codeUnits;
builder.add(nameData);
builder.addByte(_CharCode.COLON);
builder.addByte(_CharCode.SP);
@@ -513,7 +514,7 @@
}
builder.addByte(_CharCode.CR);
builder.addByte(_CharCode.LF);
- }
+ });
}
String toString() {
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 81e60db..c07240b 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -2081,6 +2081,7 @@
if (connectionTimeout != null) {
socketFuture = socketFuture.timeout(connectionTimeout, onTimeout: () {
_socketTasks.remove(task);
+ _connecting--;
task.cancel();
return null;
});
@@ -2123,6 +2124,9 @@
_checkPending();
throw error;
});
+ }, onError: (error) {
+ _connecting--;
+ throw error;
});
}
}
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index c1235fd..48d54ad 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -7,6 +7,10 @@
/// This library defines the representation of runtime types.
part of dart._runtime;
+_throwNullSafetyWarningError() => throw UnsupportedError(
+ 'Null safety errors cannot be shown as warnings when running with sound '
+ 'null safety.');
+
@notNull
bool _setNullSafety = false;
@@ -17,15 +21,32 @@
///
/// Changing the mode after the application has started running is not
/// supported.
-void nullSafety(bool flag) {
+void nullSafety(bool soundNullSafety) {
if (_setNullSafety) {
throw UnsupportedError('The Null Safety mode can only be set once.');
}
- strictNullSafety = flag;
+ if (soundNullSafety && _weakNullSafetyWarnings)
+ _throwNullSafetyWarningError();
+
+ strictNullSafety = soundNullSafety;
_setNullSafety = true;
}
+@notNull
+bool _weakNullSafetyWarnings = false;
+
+/// Sets the runtime mode to show warnings when running with weak null safety.
+///
+/// These are warnings for issues that will become errors when sound null safety
+/// is enabled. Showing warnings while running with sound null safety is not
+/// supported (they will be errors).
+void weakNullSafetyWarnings(bool showWarnings) {
+ if (showWarnings && strictNullSafety) _throwNullSafetyWarningError();
+
+ _weakNullSafetyWarnings = showWarnings;
+}
+
final metadata = JS('', 'Symbol("metadata")');
/// Types in dart are represented internally at runtime as follows.
@@ -221,8 +242,10 @@
}
void _nullWarn(arg) {
- _warn('$arg\n'
- 'This will become a failure when runtime null safety is enabled.');
+ if (_weakNullSafetyWarnings) {
+ _warn('$arg\n'
+ 'This will become a failure when runtime null safety is enabled.');
+ }
}
/// Tracks objects that have been compared against null (i.e., null is Type).
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index d89eded..1a13a7a 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -21,7 +21,7 @@
LEGACY_TYPE_REF;
import 'dart:_interceptors'
- show JavaScriptFunction, JSArray, JSUnmodifiableArray;
+ show JavaScriptFunction, JSArray, JSNull, JSUnmodifiableArray;
import 'dart:_js_names' show unmangleGlobalNameIfPreservedAnyways;
@@ -870,9 +870,7 @@
// 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);
- }
+ if (object == null) return _nullIs(testRti);
Rti objectRti = instanceOrFunctionType(object, testRti);
return isSubtype(_theUniverse(), objectRti, testRti);
}
@@ -882,9 +880,7 @@
// 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);
- }
+ if (object == null) return _nullIs(testRti);
var tag = Rti._getSpecializedTestResource(testRti);
// This test is redundant with getInterceptor below, but getInterceptor does
@@ -905,9 +901,7 @@
Rti testRti = _castToRti(JS('', 'this'));
if (object == null) {
if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object;
- } else {
- if (Rti._isCheck(testRti, object)) return object;
- }
+ } else if (Rti._isCheck(testRti, object)) return object;
Rti objectRti = instanceOrFunctionType(object, testRti);
String message =
@@ -2902,7 +2896,9 @@
bool isNullableObjectType(Rti t) =>
Rti._getKind(t) == Rti.kindQuestion &&
isObjectType(Rti._getQuestionArgument(t));
-bool isNullType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Null>());
+bool isNullType(Rti t) =>
+ _Utils.isIdentical(t, TYPE_REF<Null>()) ||
+ _Utils.isIdentical(t, TYPE_REF<JSNull>());
bool isFunctionType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Function>());
bool isJsFunctionType(Rti t) =>
_Utils.isIdentical(t, TYPE_REF<JavaScriptFunction>());
diff --git a/sdk/lib/_internal/vm/lib/core_patch.dart b/sdk/lib/_internal/vm/lib/core_patch.dart
index 65d9845..d9e9e36 100644
--- a/sdk/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk/lib/_internal/vm/lib/core_patch.dart
@@ -124,42 +124,71 @@
_SyncGeneratorCallback<T> _moveNextFn;
Iterator<T> _yieldEachIterator;
+ // Stack of suspended _moveNextFn, if any.
+ List<_SyncGeneratorCallback<T>> _stack;
+
// These two fields are set by generated code for the yield and yield*
// statement.
T _current;
Iterable<T> _yieldEachIterable;
+ @override
T get current =>
_yieldEachIterator != null ? _yieldEachIterator.current : _current;
_SyncIterator(this._moveNextFn);
+ @override
bool moveNext() {
if (_moveNextFn == null) {
return false;
}
+
while (true) {
- if (_yieldEachIterator != null) {
- if (_yieldEachIterator.moveNext()) {
+ // If the active iterator isn't a nested _SyncIterator, we have to
+ // delegate downwards from the immediate iterator.
+ final iterator = _yieldEachIterator;
+ if (iterator != null) {
+ if (iterator.moveNext()) {
return true;
}
_yieldEachIterator = null;
}
- // _moveNextFn() will update the values of _yieldEachIterable
- // and _current.
+
+ final stack = _stack;
if (!_moveNextFn(this)) {
_moveNextFn = null;
_current = null;
+ // If we have any suspended parent generators, continue next one up:
+ if (stack != null && stack.isNotEmpty) {
+ _moveNextFn = stack.removeLast();
+ continue;
+ }
return false;
}
- if (_yieldEachIterable != null) {
- // Spec mandates: it is a dynamic error if the class of [the object
- // returned by yield*] does not implement Iterable.
- _yieldEachIterator = _yieldEachIterable.iterator;
+
+ final iterable = _yieldEachIterable;
+ if (iterable != null) {
+ if (iterable is _SyncIterable) {
+ // We got a recursive yield* of sync* function. Instead of creating
+ // a new iterator we replace our _moveNextFn (remembering the
+ // current _moveNextFn for later resumption).
+ if (stack == null) {
+ _stack = [];
+ }
+ _stack.add(_moveNextFn);
+ final typedIterable = unsafeCast<_SyncIterable<T>>(iterable);
+ _moveNextFn = typedIterable._moveNextFnMaker();
+ } else {
+ _yieldEachIterator = iterable.iterator;
+ }
_yieldEachIterable = null;
_current = null;
+
+ // Fetch the next item.
continue;
}
+
return true;
}
}
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index 074cb11..c895e04 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -166,3 +166,9 @@
String packageConfig,
bool newIsolateGroup,
String debugName) native "Isolate_spawnFunction";
+
+// Collection of functions which should only be used for testing purposes.
+abstract class VMInternalsForTesting {
+ // This function can be used by tests to enforce garbage collection.
+ static void collectAllGarbage() native "Internal_collectAllGarbage";
+}
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 2a1e198..c19bb37 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -84,6 +84,9 @@
///
/// If [start] and [end] are provided, only the substring
/// `string.substring(start, end)` is converted.
+ ///
+ /// Any unpaired surrogate character (`U+D800`-`U+DFFF`) in the input string
+ /// is encoded as a Unicode Replacement character `U+FFFD` (�).
Uint8List convert(String string, [int start = 0, int end]) {
var stringLength = string.length;
end = RangeError.checkValidRange(start, end, stringLength);
@@ -100,10 +103,8 @@
// Force encoding of the lead surrogate by itself.
var lastCodeUnit = string.codeUnitAt(end - 1);
assert(_isLeadSurrogate(lastCodeUnit));
- // We use a non-surrogate as `nextUnit` so that _writeSurrogate just
- // writes the lead-surrogate.
- var wasCombined = encoder._writeSurrogate(lastCodeUnit, 0);
- assert(!wasCombined);
+ // Write a replacement character to represent the unpaired surrogate.
+ encoder._writeReplacementCharacter();
}
return encoder._buffer.sublist(0, encoder._bufferIndex);
}
@@ -264,11 +265,9 @@
var isLastSlice = isLast && (start == end);
if (start == end - 1 && _isLeadSurrogate(str.codeUnitAt(start))) {
if (isLast && _bufferIndex < _buffer.length - 3) {
- // There is still space for the last incomplete surrogate.
- // We use a non-surrogate as second argument. This way the
- // function will just add the surrogate-half to the buffer.
- var hasBeenCombined = _writeSurrogate(str.codeUnitAt(start), 0);
- assert(!hasBeenCombined);
+ // There is still space for the replacement character to represent
+ // the last incomplete surrogate.
+ _writeReplacementCharacter();
} else {
// Otherwise store it in the carry. If isLast is true, then
// close will flush the last carry.
@@ -494,6 +493,7 @@
static const int errorSurrogate = E6;
static const int errorUnfinished = E7;
+ @pragma("vm:prefer-inline")
static bool isErrorState(int state) => (state & 1) != 0;
static String errorDescription(int state) {
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 02c46ab..10599a9 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -22682,7 +22682,7 @@
options_dict = convertDartToNative_Dictionary(options);
}
return promiseToFuture(
- JS("", "#.requestMidiAccess(#)", this, options_dict));
+ JS("", "#.requestMIDIAccess(#)", this, options_dict));
}
Future requestMediaKeySystemAccess(
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 6c737f2e..eea4e55 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -1080,7 +1080,7 @@
@JSName('suspend')
Future suspendFor(num suspendTime) =>
- promiseToFuture(JS("", "#.suspendFor(#)", this, suspendTime));
+ promiseToFuture(JS("", "#.suspend(#)", this, suspendTime));
}
// 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
diff --git a/sdk_nnbd/lib/_http/http_headers.dart b/sdk_nnbd/lib/_http/http_headers.dart
index 98ddbf5..ae8b482 100644
--- a/sdk_nnbd/lib/_http/http_headers.dart
+++ b/sdk_nnbd/lib/_http/http_headers.dart
@@ -130,6 +130,7 @@
void set persistentConnection(bool persistentConnection) {
_checkMutable();
if (persistentConnection == _persistentConnection) return;
+ final originalName = _originalHeaderName(HttpHeaders.connectionHeader);
if (persistentConnection) {
if (protocolVersion == "1.1") {
remove(HttpHeaders.connectionHeader, "close");
@@ -139,11 +140,11 @@
"Trying to set 'Connection: Keep-Alive' on HTTP 1.0 headers with "
"no ContentLength");
}
- add(HttpHeaders.connectionHeader, "keep-alive");
+ add(originalName, "keep-alive", preserveHeaderCase: true);
}
} else {
if (protocolVersion == "1.1") {
- add(HttpHeaders.connectionHeader, "close");
+ add(originalName, "close", preserveHeaderCase: true);
} else {
remove(HttpHeaders.connectionHeader, "keep-alive");
}
@@ -500,9 +501,10 @@
}
void _build(BytesBuilder builder) {
- _headers.forEach((name, values) {
+ _headers.forEach((String name, List<String> values) {
+ String originalName = _originalHeaderName(name);
bool fold = _foldHeader(name);
- var nameData = name.codeUnits;
+ var nameData = originalName.codeUnits;
builder.add(nameData);
builder.addByte(_CharCode.COLON);
builder.addByte(_CharCode.SP);
diff --git a/sdk_nnbd/lib/_http/http_impl.dart b/sdk_nnbd/lib/_http/http_impl.dart
index cc5e99a..f949b53 100644
--- a/sdk_nnbd/lib/_http/http_impl.dart
+++ b/sdk_nnbd/lib/_http/http_impl.dart
@@ -2080,6 +2080,7 @@
if (connectionTimeout != null) {
socketFuture = socketFuture.timeout(connectionTimeout, onTimeout: () {
_socketTasks.remove(task);
+ _connecting--;
task.cancel();
return null;
});
@@ -2122,6 +2123,9 @@
_checkPending();
throw error;
});
+ }, onError: (error) {
+ _connecting--;
+ throw error;
});
}
}
diff --git a/sdk_nnbd/lib/_internal/allowed_experiments.json b/sdk_nnbd/lib/_internal/allowed_experiments.json
new file mode 100644
index 0000000..01da114
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/allowed_experiments.json
@@ -0,0 +1,21 @@
+{
+ "version": 1,
+ "experimentSets": {
+ "nullSafety": ["non-nullable"]
+ },
+ "sdk": {
+ "default": {
+ "experimentSet": "nullSafety"
+ },
+ "_example_libraries": {
+ "ui": {
+ "experimentSet": "nullSafety"
+ }
+ }
+ },
+ "_example_packages": {
+ "collection": {
+ "experimentSet": "nullSafety"
+ }
+ }
+}
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 b985e78..41cc31d 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,10 @@
/// This library defines the representation of runtime types.
part of dart._runtime;
+_throwNullSafetyWarningError() => throw UnsupportedError(
+ 'Null safety errors cannot be shown as warnings when running with sound '
+ 'null safety.');
+
@notNull
bool _setNullSafety = false;
@@ -15,15 +19,32 @@
///
/// Changing the mode after the application has started running is not
/// supported.
-void nullSafety(bool flag) {
+void nullSafety(bool soundNullSafety) {
if (_setNullSafety) {
throw UnsupportedError('The Null Safety mode can only be set once.');
}
- strictNullSafety = flag;
+ if (soundNullSafety && _weakNullSafetyWarnings)
+ _throwNullSafetyWarningError();
+
+ strictNullSafety = soundNullSafety;
_setNullSafety = true;
}
+@notNull
+bool _weakNullSafetyWarnings = false;
+
+/// Sets the runtime mode to show warnings when running with weak null safety.
+///
+/// These are warnings for issues that will become errors when sound null safety
+/// is enabled. Showing warnings while running with sound null safety is not
+/// supported (they will be errors).
+void weakNullSafetyWarnings(bool showWarnings) {
+ if (showWarnings && strictNullSafety) _throwNullSafetyWarningError();
+
+ _weakNullSafetyWarnings = showWarnings;
+}
+
final metadata = JS('', 'Symbol("metadata")');
/// Types in dart are represented internally at runtime as follows.
@@ -219,8 +240,10 @@
}
void _nullWarn(arg) {
- _warn('$arg\n'
- 'This will become a failure when runtime null safety is enabled.');
+ if (_weakNullSafetyWarnings) {
+ _warn('$arg\n'
+ 'This will become a failure when runtime null safety is enabled.');
+ }
}
/// Tracks objects that have been compared against null (i.e., null is Type).
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
index 9d0eef4..77dfe84 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -20,7 +20,7 @@
LEGACY_TYPE_REF;
import 'dart:_interceptors'
- show JavaScriptFunction, JSArray, JSUnmodifiableArray;
+ show JavaScriptFunction, JSArray, JSNull, JSUnmodifiableArray;
import 'dart:_js_names' show unmangleGlobalNameIfPreservedAnyways;
@@ -933,9 +933,7 @@
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _Utils.asRti(JS('', 'this'));
- if (JS_GET_FLAG('NNBD') && object == null) {
- return _nullIs(testRti);
- }
+ if (object == null) return _nullIs(testRti);
Rti objectRti = instanceOrFunctionType(object, testRti);
return isSubtype(_theUniverse(), objectRti, testRti);
}
@@ -960,9 +958,7 @@
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _Utils.asRti(JS('', 'this'));
- if (JS_GET_FLAG('NNBD') && object == null) {
- return _nullIs(testRti);
- }
+ if (object == null) return _nullIs(testRti);
var tag = Rti._getSpecializedTestResource(testRti);
// This test is redundant with getInterceptor below, but getInterceptor does
@@ -984,9 +980,7 @@
Rti testRti = _Utils.asRti(JS('', 'this'));
if (object == null) {
if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) return object;
- } else {
- if (Rti._isCheck(testRti, object)) return object;
- }
+ } else if (Rti._isCheck(testRti, object)) return object;
_failedAsCheck(object, testRti);
}
@@ -996,8 +990,9 @@
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _Utils.asRti(JS('', 'this'));
- if (object == null) return object;
- if (Rti._isCheck(testRti, object)) return object;
+ if (object == null) {
+ return object;
+ } else if (Rti._isCheck(testRti, object)) return object;
_failedAsCheck(object, testRti);
}
@@ -3038,7 +3033,9 @@
bool isLegacyObjectType(Rti t) =>
_Utils.isIdentical(t, LEGACY_TYPE_REF<Object>());
bool isNullableObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Object?>());
-bool isNullType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Null>());
+bool isNullType(Rti t) =>
+ _Utils.isIdentical(t, TYPE_REF<Null>()) ||
+ _Utils.isIdentical(t, TYPE_REF<JSNull>());
bool isFunctionType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Function>());
bool isJsFunctionType(Rti t) =>
_Utils.isIdentical(t, TYPE_REF<JavaScriptFunction>());
diff --git a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
index 4db4231..396ad6b 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
@@ -122,11 +122,15 @@
_SyncGeneratorCallback<T>? _moveNextFn;
Iterator<T>? _yieldEachIterator;
+ // Stack of suspended _moveNextFn.
+ List<_SyncGeneratorCallback<T>>? _stack;
+
// These two fields are set by generated code for the yield and yield*
// statement.
T? _current;
Iterable<T>? _yieldEachIterable;
+ @override
T get current {
final iterator = _yieldEachIterator;
if (iterator != null) {
@@ -139,11 +143,15 @@
_SyncIterator(this._moveNextFn);
+ @override
bool moveNext() {
if (_moveNextFn == null) {
return false;
}
+
while (true) {
+ // If the active iterator isn't a nested _SyncIterator, we have to
+ // delegate downwards from the immediate iterator.
final iterator = _yieldEachIterator;
if (iterator != null) {
if (iterator.moveNext()) {
@@ -151,22 +159,41 @@
}
_yieldEachIterator = null;
}
- // _moveNextFn() will update the values of _yieldEachIterable
- // and _current.
- if (!_moveNextFn!(this)) {
+
+ final stack = _stack;
+ if (!_moveNextFn!.call(this)) {
_moveNextFn = null;
_current = null;
+ // If we have any suspended parent generators, continue next one up:
+ if (stack != null && stack.isNotEmpty) {
+ _moveNextFn = stack.removeLast();
+ continue;
+ }
return false;
}
- final yieldEachIterable = _yieldEachIterable;
- if (yieldEachIterable != null) {
- // Spec mandates: it is a dynamic error if the class of [the object
- // returned by yield*] does not implement Iterable.
- _yieldEachIterator = yieldEachIterable.iterator;
+
+ final iterable = _yieldEachIterable;
+ if (iterable != null) {
+ if (iterable is _SyncIterable) {
+ // We got a recursive yield* of sync* function. Instead of creating
+ // a new iterator we replace our _moveNextFn (remembering the
+ // current _moveNextFn for later resumption).
+ if (stack == null) {
+ _stack = [];
+ }
+ _stack!.add(_moveNextFn!);
+ final typedIterable = unsafeCast<_SyncIterable<T>>(iterable);
+ _moveNextFn = typedIterable._moveNextFnMaker();
+ } else {
+ _yieldEachIterator = iterable.iterator;
+ }
_yieldEachIterable = null;
_current = null;
+
+ // Fetch the next item.
continue;
}
+
return true;
}
}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
index a4cc093..8382618 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
@@ -170,3 +170,9 @@
String? packageConfig,
bool newIsolateGroup,
String? debugName) native "Isolate_spawnFunction";
+
+// Collection of functions which should only be used for testing purposes.
+abstract class VMInternalsForTesting {
+ // This function can be used by tests to enforce garbage collection.
+ static void collectAllGarbage() native "Internal_collectAllGarbage";
+}
diff --git a/sdk_nnbd/lib/convert/utf.dart b/sdk_nnbd/lib/convert/utf.dart
index 1743510..c74f918 100644
--- a/sdk_nnbd/lib/convert/utf.dart
+++ b/sdk_nnbd/lib/convert/utf.dart
@@ -81,6 +81,9 @@
///
/// If [start] and [end] are provided, only the substring
/// `string.substring(start, end)` is converted.
+ ///
+ /// Any unpaired surrogate character (`U+D800`-`U+DFFF`) in the input string
+ /// is encoded as a Unicode Replacement character `U+FFFD` (�).
Uint8List convert(String string, [int start = 0, int? end]) {
var stringLength = string.length;
end = RangeError.checkValidRange(start, end, stringLength);
@@ -101,10 +104,8 @@
// Force encoding of the lead surrogate by itself.
var lastCodeUnit = string.codeUnitAt(end - 1);
assert(_isLeadSurrogate(lastCodeUnit));
- // We use a non-surrogate as `nextUnit` so that _writeSurrogate just
- // writes the lead-surrogate.
- var wasCombined = encoder._writeSurrogate(lastCodeUnit, 0);
- assert(!wasCombined);
+ // Write a replacement character to represent the unpaired surrogate.
+ encoder._writeReplacementCharacter();
}
return encoder._buffer.sublist(0, encoder._bufferIndex);
}
@@ -265,11 +266,9 @@
var isLastSlice = isLast && (start == end);
if (start == end - 1 && _isLeadSurrogate(str.codeUnitAt(start))) {
if (isLast && _bufferIndex < _buffer.length - 3) {
- // There is still space for the last incomplete surrogate.
- // We use a non-surrogate as second argument. This way the
- // function will just add the surrogate-half to the buffer.
- var hasBeenCombined = _writeSurrogate(str.codeUnitAt(start), 0);
- assert(!hasBeenCombined);
+ // There is still space for the replacement character to represent
+ // the last incomplete surrogate.
+ _writeReplacementCharacter();
} else {
// Otherwise store it in the carry. If isLast is true, then
// close will flush the last carry.
@@ -495,6 +494,7 @@
static const int errorSurrogate = E6;
static const int errorUnfinished = E7;
+ @pragma("vm:prefer-inline")
static bool isErrorState(int state) => (state & 1) != 0;
static String errorDescription(int state) {
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
index 3f9da79..d84d8f6 100644
--- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -22721,7 +22721,7 @@
options_dict = convertDartToNative_Dictionary(options);
}
return promiseToFuture(
- JS("", "#.requestMidiAccess(#)", this, options_dict));
+ JS("", "#.requestMIDIAccess(#)", this, options_dict));
}
Future requestMediaKeySystemAccess(
diff --git a/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart
index a0d7b1e..146e158 100644
--- a/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -1080,7 +1080,7 @@
@JSName('suspend')
Future suspendFor(num suspendTime) =>
- promiseToFuture(JS("", "#.suspendFor(#)", this, suspendTime));
+ promiseToFuture(JS("", "#.suspend(#)", this, suspendTime));
}
// 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
diff --git a/tests/compiler/dartdevc_native/hot_restart_late_test.dart b/tests/compiler/dartdevc_native/hot_restart_late_test.dart
index 1908f6d..ab37cbc 100644
--- a/tests/compiler/dartdevc_native/hot_restart_late_test.dart
+++ b/tests/compiler/dartdevc_native/hot_restart_late_test.dart
@@ -9,25 +9,32 @@
import 'package:expect/expect.dart';
import 'dart:_runtime' as dart;
+late double l;
+
class Lates {
- late String s;
+ static late String s;
}
main() {
- var l = Lates();
-
- Expect.throws(() => l.s);
- l.s = "set";
- Expect.equals(l.s, "set");
+ Expect.throws(() => Lates.s);
+ Expect.throws(() => l);
+ Lates.s = "set";
+ l = 1.62;
+ Expect.equals(Lates.s, "set");
+ Expect.equals(l, 1.62);
dart.hotRestart();
- Expect.throws(() => l.s);
- l.s = "set";
- Expect.equals(l.s, "set");
+ Expect.throws(() => Lates.s);
+ Expect.throws(() => l);
+ Lates.s = "set";
+ Expect.equals(Lates.s, "set");
+ l = 1.62;
+ Expect.equals(l, 1.62);
dart.hotRestart();
dart.hotRestart();
- Expect.throws(() => l.s);
+ Expect.throws(() => Lates.s);
+ Expect.throws(() => l);
}
diff --git a/tests/ffi/coordinate.dart b/tests/ffi/coordinate.dart
index 92dd9d4..9507312 100644
--- a/tests/ffi/coordinate.dart
+++ b/tests/ffi/coordinate.dart
@@ -10,12 +10,12 @@
/// Sample struct for dart:ffi library.
class Coordinate extends Struct {
@Double()
- double x;
+ external double x;
@Double()
- double y;
+ external double y;
- Pointer<Coordinate> next;
+ external Pointer<Coordinate> next;
factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
return allocate<Coordinate>().ref
diff --git a/tests/ffi/coordinate_bare.dart b/tests/ffi/coordinate_bare.dart
index daaea24..09509b7 100644
--- a/tests/ffi/coordinate_bare.dart
+++ b/tests/ffi/coordinate_bare.dart
@@ -9,10 +9,10 @@
/// Stripped down sample struct for dart:ffi library.
class Coordinate extends Struct {
@Double()
- double x;
+ external double x;
@Double()
- double y;
+ external double y;
- Pointer<Coordinate> next;
+ external Pointer<Coordinate> next;
}
diff --git a/tests/ffi/extension_methods_test.dart b/tests/ffi/extension_methods_test.dart
index 19bc44b..d4e8e4a 100644
--- a/tests/ffi/extension_methods_test.dart
+++ b/tests/ffi/extension_methods_test.dart
@@ -61,5 +61,5 @@
class Foo extends Struct {
@Int8()
- int a;
+ external int a;
}
diff --git a/tests/ffi/very_large_struct.dart b/tests/ffi/very_large_struct.dart
index ca29143..d827e4a 100644
--- a/tests/ffi/very_large_struct.dart
+++ b/tests/ffi/very_large_struct.dart
@@ -7,45 +7,45 @@
/// Large sample struct for dart:ffi library.
class VeryLargeStruct extends Struct {
@Int8()
- int a;
+ external int a;
@Int16()
- int b;
+ external int b;
@Int32()
- int c;
+ external int c;
@Int64()
- int d;
+ external int d;
@Uint8()
- int e;
+ external int e;
@Uint16()
- int f;
+ external int f;
@Uint32()
- int g;
+ external int g;
@Uint64()
- int h;
+ external int h;
@IntPtr()
- int i;
+ external int i;
@Double()
- double j;
+ external double j;
@Float()
- double k;
+ external double k;
- Pointer<VeryLargeStruct> parent;
+ external Pointer<VeryLargeStruct> parent;
@IntPtr()
- int numChildren;
+ external int numChildren;
- Pointer<VeryLargeStruct> children;
+ external Pointer<VeryLargeStruct> children;
@Int8()
- int smallLastField;
+ external int smallLastField;
}
diff --git a/tests/ffi/vmspecific_static_checks_test.dart b/tests/ffi/vmspecific_static_checks_test.dart
index a0af90f..f6236e8 100644
--- a/tests/ffi/vmspecific_static_checks_test.dart
+++ b/tests/ffi/vmspecific_static_checks_test.dart
@@ -309,9 +309,9 @@
// error on missing field annotation
class TestStruct extends Struct {
@Double()
- double x;
+ external double x;
- double y; //# 50: compile-time error
+ external double y; //# 50: compile-time error
}
// Cannot extend structs.
@@ -321,25 +321,25 @@
class TestStruct4 extends Struct {
@Double()
@Double() //# 53: compile-time error
- double z;
+ external double z;
}
// error on annotation not matching up
class TestStruct5 extends Struct {
@Int64() //# 54: compile-time error
- double z; //# 54: compile-time error
+ external double z; //# 54: compile-time error
}
// error on annotation not matching up
class TestStruct6 extends Struct {
@Void() //# 55: compile-time error
- double z; //# 55: compile-time error
+ external double z; //# 55: compile-time error
}
// error on annotation not matching up
class TestStruct7 extends Struct {
@NativeType() //# 56: compile-time error
- double z; //# 56: compile-time error
+ external double z; //# 56: compile-time error
}
// error on field initializer on field
@@ -350,8 +350,8 @@
// error on field initializer in constructor
class TestStruct9 extends Struct {
- @Double()
- double z;
+ @Double() //# 58: compile-time error
+ double z; //# 58: compile-time error
TestStruct9() : z = 0.0 {} //# 58: compile-time error
}
@@ -364,7 +364,7 @@
// annotation).
class TestStruct12 extends Struct {
@Pointer //# 61: compile-time error
- TestStruct9 struct; //# 61: compile-time error
+ external TestStruct9 struct; //# 61: compile-time error
}
class DummyAnnotation {
@@ -375,7 +375,7 @@
class TestStruct13 extends Struct {
@DummyAnnotation()
@Double()
- double z;
+ external double z;
}
// Cannot extend native types.
diff --git a/tests/language/if_null/assignment_behavior_test.dart b/tests/language/if_null/assignment_behavior_test.dart
index a95aa57..6cdccc7 100644
--- a/tests/language/if_null/assignment_behavior_test.dart
+++ b/tests/language/if_null/assignment_behavior_test.dart
@@ -124,6 +124,10 @@
// ^^^^^^^^
// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL
// [cfe] The setter 'finalOne' isn't defined for the class 'C'.
+// ^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+// ^^^^
+// [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
yGetValue = 1;
}
}
@@ -160,15 +164,25 @@
h.xGetValue = 1; check(1, () => h.x ??= bad(), ['h.x']);
yGetValue = 1; check(1, () => h.x ??= y, ['h.x', 'y', 'h.x=1']);
{ var l = 1; check(1, () => l ??= bad(), []); }
+ // ^^^^^
+ // [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
{ var l; yGetValue = 1; check(1, () => l ??= y, ['y']); Expect.equals(1, l); }
{ final l = 1; l ??= null; }
// ^
// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
// [cfe] Can't assign to the final variable 'l'.
+ // ^^^^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // ^^^^
+ // [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
C ??= null;
//^
// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
// [cfe] Can't assign to a type literal.
+// ^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+// ^^^^
+// [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
h ??= null;
//^
// [analyzer] COMPILE_TIME_ERROR.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT
diff --git a/tests/language/implicit_creation/implicit_const_context_constructor_generic_named_test.dart b/tests/language/implicit_creation/implicit_const_context_constructor_generic_named_test.dart
new file mode 100644
index 0000000..468077d
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_constructor_generic_named_test.dart
@@ -0,0 +1,52 @@
+// 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:expect/expect.dart";
+
+// Test that constructor invocations are constant
+// when evaluated in a const context.
+
+class C<T> {
+ final T x;
+ const C.named(this.x);
+
+ // Static const.
+ static const staticConst = C<int>.named(42);
+}
+
+// Top-level const.
+const topConst = C<int>.named(42);
+
+main() {
+ const c0 = const C<int>.named(42); // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = C<int>.named(42);
+
+ // Inside const expression.
+ var c2 = (const [C<int>.named(42)])[0]; // List element.
+ var c3 = (const {C<int>.named(42): 0}).keys.first; // Map key.
+ var c4 = (const {0: C<int>.named(42)}).values.first; // Map value.
+ var c5 = (const C.named(C<int>.named(42))).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case C<int>.named(42): break;
+ default: Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C.named(C<int>.named(42))
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_constructor_generic_test.dart b/tests/language/implicit_creation/implicit_const_context_constructor_generic_test.dart
new file mode 100644
index 0000000..ffeb1fe
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_constructor_generic_test.dart
@@ -0,0 +1,54 @@
+// 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:expect/expect.dart";
+
+// Test that constructor invocations are constant
+// when evaluated in a const context.
+
+class C<T> {
+ final T x;
+ const C(this.x);
+
+ // Static const.
+ static const staticConst = C<int>(42);
+}
+
+// Top-level const.
+const topConst = C<int>(42);
+
+main() {
+ const c0 = const C<int>(42); // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = C<int>(42);
+
+ // Inside const expression.
+ var c2 = (const [C<int>(42)])[0]; // List element.
+ var c3 = (const {C<int>(42): 0}).keys.first; // Map key.
+ var c4 = (const {0: C<int>(42)}).values.first; // Map value.
+ var c5 = (const C(C<int>(42))).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case C<int>(42):
+ break;
+ default:
+ Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C(C<int>(42))
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_constructor_named_test.dart b/tests/language/implicit_creation/implicit_const_context_constructor_named_test.dart
new file mode 100644
index 0000000..16345ab
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_constructor_named_test.dart
@@ -0,0 +1,54 @@
+// 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:expect/expect.dart";
+
+// Test that constructor invocations are constant
+// when evaluated in a const context.
+
+class C {
+ final Object x;
+ const C.named(this.x);
+
+ // Static const.
+ static const staticConst = C.named(42);
+}
+
+// Top-level const.
+const topConst = C.named(42);
+
+main() {
+ const c0 = const C.named(42); // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = C.named(42);
+
+ // Inside const expression.
+ var c2 = (const [C.named(42)])[0]; // List element.
+ var c3 = (const {C.named(42): 0}).keys.first; // Map key.
+ var c4 = (const {0: C.named(42)}).values.first; // Map value.
+ var c5 = (const C.named(C.named(42))).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case C.named(42):
+ break;
+ default:
+ Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C.named(C.named(42))
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_constructor_test.dart b/tests/language/implicit_creation/implicit_const_context_constructor_test.dart
new file mode 100644
index 0000000..fec39c2
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_constructor_test.dart
@@ -0,0 +1,54 @@
+// 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:expect/expect.dart";
+
+// Test that constructor invocations are constant
+// when evaluated in a const context.
+
+class C {
+ final Object x;
+ const C(this.x);
+
+ // Static const.
+ static const staticConst = C(42);
+}
+
+// Top-level const.
+const topConst = C(42);
+
+main() {
+ const c0 = const C(42); // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = C(42);
+
+ // Inside const expression.
+ var c2 = (const [C(42)])[0]; // List element.
+ var c3 = (const {C(42): 0}).keys.first; // Map key.
+ var c4 = (const {0: C(42)}).values.first; // Map value.
+ var c5 = (const C(C(42))).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case C(42):
+ break;
+ default:
+ Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C(C(42))
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_list_test.dart b/tests/language/implicit_creation/implicit_const_context_list_test.dart
new file mode 100644
index 0000000..c089d35
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_list_test.dart
@@ -0,0 +1,63 @@
+// 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:expect/expect.dart";
+
+// Test that list literals are constant when evaluated in a const context.
+
+class C {
+ final Object x;
+ const C(this.x);
+
+ // Static const.
+ static const staticConst = <int>[42];
+}
+
+// Top-level const.
+const topConst = <int>[42];
+
+main() {
+ const c0 = const <int>[42]; // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = <int>[42];
+
+ // Inside const expression.
+ var c2 = (const [
+ <int>[42]
+ ])[0]; // List element.
+ var c3 = (const {
+ <int>[42]: 0
+ })
+ .keys
+ .first; // Map key.
+ var c4 = (const {
+ 0: <int>[42]
+ })
+ .values
+ .first; // Map value.
+ var c5 = (const C(<int>[42])).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case <int>[42]:
+ break;
+ default:
+ Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C(<int>[42])
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_map_test.dart b/tests/language/implicit_creation/implicit_const_context_map_test.dart
new file mode 100644
index 0000000..231bfc3
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_map_test.dart
@@ -0,0 +1,63 @@
+// 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:expect/expect.dart";
+
+// Test that map literals are constant when evaluated in a const context.
+
+class C {
+ final Object x;
+ const C(this.x);
+
+ // Static const.
+ static const staticConst = <int, int>{37: 87};
+}
+
+// Top-level const.
+const topConst = <int, int>{37: 87};
+
+main() {
+ const c0 = const <int, int>{37: 87}; // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = <int, int>{37: 87};
+
+ // Inside const expression.
+ var c2 = (const [
+ <int, int>{37: 87}
+ ])[0]; // List element.
+ var c3 = (const {
+ <int, int>{37: 87}: 0
+ })
+ .keys
+ .first; // Map key.
+ var c4 = (const {
+ 0: <int, int>{37: 87}
+ })
+ .values
+ .first; // Map value.
+ var c5 = (const C(<int, int>{37: 87})).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case <int, int>{37: 87}:
+ break;
+ default:
+ Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C(<int, int>{37: 87})
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_not_test.dart b/tests/language/implicit_creation/implicit_const_context_not_test.dart
new file mode 100644
index 0000000..7d69c0a
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_not_test.dart
@@ -0,0 +1,78 @@
+// 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:expect/expect.dart";
+
+// Check places that are *not* supposed to be constant contexts,
+// but which do require constant values, do not introduce an implicit const.
+// Nested expressions still do.
+// (Also acts as regression test for http:/dartbug.com/36533)
+
+class C {
+ final v;
+
+ // Initializer of final field in class with const constructor.
+ // Can't use `const C()`, it's a cyclic constant dependency.
+ final i1 = []; //# 1: compile-time error
+ final i2 = const [];
+ final i3 = const [[]];
+
+ const C([this.v]);
+
+ // Initializer expression in generative const constructor.
+ const C.c1() : v = C(); //# 2: compile-time error
+ const C.c2() : v = const C();
+ const C.c3() : v = const C(C());
+
+ // Expression in redirecting generative const constuctor.
+ const C.r1() : this(C()); //# 3: compile-time error
+ const C.r2() : this(const C());
+ const C.r3() : this(const C(C()));
+
+ // Default value of positional optional parameter.
+ static List<C> foo([
+ p1 = C(), //# 4: compile-time error
+ p2 = const C(),
+ p3 = const C(C()),
+ ]) =>
+ [p2, p3];
+
+ // Default value of named optional parameter.
+ static List<C> bar({
+ p1 = C(), //# 5: compile-time error
+ p2 = const C(),
+ p3 = const C(C()),
+ }) =>
+ [p2, p3];
+}
+
+void main() {
+ var c = const C();
+ var cc = const C(C());
+
+ // Check that const constructors can be invoked without `const`,
+ // creating new instances every time.
+ var nc1 = C();
+ var nc2 = C.c2();
+ var nc3 = C.c3();
+ var nc4 = C.r2();
+ var nc5 = C.r3();
+ Expect.allDistinct([nc1, nc2, nc3, nc4, nc5, c, cc]);
+
+ // Check that const invocations create identical objects.
+ Expect.identical(c, C.c2().v);
+ Expect.identical(cc, C.c3().v);
+
+ Expect.identical(c, C.r2().v);
+ Expect.identical(cc, C.r3().v);
+
+ Expect.identical(const [], C().i2);
+ Expect.identical(const [[]], C().i3);
+
+ Expect.identical(c, C.foo()[0]);
+ Expect.identical(cc, C.foo()[1]);
+
+ Expect.identical(c, C.bar()[0]);
+ Expect.identical(cc, C.bar()[1]);
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_prefix_constructor_generic_named_test.dart b/tests/language/implicit_creation/implicit_const_context_prefix_constructor_generic_named_test.dart
new file mode 100644
index 0000000..0455aa7
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_prefix_constructor_generic_named_test.dart
@@ -0,0 +1,55 @@
+// 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:expect/expect.dart";
+
+import "implicit_const_context_prefix_constructor_generic_named_test.dart"
+ as prefix;
+
+// Test that constructor invocations are constant
+// when evaluated in a const context.
+
+class C<T> {
+ final T x;
+ const C.named(this.x);
+
+ // Static const.
+ static const staticConst = prefix.C<int>.named(42);
+}
+
+// Top-level const.
+const topConst = prefix.C<int>.named(42);
+
+main() {
+ const c0 = const prefix.C<int>.named(42); // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = prefix.C<int>.named(42);
+
+ // Inside const expression.
+ var c2 = (const [prefix.C<int>.named(42)])[0]; // List element.
+ var c3 = (const {prefix.C<int>.named(42): 0}).keys.first; // Map key.
+ var c4 = (const {0: prefix.C<int>.named(42)}).values.first; // Map value.
+ var c5 = (const C.named(prefix.C<int>.named(42))).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case prefix.C<int>.named(42): break;
+ default: Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C.named(prefix.C<int>.named(42))
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_prefix_constructor_generic_test.dart b/tests/language/implicit_creation/implicit_const_context_prefix_constructor_generic_test.dart
new file mode 100644
index 0000000..e86289f
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_prefix_constructor_generic_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.
+
+import "package:expect/expect.dart";
+
+import "implicit_const_context_prefix_constructor_generic_test.dart" as prefix;
+
+// Test that constructor invocations are constant
+// when evaluated in a const context.
+
+class C<T> {
+ final T x;
+ const C(this.x);
+
+ // Static const.
+ static const staticConst = prefix.C<int>(42);
+}
+
+// Top-level const.
+const topConst = prefix.C<int>(42);
+
+main() {
+ const c0 = const prefix.C<int>(42); // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = prefix.C<int>(42);
+
+ // Inside const expression.
+ var c2 = (const [prefix.C<int>(42)])[0]; // List element.
+ var c3 = (const {prefix.C<int>(42): 0}).keys.first; // Map key.
+ var c4 = (const {0: prefix.C<int>(42)}).values.first; // Map value.
+ var c5 = (const C(prefix.C<int>(42))).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case prefix.C<int>(42):
+ break;
+ default:
+ Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C(prefix.C<int>(42))
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_prefix_constructor_named_test.dart b/tests/language/implicit_creation/implicit_const_context_prefix_constructor_named_test.dart
new file mode 100644
index 0000000..4ab1603
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_prefix_constructor_named_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.
+
+import "package:expect/expect.dart";
+
+import "implicit_const_context_prefix_constructor_named_test.dart" as prefix;
+
+// Test that constructor invocations are constant
+// when evaluated in a const context.
+
+class C {
+ final Object x;
+ const C.named(this.x);
+
+ // Static const.
+ static const staticConst = prefix.C.named(42);
+}
+
+// Top-level const.
+const topConst = prefix.C.named(42);
+
+main() {
+ const c0 = const prefix.C.named(42); // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = prefix.C.named(42);
+
+ // Inside const expression.
+ var c2 = (const [prefix.C.named(42)])[0]; // List element.
+ var c3 = (const {prefix.C.named(42): 0}).keys.first; // Map key.
+ var c4 = (const {0: prefix.C.named(42)}).values.first; // Map value.
+ var c5 = (const C.named(prefix.C.named(42))).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case prefix.C.named(42):
+ break;
+ default:
+ Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C.named(prefix.C.named(42))
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_context_prefix_constructor_test.dart b/tests/language/implicit_creation/implicit_const_context_prefix_constructor_test.dart
new file mode 100644
index 0000000..cfd8fd1
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_context_prefix_constructor_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.
+
+import "package:expect/expect.dart";
+
+import "implicit_const_context_prefix_constructor_test.dart" as prefix;
+
+// Test that constructor invocations are constant
+// when evaluated in a const context.
+
+class C {
+ final Object x;
+ const C(this.x);
+
+ // Static const.
+ static const staticConst = prefix.C(42);
+}
+
+// Top-level const.
+const topConst = prefix.C(42);
+
+main() {
+ const c0 = const prefix.C(42); // Explicit const.
+
+ // RHS of const local variable.
+ const c1 = prefix.C(42);
+
+ // Inside const expression.
+ var c2 = (const [prefix.C(42)])[0]; // List element.
+ var c3 = (const {prefix.C(42): 0}).keys.first; // Map key.
+ var c4 = (const {0: prefix.C(42)}).values.first; // Map value.
+ var c5 = (const C(prefix.C(42))).x; // Constructor argument.
+
+ Expect.identical(c0, c1);
+ Expect.identical(c0, c2);
+ Expect.identical(c0, c3);
+ Expect.identical(c0, c4);
+ Expect.identical(c0, c5);
+ Expect.identical(c0, C.staticConst);
+ Expect.identical(c0, topConst);
+
+ // Switch case expression.
+ switch (c0) {
+ case prefix.C(42):
+ break;
+ default:
+ Expect.fail("Didn't match constant");
+ }
+
+ // Annotation argument.
+ // (Cannot check that it's const, just that it's accepted).
+ @C(prefix.C(42))
+ var foo = null;
+ foo; // avoid "unused" hints.
+}
diff --git a/tests/language/implicit_creation/implicit_const_not_default_values_test.dart b/tests/language/implicit_creation/implicit_const_not_default_values_test.dart
new file mode 100644
index 0000000..3968dea
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_const_not_default_values_test.dart
@@ -0,0 +1,123 @@
+// 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.
+
+// Tests that const/new-insertion does the right thing for default values.
+// A default-value expression does not introduce a const context.
+
+main() {
+ foo();
+ bar();
+ baz();
+ qux();
+ C.foo();
+ C.bar();
+ new C().baz();
+ new C().qux();
+ new C.pos();
+ new C.nam();
+ const C.pos();
+ const C.nam();
+}
+
+// Default arguments must be const to be accepted
+foo([x //
+ = const [C()] // //# o1: ok
+ = const {42: C()} // //# o2: ok
+ = const C(C()) // //# o3: ok
+ = [42] // //# e1: compile-time error
+ = {42: 42} // //# e2: compile-time error
+ = C([]) // //# e3: compile-time error
+ ]) {
+}
+
+bar({x //
+ = const [C()] // //# o4: ok
+ = const {42: C()} // //# o5: ok
+ = const C(C()) // //# o6: ok
+ = [42] // //# e4: compile-time error
+ = {42: 42} // //# e5: compile-time error
+ = C([]) // //# e6: compile-time error
+ }) {
+}
+
+var baz = ([x
+ = const [C()] // //# o7: ok
+ = const {42: C()} // //# o8: ok
+ = const C(C()) // //# o9: ok
+ = [42] // //# e7: compile-time error
+ = {42: 42} // //# e8: compile-time error
+ = C([]) // //# e9: compile-time error
+]) => 42;
+
+var qux = ({x
+ = const [C()] // //# o10: ok
+ = const {42: C()} // //# o11: ok
+ = const C(C()) // //# o12: ok
+ = [42] // //# e10: compile-time error
+ = {42: 42} // //# e11: compile-time error
+ = C([]) // //# e12: compile-time error
+}) => 42;
+
+class C {
+ final x;
+ const C([this.x]);
+
+ const C.pos([this.x //
+ = const [C()] // //# o13: ok
+ = const {42: C()} // //# o14: ok
+ = const C(C()) // //# o15: ok
+ = [42] // //# e13: compile-time error
+ = {42: 42} // //# e14: compile-time error
+ = C([]) // //# e15: compile-time error
+ ]);
+
+ const C.nam({this.x //
+ = const [C()] // //# o16: ok
+ = const {42: C()} // //# o17: ok
+ = const C(C()) // //# o18: ok
+ = [42] // //# e16: compile-time error
+ = {42: 42} // //# e17: compile-time error
+ = C([]) // //# e18: compile-time error
+ });
+
+ static foo([x //
+ = const [C()] // //# o19: ok
+ = const {42: C()} // //# o20: ok
+ = const C(C()) // //# o21: ok
+ = [42] // //# e19: compile-time error
+ = {42: 42} // //# e20: compile-time error
+ = C([]) // //# e21: compile-time error
+ ]) {
+ }
+
+ static bar({x //
+ = const [C()] // //# o22: ok
+ = const {42: C()} // //# o23: ok
+ = const C(C()) // //# o24: ok
+ = [42] // //# e22: compile-time error
+ = {42: 42} // //# e23: compile-time error
+ = C([]) // //# e24: compile-time error
+ }) {
+ }
+
+ baz([x //
+ = const [C()] // //# o25: ok
+ = const {42: C()} // //# o26: ok
+ = const C(C()) // //# o27: ok
+ = [42] // //# e25: compile-time error
+ = {42: 42} // //# e26: compile-time error
+ = C([]) // //# e27: compile-time error
+ ]) {
+ }
+
+ qux({x //
+ = const [C()] // //# o28: ok
+ = const {42: C()} // //# o29: ok
+ = const C(C()) // //# o30: ok
+ = [42] // //# e28: compile-time error
+ = {42: 42} // //# e29: compile-time error
+ = C([]) // //# e30: compile-time error
+ }) {
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_constructor_generic_named_test.dart b/tests/language/implicit_creation/implicit_new_constructor_generic_named_test.dart
new file mode 100644
index 0000000..11d9aa1
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_constructor_generic_named_test.dart
@@ -0,0 +1,69 @@
+// 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:expect/expect.dart";
+
+// Test that an omitted `new` is allowed for a generic constructor invocation.
+
+class C<T> {
+ final T x;
+ C(this.x); // Not const constructor.
+ const C.c(this.x); // Const constructor.
+
+ operator <(other) => this;
+ operator >(other) => other;
+ operator -() => this;
+
+ C<T> get self => this;
+ C<T> method() => self;
+}
+
+T id<T>(T x) => x;
+
+main() {
+ const cc = const C<int>.c(42); // Canonicalized.
+ var x = 42; // Avoid constant parameter for constant constructor.
+ var c0 = new C<int>.c(x); // Original syntax.
+
+ // Uses of `C<int>.c(x)` in various contexts.
+ var c1 = C<int>.c(x);
+ var c2 = [C<int>.c(x)][0];
+ var c3 = {C<int>.c(x): 0}.keys.first;
+ var c4 = {0: C<int>.c(x)}.values.first;
+ var c5 = id(C<int>.c(x));
+ var c6 = C<int>.c(x).self;
+ var c7 = C<int>.c(x).method();
+ var c8 = C(C<int>.c(x)).x;
+ var c9 = -C<int>.c(x);
+ var c10 = C<int>.c(x) < 9;
+ var c11 = C(null) > C<int>.c(x);
+ var c12 = (c10 == c11) ? null : C<int>.c(x);
+ var c13 = C<int>.c(x)..method();
+ var c14;
+ try {
+ throw C<int>.c(x);
+ } catch (e) {
+ c14 = e;
+ }
+
+ switch (C<int>.c(x)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (C<int>.c(x); false; C<int>.c(x), C<int>.c(x)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values =
+ [cc, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C<int>);
+ Expect.equals(42, (value as C<int>).x);
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_constructor_generic_test.dart b/tests/language/implicit_creation/implicit_new_constructor_generic_test.dart
new file mode 100644
index 0000000..aca30e2
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_constructor_generic_test.dart
@@ -0,0 +1,85 @@
+// 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:expect/expect.dart";
+
+// Test that an omitted `new` is allowed for a generic constructor invocation.
+
+class C<T> {
+ final T x;
+ C(this.x); // Not const constructor.
+ const C.c(this.x); // Const constructor.
+
+ operator <(other) => this;
+ operator >(other) => other;
+ operator -() => this;
+
+ C<T> get self => this;
+ C<T> method() => self;
+}
+
+T id<T>(T x) => x;
+
+main() {
+ const cc = const C<int>.c(42); // Canonicalized.
+
+ var c0 = new C<int>(42); // Original syntax.
+
+ // Uses of `C<int>(42)` in various contexts.
+ var c1 = C<int>(42);
+ var c2 = [C<int>(42)][0];
+ var c3 = {C<int>(42): 0}.keys.first;
+ var c4 = {0: C<int>(42)}.values.first;
+ var c5 = id(C<int>(42));
+ var c6 = C<int>(42).self;
+ var c7 = C<int>(42).method();
+ var c8 = C(C<int>(42)).x;
+ var c9 = -C<int>(42);
+ var c10 = C<int>(42) < 9;
+ var c11 = C(null) > C<int>(42);
+ var c12 = (c10 == c11) ? null : C<int>(42);
+ var c13 = C<int>(42)..method();
+ var c14;
+ try {
+ throw C<int>(42);
+ } catch (e) {
+ c14 = e;
+ }
+
+ switch (C<int>(42)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (C<int>(42); false; C<int>(42), C<int>(42)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values = [
+ cc,
+ c0,
+ c1,
+ c2,
+ c3,
+ c4,
+ c5,
+ c6,
+ c7,
+ c8,
+ c9,
+ c10,
+ c11,
+ c12,
+ c13,
+ c14
+ ];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C<int>);
+ Expect.equals(42, (value as C<int>).x);
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_constructor_named_test.dart b/tests/language/implicit_creation/implicit_new_constructor_named_test.dart
new file mode 100644
index 0000000..d576915
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_constructor_named_test.dart
@@ -0,0 +1,86 @@
+// 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:expect/expect.dart";
+
+// Test that an omitted `new` is allowed for a non-generic class.
+
+class C {
+ final Object? x;
+ C(this.x); // Not const constructor.
+ const C.c(this.x); // Const constructor.
+
+ operator <(other) => this;
+ operator >(other) => other;
+ operator -() => this;
+
+ C get self => this;
+ C method() => self;
+}
+
+T id<T>(T x) => x;
+
+main() {
+ const cc = const C.c(42); // Canonicalized.
+ var x = 42; // Avoid constant parameter.
+ var c0 = new C.c(x); // Original syntax.
+
+ // Uses of `C.c(x)` in various contexts.
+ var c1 = C.c(x);
+ var c2 = [C.c(x)][0];
+ var c3 = {C.c(x): 0}.keys.first;
+ var c4 = {0: C.c(x)}.values.first;
+ var c5 = id(C.c(x));
+ var c6 = C.c(x).self;
+ var c7 = C.c(x).method();
+ var c8 = C(C.c(x)).x;
+ var c9 = -C.c(x);
+ var c10 = C.c(x) < 9;
+ var c11 = C(null) > C.c(x);
+ var c12 = (c10 == c11) ? null : C.c(x);
+ var c13 = C.c(x)..method();
+ var c14;
+ try {
+ throw C.c(x);
+ } catch (e) {
+ c14 = e;
+ }
+ Expect.isNotNull(c12);
+
+ switch (C.c(x)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (C.c(x); false; C.c(x), C.c(x)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values = [
+ cc,
+ c0,
+ c1,
+ c2,
+ c3,
+ c4,
+ c5,
+ c6,
+ c7,
+ c8,
+ c9,
+ c10,
+ c11,
+ c12,
+ c13,
+ c14
+ ];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C);
+ Expect.equals(42, (value as C).x);
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_constructor_test.dart b/tests/language/implicit_creation/implicit_new_constructor_test.dart
new file mode 100644
index 0000000..3ad4f51
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_constructor_test.dart
@@ -0,0 +1,149 @@
+// 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:expect/expect.dart";
+
+// Test that an omitted `new` is allowed for a non-generic class.
+
+class C {
+ final Object? x;
+ C(this.x); // Not const constructor.
+ const C.c(this.x); // Const constructor.
+
+ operator <(other) => this;
+ operator >(other) => other;
+ operator -() => this;
+
+ C get self => this;
+ C method() => self;
+}
+
+T id<T>(T x) => x;
+
+main() {
+ const cc = const C.c(42); // Canonicalized.
+
+ var c0 = new C(42); // Original syntax.
+
+ // Uses of `C(42)` in various contexts.
+ var c1 = C(42);
+ var c2 = [C(42)][0];
+ var c3 = {C(42): 0}.keys.first;
+ var c4 = {0: C(42)}.values.first;
+ var c5 = id(C(42));
+ var c6 = C(42).self;
+ var c7 = C(42).method();
+ var c8 = C(C(42)).x;
+ var c9 = -C(42);
+ var c10 = C(42) < 9;
+ var c11 = C(null) > C(42);
+ var c12 = (c10 == c11) ? null : C(42);
+ var c13 = C(42)..method();
+ var c14;
+ try {
+ throw C(42);
+ } catch (e) {
+ c14 = e;
+ }
+
+ switch (C(42)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (C(42); false; C(42), C(42)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values = [
+ cc,
+ c0,
+ c1,
+ c2,
+ c3,
+ c4,
+ c5,
+ c6,
+ c7,
+ c8,
+ c9,
+ c10,
+ c11,
+ c12,
+ c13,
+ c14
+ ];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C);
+ Expect.equals(42, (value as C).x);
+ }
+}
+
+void testNamed() {
+ const cc = const C.c(42); // Canonicalized.
+ var x = 42; // Avoid constant parameter.
+ var c0 = new C.c(x); // Original syntax.
+
+ // Uses of `C.c(x)` in various contexts.
+ var c1 = C.c(x);
+ var c2 = [C.c(x)][0];
+ var c3 = {C.c(x): 0}.keys.first;
+ var c4 = {0: C.c(x)}.values.first;
+ var c5 = id(C.c(x));
+ var c6 = C.c(x).self;
+ var c7 = C.c(x).method();
+ var c8 = C(C.c(x)).x;
+ var c9 = -C.c(x);
+ var c10 = C.c(x) < 9;
+ var c11 = C(null) > C.c(x);
+ var c12 = (c10 == c11) ? null : C.c(x);
+ var c13 = C.c(x)..method();
+ var c14;
+ try {
+ throw C.c(x);
+ } catch (e) {
+ c14 = e;
+ }
+ Expect.isNotNull(c12);
+
+ switch (C.c(x)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (C.c(x); false; C.c(x), C.c(x)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values = [
+ cc,
+ c0,
+ c1,
+ c2,
+ c3,
+ c4,
+ c5,
+ c6,
+ c7,
+ c8,
+ c9,
+ c10,
+ c11,
+ c12,
+ c13,
+ c14
+ ];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C);
+ Expect.equals(42, (value as C).x);
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_or_const_composite_test.dart b/tests/language/implicit_creation/implicit_new_or_const_composite_test.dart
new file mode 100644
index 0000000..3b9af6d
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_or_const_composite_test.dart
@@ -0,0 +1,228 @@
+// 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:expect/expect.dart";
+
+// Tests that new-insertion always inserts `new` when not in const context,
+// no matter what the arguments are.
+// There is (currently) no automatic const insertion in non-const context.
+//
+// Not testing inference, so all type arguments are explicit.
+
+main() {
+ var x = 42;
+ const cc42 = const C(42);
+ var c42 = cc42;
+
+ const clist = const <int>[37];
+ var list = clist;
+ const cmap = const <int, int>{19: 87};
+ var map = cmap;
+
+ {
+ // Constructor inside constructor.
+ var d42 = const D<int>(42);
+
+ const cd1 = const C(const D<int>(42));
+ const cd2 = C(D<int>(42)); // Const context.
+ var cd3 = C(D<int>(42)); // Non-constant context, so `new`.
+ var cd4 = C(D<int>(x)); // Non-constant context, so `new`.
+ var cd5 = C(d42); // Non-constant context, so `new`.
+
+ Expect.identical(cd1, cd2);
+ Expect.allDistinct([cd1, cd3, cd4, cd5]);
+ }
+
+ {
+ // List inside other constructor
+ const cl1 = const C(const <int>[37]);
+ const cl2 = C(clist); // Constant context.
+ const cl3 = C(const <int>[37]); // Constant context.
+ const cl4 = C(<int>[37]); // Constant context.
+ var cl5 = C(clist); // Non-constant context, so `new`.
+ var cl6 = C(const <int>[37]); // Non-constant context, so `new`.
+ var cl7 = C(list); // Non-constant context, so `new`.
+ var cl8 = C(<int>[37]); // Non-constant context, so `new`.
+
+ Expect.allIdentical([cl1, cl2, cl3, cl4]);
+ Expect.allDistinct([cl1, cl5, cl6, cl7, cl8]);
+ }
+
+ {
+ // Map inside other constructor.
+ const cm1 = C(cmap); // Constant context.
+ const cm2 = C(const <int, int>{19: 87}); // Constant context.
+ const cm3 = C(<int, int>{19: 87}); // Constant context.
+ var cm4 = C(cmap); // Non-constant context, so `new`.
+ var cm5 = C(const <int, int>{19: 87}); // Non-constant context, so `new`.
+ var cm6 = C(map); // Non-constant context, so `new`.
+ var cm7 = C(<int, int>{19: 87}); // Non-constant context, so `new`.
+
+ Expect.identical(cm1, cm2);
+ Expect.identical(cm1, cm3);
+ Expect.allDistinct([cm1, cm4, cm5, cm6, cm7]);
+ }
+
+ {
+ // Composite with more than one sub-expression.
+ const n1 = N(clist, cmap);
+ const n2 = N(const <int>[37], const <int, int>{19: 87});
+ const n3 = N(<int>[37], <int, int>{19: 87});
+ var n4 = N(const <int>[37], const <int, int>{19: 87});
+ var n5 = N(<int>[37], const <int, int>{19: 87});
+ var n6 = N(const <int>[37], <int, int>{19: 87});
+ var n7 = N(<int>[37], <int, int>{19: 87});
+ var n8 = N(clist, cmap);
+ var n9 = N(<int>[37], cmap);
+ var n10 = N(clist, <int, int>{19: 87});
+ var n11 = N(<int>[37], <int, int>{19: 87});
+ var n12 = N(list, cmap);
+ var n13 = N(clist, map);
+ var n14 = N(list, map);
+
+ Expect.identical(n1, n2);
+ Expect.identical(n1, n3);
+ Expect.allDistinct([n1, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14]);
+
+ Expect
+ .allIdentical([clist, n6.left, n10.left, n12.left, n13.left, n14.left]);
+ Expect.allDistinct([n5.left, n7.left, n9.left, n11.left]);
+
+ Expect.allIdentical(
+ [cmap, n5.right, n9.right, n12.right, n13.right, n14.right]);
+ Expect.allDistinct([n6.right, n7.right, n10.right, n11.right]);
+
+ const n20 = const N(const C(42), const <int>[37]);
+ const n21 = N(const C(42), const <int>[37]);
+ const n22 = N(C(42), const <int>[37]);
+ const n23 = N(C(42), clist);
+ const n24 = N(C(42), <int>[37]);
+ var n25 = N(const C(42), const <int>[37]);
+ var n26 = N(C(42), const <int>[37]);
+ var n27 = N(C(42), clist);
+ var n28 = N(C(42), <int>[37]);
+ var n29 = N(C(42), list);
+ var n30 = N(c42, clist);
+ var n31 = N(cc42, list);
+
+ Expect.allIdentical([n20, n21, n22, n23, n24]);
+ Expect.allDistinct([n20, n25, n26, n27, n28, n29, n30, n31]);
+
+ Expect.allDistinct([cc42, n28.left, n29.left]);
+ Expect.identical(cc42, n30.left);
+ Expect.identical(cc42, n31.left);
+ Expect.allIdentical([clist, n29.right, n30.right, n31.right]);
+ Expect.notIdentical(clist, n28.right);
+ }
+
+ {
+ // List literals.
+ const l20 = const [
+ const C(42),
+ const <int>[37]
+ ];
+ const l21 = [
+ const C(42),
+ const <int>[37]
+ ];
+ const l22 = [
+ C(42),
+ const <int>[37]
+ ];
+ var l23 = const [C(42), clist];
+ const l24 = [
+ C(42),
+ <int>[37]
+ ];
+ var l25 = [
+ const C(42),
+ const <int>[37]
+ ];
+ var l26 = [
+ C(42),
+ const <int>[37]
+ ];
+ var l27 = [C(42), clist];
+ var l28 = [
+ C(42),
+ <int>[37]
+ ];
+ var l29 = [C(42), list];
+ var l30 = [c42, clist];
+ var l31 = [cc42, list];
+
+ Expect.allIdentical([l20, l21, l22, l23, l24]);
+ // List literals are never const unless in const context.
+ Expect.allDistinct([l20, l25, l26, l27, l28, l29, l30, l31]);
+ Expect.allIdentical([cc42, l25[0], l30[0], l31[0]]);
+ Expect.allDistinct([cc42, l26[0], l27[0], l28[0], l29[0]]);
+ Expect
+ .allIdentical([clist, l25[1], l26[1], l27[1], l29[1], l30[1], l31[1]]);
+ Expect.notIdentical(clist, l28[1]);
+ }
+
+ {
+ // Map literals.
+ const m20 = const <C, List<int>>{
+ const C(42): const <int>[37]
+ };
+ const m21 = {
+ const C(42): const <int>[37]
+ };
+ const m22 = {
+ C(42): const <int>[37]
+ };
+ var m23 = const {C(42): clist};
+ const m24 = {
+ C(42): <int>[37]
+ };
+ var m25 = {
+ const C(42): const <int>[37]
+ };
+ var m26 = {
+ C(42): const <int>[37]
+ };
+ var m27 = {C(42): clist};
+ var m28 = {
+ C(42): <int>[37]
+ };
+ var m29 = {C(42): list};
+ var m30 = {c42: clist};
+ var m31 = {cc42: list};
+
+ Expect.allIdentical([m20, m21, m22, m23, m24]);
+ // Map literals are never const unless in const context.
+ Expect.allDistinct([m20, m25, m26, m27, m28, m29, m30, m31]);
+ Expect.identical(cc42, m25.keys.first);
+ Expect.allDistinct(
+ [cc42, m26.keys.first, m27.keys.first, m28.keys.first, m29.keys.first]);
+ Expect.identical(cc42, m30.keys.first);
+ Expect.identical(cc42, m31.keys.first);
+ Expect.allIdentical([
+ clist,
+ m25.values.first,
+ m26.values.first,
+ m27.values.first,
+ m29.values.first,
+ m30.values.first,
+ m31.values.first
+ ]);
+ Expect.notIdentical(clist, m28.values.first);
+ }
+}
+
+class C {
+ final Object x;
+ const C(this.x);
+}
+
+class D<T> {
+ final T x;
+ const D(this.x);
+}
+
+class N {
+ final Object left, right;
+ const N(this.left, this.right);
+}
diff --git a/tests/language/implicit_creation/implicit_new_or_const_generic_test.dart b/tests/language/implicit_creation/implicit_new_or_const_generic_test.dart
new file mode 100644
index 0000000..af98849
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_or_const_generic_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.
+
+import "package:expect/expect.dart";
+
+import "implicit_new_or_const_generic_test.dart" as prefix;
+
+// Test that const constructors with const arguments do not become const
+// if not in a const context.
+
+// This test uses a generic class cosntructor with no prefix,
+// which requires new Dart 2 syntax.
+
+main() {
+ // Various valid object creation expressions.
+ var x = 42; // non constant variable.
+
+ // Various valid object creation expressions of a generic constructor.
+ // (Requires inference to infer `<int>` for the invocations of `D`.)
+ var instances = <Object>[
+ new D(x),
+ new D(42),
+ const D(42),
+ D(x),
+ D(42),
+ new D.named(x),
+ new D.named(42),
+ const D.named(42),
+ D.named(x),
+ D.named(42),
+ new prefix.D(x),
+ new prefix.D(42),
+ const prefix.D(42),
+ prefix.D(x),
+ prefix.D(42),
+ new prefix.D.named(x),
+ new prefix.D.named(42),
+ const prefix.D.named(42),
+ prefix.D.named(x),
+ prefix.D.named(42),
+ new D<int>(x),
+ new D<int>(42),
+ const D<int>(42),
+ D<int>(x),
+ D<int>(42),
+ new D<int>.named(x),
+ new D<int>.named(42),
+ const D<int>.named(42),
+ D<int>.named(x),
+ D<int>.named(42),
+ new prefix.D<int>(x),
+ new prefix.D<int>(42),
+ const prefix.D<int>(42),
+ prefix.D<int>(x),
+ prefix.D<int>(42),
+ new prefix.D<int>.named(x),
+ new prefix.D<int>.named(42),
+ const prefix.D<int>.named(42),
+ prefix.D<int>.named(x),
+ prefix.D<int>.named(42),
+ ];
+
+ const d42 = const D<int>(42);
+ for (var i = 0; i < instances.length; i++) {
+ var d = instances[i];
+ Expect.equals(d42, d);
+ if (i % 5 == 2) {
+ // The cases of D(42) without "new" are all constant.
+ Expect.identical(d42, d, "$i");
+ } else {
+ // The rest are not.
+ Expect.notIdentical(d42, d, "$i");
+ }
+ }
+
+ // Test instance creation with type parameters.
+ new G<int>().testWithInt();
+}
+
+class D<T> {
+ final T? x;
+
+ const D(this.x);
+ const D.named(this.x);
+
+ int get hashCode => x.hashCode;
+ bool operator ==(Object other) => other is D<Object> && x == other.x;
+}
+
+class G<T> {
+ // Tests creation of D<T> where T is a type variable.
+ void testWithInt() {
+ // Cannot create constants referencing T or x.
+ var instances = [
+ new D<T>(null),
+ D<T>(null),
+ new D<T>.named(null),
+ D<T>.named(null),
+ new prefix.D<T>(null),
+ prefix.D<T>(null),
+ new prefix.D<T>.named(null),
+ prefix.D<T>.named(null),
+ ];
+
+ const dx = const D<int>(null);
+ Expect.allDistinct([dx]..addAll(instances));
+ for (var i = 0; i < instances.length; i++) {
+ var d = instances[i];
+ Expect.isTrue(d is D<T>);
+ Expect.isTrue(d is! D<Null>);
+ Expect.equals(dx, d, "$i");
+ }
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_or_const_test.dart b/tests/language/implicit_creation/implicit_new_or_const_test.dart
new file mode 100644
index 0000000..1d217a6
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_or_const_test.dart
@@ -0,0 +1,61 @@
+// 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:expect/expect.dart";
+
+import "implicit_new_or_const_test.dart" as prefix;
+
+// Test that const constructors with const arguments do not become const
+// if not in a const context.
+
+main() {
+ // Various valid object creation expressions.
+ var x = 42; // non constant variable.
+
+ var instances = <Object>[
+ new C(x),
+ new C(42),
+ const C(42),
+ C(x),
+ C(42),
+ new C.named(x),
+ new C.named(42),
+ const C.named(42),
+ C.named(x),
+ C.named(42),
+ new prefix.C(x),
+ new prefix.C(42),
+ const prefix.C(42),
+ prefix.C(x),
+ prefix.C(42),
+ new prefix.C.named(x),
+ new prefix.C.named(42),
+ const prefix.C.named(42),
+ prefix.C.named(x),
+ prefix.C.named(42),
+ ];
+
+ // Test that the correct ones are constant, and the rest are not.
+ const c42 = const C(42); // Reference constant.
+
+ for (var i = 0; i < instances.length; i++) {
+ var c = instances[i];
+ Expect.equals(c42, c);
+ if (i % 5 == 2) {
+ Expect.identical(c42, c, "$i");
+ } else {
+ Expect.notIdentical(c42, c, "$i");
+ }
+ }
+}
+
+class C {
+ final Object x;
+
+ const C(this.x);
+ const C.named(this.x);
+
+ int get hashCode => x.hashCode;
+ bool operator ==(Object other) => other is C && x == other.x;
+}
diff --git a/tests/language/implicit_creation/implicit_new_prefix_constructor_generic_named_test.dart b/tests/language/implicit_creation/implicit_new_prefix_constructor_generic_named_test.dart
new file mode 100644
index 0000000..600537c
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_prefix_constructor_generic_named_test.dart
@@ -0,0 +1,71 @@
+// 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:expect/expect.dart";
+
+import "implicit_new_prefix_constructor_generic_named_test.dart" as prefix;
+
+// Test that an omitted `new` is allowed for a generic constructor invocation.
+
+class C<T> {
+ final T x;
+ C(this.x); // Not const constructor.
+ const C.c(this.x); // Const constructor.
+
+ operator <(other) => this;
+ operator >(other) => other;
+ operator -() => this;
+
+ C<T> get self => this;
+ C<T> method() => self;
+}
+
+T id<T>(T x) => x;
+
+main() {
+ const cc = const C<int>.c(42); // Canonicalized.
+ var x = 42; // Avoid constant parameter.
+ var c0 = new prefix.C<int>.c(x); // Original syntax.
+
+ // Uses of `prefix.C<int>.c(x)` in various contexts.
+ var c1 = prefix.C<int>.c(x);
+ var c2 = [prefix.C<int>.c(x)][0];
+ var c3 = {prefix.C<int>.c(x): 0}.keys.first;
+ var c4 = {0: prefix.C<int>.c(x)}.values.first;
+ var c5 = id(prefix.C<int>.c(x));
+ var c6 = prefix.C<int>.c(x).self;
+ var c7 = prefix.C<int>.c(x).method();
+ var c8 = C(prefix.C<int>.c(x)).x;
+ var c9 = -prefix.C<int>.c(x);
+ var c10 = prefix.C<int>.c(x) < 9;
+ var c11 = C(null) > prefix.C<int>.c(x);
+ var c12 = (c10 == c11) ? null : prefix.C<int>.c(x);
+ var c13 = prefix.C<int>.c(x)..method();
+ var c14;
+ try {
+ throw prefix.C<int>.c(x);
+ } catch (e) {
+ c14 = e;
+ }
+
+ switch (prefix.C<int>.c(x)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (prefix.C<int>.c(x); false; prefix.C<int>.c(x), prefix.C<int>.c(x)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values =
+ [cc, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C<int>);
+ Expect.equals(42, (value as C<int>).x);
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_prefix_constructor_generic_test.dart b/tests/language/implicit_creation/implicit_new_prefix_constructor_generic_test.dart
new file mode 100644
index 0000000..3487d90
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_prefix_constructor_generic_test.dart
@@ -0,0 +1,87 @@
+// 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:expect/expect.dart";
+
+import "implicit_new_prefix_constructor_generic_test.dart" as prefix;
+
+// Test that an omitted `new` is allowed for a generic constructor invocation.
+
+class C<T> {
+ final T x;
+ C(this.x); // Not const constructor.
+ const C.c(this.x); // Const constructor.
+
+ operator <(other) => this;
+ operator >(other) => other;
+ operator -() => this;
+
+ C<T> get self => this;
+ C<T> method() => self;
+}
+
+T id<T>(T x) => x;
+
+main() {
+ const cc = const C<int>.c(42); // Canonicalized.
+
+ var c0 = new prefix.C<int>(42); // Original syntax.
+
+ // Uses of `prefix.C<int>(42)` in various contexts.
+ var c1 = prefix.C<int>(42);
+ var c2 = [prefix.C<int>(42)][0];
+ var c3 = {prefix.C<int>(42): 0}.keys.first;
+ var c4 = {0: prefix.C<int>(42)}.values.first;
+ var c5 = id(prefix.C<int>(42));
+ var c6 = prefix.C<int>(42).self;
+ var c7 = prefix.C<int>(42).method();
+ var c8 = C(prefix.C<int>(42)).x;
+ var c9 = -prefix.C<int>(42);
+ var c10 = prefix.C<int>(42) < 9;
+ var c11 = C(null) > prefix.C<int>(42);
+ var c12 = (c10 == c11) ? null : prefix.C<int>(42);
+ var c13 = prefix.C<int>(42)..method();
+ var c14;
+ try {
+ throw prefix.C<int>(42);
+ } catch (e) {
+ c14 = e;
+ }
+
+ switch (prefix.C<int>(42)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (prefix.C<int>(42); false; prefix.C<int>(42), prefix.C<int>(42)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values = [
+ cc,
+ c0,
+ c1,
+ c2,
+ c3,
+ c4,
+ c5,
+ c6,
+ c7,
+ c8,
+ c9,
+ c10,
+ c11,
+ c12,
+ c13,
+ c14
+ ];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C<int>);
+ Expect.equals(42, (value as C<int>).x);
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_prefix_constructor_named_test.dart b/tests/language/implicit_creation/implicit_new_prefix_constructor_named_test.dart
new file mode 100644
index 0000000..534e41d
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_prefix_constructor_named_test.dart
@@ -0,0 +1,88 @@
+// 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:expect/expect.dart";
+
+import "implicit_new_prefix_constructor_named_test.dart" as prefix;
+
+// Test that an omitted `new` is allowed for a non-generic class.
+
+class C {
+ final Object? x;
+ C(this.x); // Not const constructor.
+ const C.c(this.x); // Const constructor.
+
+ operator <(other) => this;
+ operator >(other) => other;
+ operator -() => this;
+
+ C get self => this;
+ C method() => self;
+}
+
+T id<T>(T x) => x;
+
+main() {
+ const cc = const C.c(42); // Canonicalized.
+ var x = 42; // Avoid constant parameter.
+ var c0 = new prefix.C.c(x); // Original syntax.
+
+ // Uses of `prefix.C.c(x)` in various contexts.
+ var c1 = prefix.C.c(x);
+ var c2 = [prefix.C.c(x)][0];
+ var c3 = {prefix.C.c(x): 0}.keys.first;
+ var c4 = {0: prefix.C.c(x)}.values.first;
+ var c5 = id(prefix.C.c(x));
+ var c6 = prefix.C.c(x).self;
+ var c7 = prefix.C.c(x).method();
+ var c8 = C(prefix.C.c(x)).x;
+ var c9 = -prefix.C.c(x);
+ var c10 = prefix.C.c(x) < 9;
+ var c11 = C(null) > prefix.C.c(x);
+ var c12 = (c10 == c11) ? null : prefix.C.c(x);
+ var c13 = prefix.C.c(x)..method();
+ var c14;
+ try {
+ throw prefix.C.c(x);
+ } catch (e) {
+ c14 = e;
+ }
+ Expect.isNotNull(c12);
+
+ switch (prefix.C.c(x)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (prefix.C.c(x); false; prefix.C.c(x), prefix.C.c(x)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values = [
+ cc,
+ c0,
+ c1,
+ c2,
+ c3,
+ c4,
+ c5,
+ c6,
+ c7,
+ c8,
+ c9,
+ c10,
+ c11,
+ c12,
+ c13,
+ c14
+ ];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C);
+ Expect.equals(42, (value as C).x);
+ }
+}
diff --git a/tests/language/implicit_creation/implicit_new_prefix_constructor_test.dart b/tests/language/implicit_creation/implicit_new_prefix_constructor_test.dart
new file mode 100644
index 0000000..4325430
--- /dev/null
+++ b/tests/language/implicit_creation/implicit_new_prefix_constructor_test.dart
@@ -0,0 +1,88 @@
+// 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:expect/expect.dart";
+
+import "implicit_new_prefix_constructor_test.dart" as prefix;
+
+// Test that an omitted `new` is allowed for a non-generic class.
+
+class C {
+ final Object? x;
+ C(this.x); // Not const constructor.
+ const C.c(this.x); // Const constructor.
+
+ operator <(other) => this;
+ operator >(other) => other;
+ operator -() => this;
+
+ C get self => this;
+ C method() => self;
+}
+
+T id<T>(T x) => x;
+
+main() {
+ const cc = const C.c(42); // Canonicalized.
+
+ var c0 = new prefix.C(42); // Original syntax.
+
+ // Uses of `prefix.C(42)` in various contexts.
+ var c1 = prefix.C(42);
+ var c2 = [prefix.C(42)][0];
+ var c3 = {prefix.C(42): 0}.keys.first;
+ var c4 = {0: prefix.C(42)}.values.first;
+ var c5 = id(prefix.C(42));
+ var c6 = prefix.C(42).self;
+ var c7 = prefix.C(42).method();
+ var c8 = C(prefix.C(42)).x;
+ var c9 = -prefix.C(42);
+ var c10 = prefix.C(42) < 9;
+ var c11 = C(null) > prefix.C(42);
+ var c12 = (c10 == c11) ? null : prefix.C(42);
+ var c13 = prefix.C(42)..method();
+ var c14;
+ try {
+ throw prefix.C(42);
+ } catch (e) {
+ c14 = e;
+ }
+ Expect.isNotNull(c12);
+
+ switch (prefix.C(42)) {
+ case cc:
+ Expect.fail("Should not be const");
+ break;
+ default:
+ // Success.
+ }
+
+ for (prefix.C(42); false; prefix.C(42), prefix.C(42)) {
+ Expect.fail("Unreachable");
+ }
+
+ var values = [
+ cc,
+ c0,
+ c1,
+ c2,
+ c3,
+ c4,
+ c5,
+ c6,
+ c7,
+ c8,
+ c9,
+ c10,
+ c11,
+ c12,
+ c13,
+ c14
+ ];
+ Expect.allDistinct(values); // Non of them create constants.
+ for (var value in values) {
+ Expect.isTrue(value is C);
+ Expect.equals(42, (value as C).x);
+ }
+}
diff --git a/tests/language/nnbd/subtyping/regress41939_test.dart b/tests/language/nnbd/subtyping/regress41939_test.dart
new file mode 100644
index 0000000..fd40999
--- /dev/null
+++ b/tests/language/nnbd/subtyping/regress41939_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// Requirements=nnbd-strong
+
+// Regression test for https://github.com/dart-lang/sdk/issues/41939
+
+void checkme0<T>(T? t) {}
+void checkme1<T extends dynamic>(T? t) {}
+void checkme2<T extends Object?>(T? t) {}
+void checkme3<T extends int>(T? t) {} //# 01: ok
+
+typedef void Test<T>(T? t);
+
+main() {
+ Test<int> t0 = checkme0;
+ Test<int> t1 = checkme1;
+ Test<int> t2 = checkme2;
+ Test<int> t3 = checkme3; //# 01: continued
+}
diff --git a/tests/language/regress/regress41890_test.dart b/tests/language/regress/regress41890_test.dart
index c23e221..86e43a7 100644
--- a/tests/language/regress/regress41890_test.dart
+++ b/tests/language/regress/regress41890_test.dart
@@ -34,16 +34,6 @@
String foo3(String s, {int opt1 = 0, required int req1}) => '$s $req1 $opt1';
Never foo4() => throw 'never';
-// TODO(sra): Use 'isStrongMode' from package:expect.
-final bool strong = () {
- try {
- int i = null as dynamic;
- return false;
- } catch (e) {
- return true;
- }
-}();
-
void test() {
var items = [foo1, foo2, foo3, foo4, Thingy(), Generic<F1>()];
@@ -52,8 +42,9 @@
for (int i = 0; i < items.length; i++) {
var item = items[i];
String code = answers[i];
- bool expected =
- code == 'T' || (code == 'S' && strong) || (code == 'W' && !strong);
+ bool expected = code == 'T' ||
+ (code == 'S' && isStrongMode) ||
+ (code == 'W' && isWeakMode);
Expect.equals(expected, predicate(item), "$predicate '$code' $item");
}
}
diff --git a/tests/lib/async/syncstar_mixed_iterators_test.dart b/tests/lib/async/syncstar_mixed_iterators_test.dart
new file mode 100644
index 0000000..2b2ecf1
--- /dev/null
+++ b/tests/lib/async/syncstar_mixed_iterators_test.dart
@@ -0,0 +1,34 @@
+// 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.
+//
+// Test that sync* correctly iterates through nested iterators of both
+// the internal sync* transform _SyncIterable and generic Iterable types.
+
+import "package:expect/expect.dart";
+
+Iterable<int> outerSyncStar() sync* {
+ yield 1;
+ // _SyncIterable<int>:
+ yield* innerSyncStar();
+ yield 4;
+ // Generic Iterable<int>:
+ yield* [5, 6];
+ //
+ yield* emptySyncStar();
+ yield 7;
+}
+
+Iterable<int> innerSyncStar() sync* {
+ yield 2;
+ yield* [];
+ yield* [3];
+}
+
+Iterable<int> emptySyncStar() sync* {
+ yield* [];
+}
+
+main() {
+ Expect.listEquals([1, 2, 3, 4, 5, 6, 7], [...outerSyncStar()]);
+}
diff --git a/tests/standalone/io/http_client_connect_test.dart b/tests/standalone/io/http_client_connect_test.dart
index 79351cd..698a9f6 100644
--- a/tests/standalone/io/http_client_connect_test.dart
+++ b/tests/standalone/io/http_client_connect_test.dart
@@ -285,6 +285,21 @@
});
}
+void testMaxConnectionsWithFailure() async {
+ var client = new HttpClient();
+ client.maxConnectionsPerHost = 1;
+ try {
+ await client.getUrl(Uri.parse('http://mydomainismissing'));
+ } catch (e) {}
+ try {
+ await client.getUrl(Uri.parse('http://mydomainismissing'));
+ } catch (e) {
+ return;
+ }
+
+ Expect.fail('second call should also fail');
+}
+
void main() {
testGetEmptyRequest();
testGetDataRequest();
@@ -300,4 +315,5 @@
testMaxConnectionsPerHost(1, 10);
testMaxConnectionsPerHost(5, 10);
testMaxConnectionsPerHost(10, 50);
+ testMaxConnectionsWithFailure();
}
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 8d41dd2..37f1aa4 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -667,6 +667,11 @@
headers.add('HEADER1', 'value 3', preserveHeaderCase: true);
headers.add('HEADER3', 'value 4', preserveHeaderCase: true);
+ BytesBuilder builder = BytesBuilder();
+ headers._build(builder);
+
+ Expect.isTrue(utf8.decode(builder.toBytes()).contains('HEADER1'));
+
bool myHeader1 = false;
bool myHeader2 = false;
bool myHeader3 = false;
diff --git a/tests/standalone/io/unix_socket_test.dart b/tests/standalone/io/unix_socket_test.dart
index 7c52777..7f91a9c 100644
--- a/tests/standalone/io/unix_socket_test.dart
+++ b/tests/standalone/io/unix_socket_test.dart
@@ -4,6 +4,7 @@
import 'dart:async';
import 'dart:io';
+import 'dart:convert';
import 'package:expect/expect.dart';
@@ -137,6 +138,31 @@
await server.close();
}
+Future testAbstractAddress() async {
+ if (!Platform.isLinux && !Platform.isAndroid) {
+ return;
+ }
+ var serverAddress =
+ InternetAddress('@temp.sock', type: InternetAddressType.unix);
+ ServerSocket server = await ServerSocket.bind(serverAddress, 0);
+ final completer = Completer<void>();
+ final content = 'random string';
+ server.listen((Socket socket) {
+ socket.listen((data) {
+ Expect.equals(content, utf8.decode(data));
+ socket.close();
+ server.close();
+ completer.complete();
+ });
+ });
+
+ Socket client = await Socket.connect(serverAddress, 0);
+ client.write(content);
+ await client.drain();
+ await client.close();
+ await completer.future;
+}
+
// Create socket in temp directory
Future withTempDir(String prefix, Future<void> test(Directory dir)) async {
var tempDir = Directory.systemTemp.createTempSync(prefix);
@@ -164,6 +190,7 @@
await withTempDir('unix_socket_test', (Directory dir) async {
await testSourceAddressConnect('${dir.path}');
});
+ await testAbstractAddress();
} catch (e) {
if (Platform.isMacOS || Platform.isLinux || Platform.isAndroid) {
Expect.fail("Unexpected exceptions are thrown");
diff --git a/tests/standalone_2/io/http_client_connect_test.dart b/tests/standalone_2/io/http_client_connect_test.dart
index 284c441d..4bd9d3a 100644
--- a/tests/standalone_2/io/http_client_connect_test.dart
+++ b/tests/standalone_2/io/http_client_connect_test.dart
@@ -283,6 +283,21 @@
});
}
+void testMaxConnectionsWithFailure() async {
+ var client = new HttpClient();
+ client.maxConnectionsPerHost = 1;
+ try {
+ await client.getUrl(Uri.parse('http://mydomainismissing'));
+ } catch (e) {}
+ try {
+ await client.getUrl(Uri.parse('http://mydomainismissing'));
+ } catch (e) {
+ return;
+ }
+
+ Expect.fail('second call should also fail');
+}
+
void main() {
testGetEmptyRequest();
testGetDataRequest();
@@ -298,4 +313,5 @@
testMaxConnectionsPerHost(1, 10);
testMaxConnectionsPerHost(5, 10);
testMaxConnectionsPerHost(10, 50);
+ testMaxConnectionsWithFailure();
}
diff --git a/tests/standalone_2/io/http_headers_test.dart b/tests/standalone_2/io/http_headers_test.dart
index 1f8e7e5..b8989f9 100644
--- a/tests/standalone_2/io/http_headers_test.dart
+++ b/tests/standalone_2/io/http_headers_test.dart
@@ -670,6 +670,11 @@
headers.add('HEADER1', 'value 3', preserveHeaderCase: true);
headers.add('HEADER3', 'value 4', preserveHeaderCase: true);
+ BytesBuilder builder = BytesBuilder();
+ headers._build(builder);
+
+ Expect.isTrue(utf8.decode(builder.toBytes()).contains('HEADER1'));
+
bool myHeader1 = false;
bool myHeader2 = false;
bool myHeader3 = false;
diff --git a/tests/standalone_2/io/unix_socket_test.dart b/tests/standalone_2/io/unix_socket_test.dart
index 7c52777..7f91a9c 100644
--- a/tests/standalone_2/io/unix_socket_test.dart
+++ b/tests/standalone_2/io/unix_socket_test.dart
@@ -4,6 +4,7 @@
import 'dart:async';
import 'dart:io';
+import 'dart:convert';
import 'package:expect/expect.dart';
@@ -137,6 +138,31 @@
await server.close();
}
+Future testAbstractAddress() async {
+ if (!Platform.isLinux && !Platform.isAndroid) {
+ return;
+ }
+ var serverAddress =
+ InternetAddress('@temp.sock', type: InternetAddressType.unix);
+ ServerSocket server = await ServerSocket.bind(serverAddress, 0);
+ final completer = Completer<void>();
+ final content = 'random string';
+ server.listen((Socket socket) {
+ socket.listen((data) {
+ Expect.equals(content, utf8.decode(data));
+ socket.close();
+ server.close();
+ completer.complete();
+ });
+ });
+
+ Socket client = await Socket.connect(serverAddress, 0);
+ client.write(content);
+ await client.drain();
+ await client.close();
+ await completer.future;
+}
+
// Create socket in temp directory
Future withTempDir(String prefix, Future<void> test(Directory dir)) async {
var tempDir = Directory.systemTemp.createTempSync(prefix);
@@ -164,6 +190,7 @@
await withTempDir('unix_socket_test', (Directory dir) async {
await testSourceAddressConnect('${dir.path}');
});
+ await testAbstractAddress();
} catch (e) {
if (Platform.isMacOS || Platform.isLinux || Platform.isAndroid) {
Expect.fail("Unexpected exceptions are thrown");
diff --git a/tools/VERSION b/tools/VERSION
index 6cc84a2..4756f9a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 9
PATCH 0
-PRERELEASE 10
+PRERELEASE 11
PRERELEASE_PATCH 0
ABI_VERSION 34
OLDEST_SUPPORTED_ABI_VERSION 34
diff --git a/tools/bots/flutter/compile_flutter.sh b/tools/bots/flutter/compile_flutter.sh
index a65a5c3..cf54870 100755
--- a/tools/bots/flutter/compile_flutter.sh
+++ b/tools/bots/flutter/compile_flutter.sh
@@ -8,16 +8,24 @@
set -e
prepareOnly=false
-if [ $# -eq 1 ]
-then
- if [ $1 = "--prepareOnly" ]
- then
- prepareOnly=true
- fi
-fi
-if $prepareOnly
-then
+REMAINING_ARGS=()
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --prepareOnly|--prepare-only|--prepare_only)
+ prepareOnly=true
+ shift
+ ;;
+ *)
+ REMAINING_ARGS+=("$1")
+ shift
+ ;;
+ esac
+done
+# Restore remaining arguments.
+set -- "${REMAINING_ARGS[@]}"
+
+if $prepareOnly; then
echo "Will prepare only!"
fi
@@ -26,8 +34,7 @@
sdk=$checkout/out/ReleaseX64/dart-sdk
tmpdir=$(mktemp -d)
cleanup() {
- if ! $prepareOnly
- then
+ if ! $prepareOnly; then
rm -rf "$tmpdir"
fi
}
@@ -35,7 +42,7 @@
pushd "$tmpdir"
git clone --single-branch -vv \
- https://dart.googlesource.com/external/github.com/flutter/flutter
+ https://dart.googlesource.com/external/github.com/flutter/flutter
pushd flutter
bin/flutter config --no-analytics
@@ -46,33 +53,65 @@
fi
bin/flutter update-packages
-popd
+popd # flutter
# Directly in temp directory again.
mkdir src
pushd src
git clone --single-branch --depth=1 -vv \
- https://dart.googlesource.com/external/github.com/flutter/engine flutter
+ https://dart.googlesource.com/external/github.com/flutter/engine flutter
mkdir third_party
pushd third_party
ln -s $checkout dart
-popd
-popd
+popd # third_party
+popd # src
./src/third_party/dart/tools/patches/flutter-engine/apply.sh || true
mkdir flutter_patched_sdk
-$checkout/tools/sdks/dart-sdk/bin/dart --packages=$checkout/.packages $checkout/pkg/front_end/tool/_fasta/compile_platform.dart dart:core -Ddart.vm.product=false -Ddart.developer.causal_async_stacks=true -Ddart.isVM=true --enable-experiment=non-nullable --nnbd-agnostic --single-root-scheme=org-dartlang-sdk --single-root-base=$checkout/ org-dartlang-sdk:///sdk_nnbd/lib/libraries.json vm_outline_strong.dill vm_platform_strong.dill vm_outline_strong.dill
-$checkout/tools/sdks/dart-sdk/bin/dart --packages=$checkout/.packages $checkout/pkg/front_end/tool/_fasta/compile_platform.dart --enable-experiment=non-nullable --nnbd-weak --target=flutter dart:core --single-root-scheme=org-dartlang-sdk --single-root-base=src org-dartlang-sdk:///flutter/lib/snapshot/libraries.json vm_outline_strong.dill flutter_patched_sdk/platform_strong.dill flutter_patched_sdk/outline_strong.dill
+$checkout/tools/sdks/dart-sdk/bin/dart \
+ --packages=$checkout/.packages \
+ $checkout/pkg/front_end/tool/_fasta/compile_platform.dart \
+ dart:core \
+ -Ddart.vm.product=false \
+ -Ddart.developer.causal_async_stacks=true \
+ -Ddart.isVM=true \
+ --enable-experiment=non-nullable \
+ --nnbd-agnostic \
+ --single-root-scheme=org-dartlang-sdk \
+ --single-root-base=$checkout/ \
+ org-dartlang-sdk:///sdk_nnbd/lib/libraries.json \
+ vm_outline_strong.dill \
+ vm_platform_strong.dill \
+ vm_outline_strong.dill
-popd
+$checkout/tools/sdks/dart-sdk/bin/dart \
+ --packages=$checkout/.packages \
+ $checkout/pkg/front_end/tool/_fasta/compile_platform.dart \
+ --enable-experiment=non-nullable \
+ --nnbd-weak \
+ --target=flutter \
+ dart:core \
+ --single-root-scheme=org-dartlang-sdk \
+ --single-root-base=src \
+ org-dartlang-sdk:///flutter/lib/snapshot/libraries.json \
+ vm_outline_strong.dill \
+ flutter_patched_sdk/platform_strong.dill \
+ flutter_patched_sdk/outline_strong.dill
-if $prepareOnly
-then
+popd # tmpdir
+
+if $prepareOnly; then
echo "Preparations complete!"
echo "Flutter is now in $tmpdir/flutter and the patched sdk in $tmpdir/flutter_patched_sdk"
echo "You can run the test with $dart --enable-asserts pkg/frontend_server/test/frontend_server_flutter.dart --flutterDir=$tmpdir/flutter --flutterPlatformDir=$tmpdir/flutter_patched_sdk"
else
- $dart --enable-asserts pkg/frontend_server/test/frontend_server_flutter_suite.dart -v --flutterDir=$tmpdir/flutter --flutterPlatformDir=$tmpdir/flutter_patched_sdk $@
+ $dart \
+ --enable-asserts \
+ pkg/frontend_server/test/frontend_server_flutter_suite.dart \
+ -v \
+ --flutterDir=$tmpdir/flutter \
+ --flutterPlatformDir=$tmpdir/flutter_patched_sdk \
+ $@
fi
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 9befd7c..4807cf8 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -1669,11 +1669,11 @@
return resultType
def _zeroArgs(self, argsNames):
- return 'JS("", "#.$NAME()", this)'
+ return 'JS("", "#.$JSNAME()", this)'
def _manyArgs(self, numberArgs, argsNames):
argsPound = "#" if numberArgs == 1 else ("#, " * numberArgs)[:-2]
- return ' JS("", "#.$NAME(%s)", this, %s)' % (argsPound, argsNames)
+ return ' JS("", "#.$JSNAME(%s)", this, %s)' % (argsPound, argsNames)
""" If argument conversionsMapToDictionary is a list first entry is argument
name and second entry signals if argument is optional (True). """
@@ -1787,6 +1787,7 @@
TYPE=promiseType,
PROMISE_CALL=promiseCall,
NAME=html_name,
+ JSNAME=info.declared_name,
PARAMS=info.ParametersAsDeclaration(self._NarrowInputType,
force_optional))
else:
diff --git a/tools/migration/lib/src/analyze.dart b/tools/migration/lib/src/analyze.dart
index f1f4c5e..25d1be6 100644
--- a/tools/migration/lib/src/analyze.dart
+++ b/tools/migration/lib/src/analyze.dart
@@ -105,6 +105,7 @@
var errors = _StaticError.parse(result.stderr as String);
var errorsByFile = <String, List<_StaticError>>{};
for (var error in errors) {
+ if (error.code.startsWith("HINT.")) continue;
errorsByFile.putIfAbsent(error.file, () => []).add(error);
}
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index fd3acc8..6c50302 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -166,13 +166,6 @@
]
}
-group("dartdevc_test_kernel_local") {
- deps = [
- ":dartdevc_kernel_sdk",
- ":dartdevc_test_kernel_pkg",
- ]
-}
-
create_timestamp_file("dartdevc_files_stamp") {
path = rebase_path("../../pkg/dev_compiler/lib")
output = "$target_gen_dir/dartdevc_files.stamp"