[cfe] Use required type for lookup in map/list pattern

The members used to match a map/list pattern should be pulled from the required type and not the matched type in order to avoid wrongfully using extension type members.

Closes #63315

Change-Id: Idccc19fad1a3fc5cd1ecac2cfdb0ef0ee431d50f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/502700
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther
2026-05-12 05:08:33 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 9af6bae2e1
commit 756dd1c665
28 changed files with 1177 additions and 459 deletions
@@ -15004,77 +15004,70 @@ class InferenceVisitorImpl extends InferenceVisitorBase
requiredType: requiredType,
);
DartType lookupType;
if (node.needsCheck) {
lookupType = node.lookupType = requiredType;
node.lookupType = requiredType;
} else {
lookupType = node.lookupType = matchedValueType;
node.lookupType = matchedValueType;
}
ObjectAccessTarget lengthTarget = findInterfaceMember(
lookupType,
requiredType,
lengthName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
DartType lengthType;
if (lengthTarget.isNever) {
lengthType = const NeverType.nonNullable();
node.isNeverPattern = true;
} else {
assert(lengthTarget.isInstanceMember);
assert(lengthTarget.isInstanceMember);
lengthType = node.lengthType = lengthTarget.getGetterType(this);
node.lengthTarget = lengthTarget.classMember!;
DartType lengthType = node.lengthType = lengthTarget.getGetterType(this);
node.lengthTarget = lengthTarget.classMember!;
ObjectAccessTarget sublistInvokeTarget = findInterfaceMember(
lookupType,
sublistName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(sublistInvokeTarget.isInstanceMember);
ObjectAccessTarget sublistInvokeTarget = findInterfaceMember(
requiredType,
sublistName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(sublistInvokeTarget.isInstanceMember);
node.sublistTarget = sublistInvokeTarget.classMember as Procedure;
node.sublistType = sublistInvokeTarget
.getFunctionType(this)
.sublistFunctionType;
node.sublistTarget = sublistInvokeTarget.classMember as Procedure;
node.sublistType = sublistInvokeTarget
.getFunctionType(this)
.sublistFunctionType;
ObjectAccessTarget minusTarget = findInterfaceMember(
ObjectAccessTarget minusTarget = findInterfaceMember(
lengthType,
minusName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(minusTarget.isInstanceMember);
assert(minusTarget.isSpecialCasedBinaryOperator(this));
node.minusTarget = minusTarget.classMember as Procedure;
node.minusType = replaceReturnType(
minusTarget.getFunctionType(this).minusFunctionType,
typeSchemaEnvironment.getTypeOfSpecialCasedBinaryOperator(
lengthType,
minusName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(minusTarget.isInstanceMember);
assert(minusTarget.isSpecialCasedBinaryOperator(this));
coreTypes.intNonNullableRawType,
),
);
node.minusTarget = minusTarget.classMember as Procedure;
node.minusType = replaceReturnType(
minusTarget.getFunctionType(this).minusFunctionType,
typeSchemaEnvironment.getTypeOfSpecialCasedBinaryOperator(
lengthType,
coreTypes.intNonNullableRawType,
),
);
ObjectAccessTarget indexGetTarget = findInterfaceMember(
requiredType,
indexGetName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(indexGetTarget.isInstanceMember);
ObjectAccessTarget indexGetTarget = findInterfaceMember(
lookupType,
indexGetName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(indexGetTarget.isInstanceMember);
node.indexGetTarget = indexGetTarget.classMember as Procedure;
node.indexGetType = indexGetTarget
.getFunctionType(this)
.indexGetFunctionType;
}
node.indexGetTarget = indexGetTarget.classMember as Procedure;
node.indexGetType = indexGetTarget
.getFunctionType(this)
.indexGetFunctionType;
for (Pattern pattern in node.patterns) {
if (pattern is RestPattern) {
@@ -15083,52 +15076,50 @@ class InferenceVisitorImpl extends InferenceVisitorBase
}
}
if (!node.isNeverPattern) {
if (node.hasRestPattern) {
ObjectAccessTarget greaterThanOrEqualTarget = findInterfaceMember(
lengthType,
greaterThanOrEqualsName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(greaterThanOrEqualTarget.isInstanceMember);
if (node.hasRestPattern) {
ObjectAccessTarget greaterThanOrEqualTarget = findInterfaceMember(
lengthType,
greaterThanOrEqualsName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(greaterThanOrEqualTarget.isInstanceMember);
node.lengthCheckTarget =
greaterThanOrEqualTarget.classMember as Procedure;
node.lengthCheckType = greaterThanOrEqualTarget
.getFunctionType(this)
.greaterThanOrEqualsFunctionType;
} else if (node.patterns.isEmpty) {
ObjectAccessTarget lessThanOrEqualsInvokeTarget = findInterfaceMember(
lengthType,
lessThanOrEqualsName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(lessThanOrEqualsInvokeTarget.isInstanceMember);
node.lengthCheckTarget =
greaterThanOrEqualTarget.classMember as Procedure;
node.lengthCheckType = greaterThanOrEqualTarget
.getFunctionType(this)
.greaterThanOrEqualsFunctionType;
} else if (node.patterns.isEmpty) {
ObjectAccessTarget lessThanOrEqualsInvokeTarget = findInterfaceMember(
lengthType,
lessThanOrEqualsName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(lessThanOrEqualsInvokeTarget.isInstanceMember);
node.lengthCheckTarget =
lessThanOrEqualsInvokeTarget.classMember as Procedure;
node.lengthCheckType = lessThanOrEqualsInvokeTarget
.getFunctionType(this)
.lessThanOrEqualsFunctionType;
} else {
ObjectAccessTarget equalsInvokeTarget = findInterfaceMember(
lengthType,
equalsName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(equalsInvokeTarget.isInstanceMember);
node.lengthCheckTarget =
lessThanOrEqualsInvokeTarget.classMember as Procedure;
node.lengthCheckType = lessThanOrEqualsInvokeTarget
.getFunctionType(this)
.lessThanOrEqualsFunctionType;
} else {
ObjectAccessTarget equalsInvokeTarget = findInterfaceMember(
lengthType,
equalsName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(equalsInvokeTarget.isInstanceMember);
node.lengthCheckTarget = equalsInvokeTarget.classMember as Procedure;
node.lengthCheckType = equalsInvokeTarget
.getFunctionType(this)
.equalsFunctionType;
}
node.lengthCheckTarget = equalsInvokeTarget.classMember as Procedure;
node.lengthCheckType = equalsInvokeTarget
.getFunctionType(this)
.equalsFunctionType;
}
pushRewrite(replacement ?? node);
@@ -15583,44 +15574,40 @@ class InferenceVisitorImpl extends InferenceVisitorBase
requiredType: requiredType,
);
DartType lookupType;
if (node.needsCheck) {
lookupType = node.lookupType = requiredType;
node.lookupType = requiredType;
} else {
lookupType = node.lookupType = matchedValueType;
node.lookupType = matchedValueType;
}
ObjectAccessTarget containsKeyTarget = findInterfaceMember(
lookupType,
requiredType,
containsKeyName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
if (containsKeyTarget.isNever) {
node.isNeverPattern = true;
} else {
assert(containsKeyTarget.isInstanceMember);
node.containsKeyTarget = containsKeyTarget.classMember as Procedure;
node.containsKeyType = containsKeyTarget
.getFunctionType(this)
.containsKeyFunctionType;
assert(containsKeyTarget.isInstanceMember);
ObjectAccessTarget indexGetTarget = findInterfaceMember(
lookupType,
indexGetName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(indexGetTarget.isInstanceMember);
node.containsKeyTarget = containsKeyTarget.classMember as Procedure;
node.containsKeyType = containsKeyTarget
.getFunctionType(this)
.containsKeyFunctionType;
node.indexGetTarget = indexGetTarget.classMember as Procedure;
node.indexGetType = indexGetTarget
.getFunctionType(this)
.indexGetFunctionType;
}
ObjectAccessTarget indexGetTarget = findInterfaceMember(
requiredType,
indexGetName,
node.fileOffset,
includeExtensionMethods: true,
isSetter: false,
);
assert(indexGetTarget.isInstanceMember);
node.indexGetTarget = indexGetTarget.classMember as Procedure;
node.indexGetType = indexGetTarget
.getFunctionType(this)
.indexGetFunctionType;
assert(
checkStack(node, stackBase, [
@@ -119,221 +119,212 @@ class MatchingExpressionVisitor
ListPattern node,
CacheableExpression matchedExpression,
) {
if (node.isNeverPattern) {
return matchedExpression;
matchedExpression = matchedExpression.promote(node.matchedValueType!);
CacheableExpression? isExpression;
CacheableExpression typedMatchedExpression;
if (node.needsCheck) {
isExpression = matchingCache.createIsExpression(
matchedExpression,
node.requiredType!,
fileOffset: node.fileOffset,
);
typedMatchedExpression = new PromotedCacheableExpression(
matchedExpression,
node.requiredType!,
);
} else {
matchedExpression = matchedExpression.promote(node.matchedValueType!);
typedMatchedExpression = matchedExpression;
}
CacheableExpression? isExpression;
CacheableExpression typedMatchedExpression;
if (node.needsCheck) {
isExpression = matchingCache.createIsExpression(
matchedExpression,
node.requiredType!,
fileOffset: node.fileOffset,
);
typedMatchedExpression = new PromotedCacheableExpression(
matchedExpression,
node.requiredType!,
);
} else {
typedMatchedExpression = matchedExpression;
}
CacheableExpression lengthGet = matchingCache.createPropertyGetExpression(
CacheableExpression lengthGet = matchingCache.createPropertyGetExpression(
typedMatchedExpression,
lengthName.text,
new DelayedInstanceGet(
typedMatchedExpression,
lengthName.text,
new DelayedInstanceGet(
typedMatchedExpression,
node.lengthTarget,
node.lengthType!,
node.lengthTarget,
node.lengthType!,
fileOffset: node.fileOffset,
),
fileOffset: node.fileOffset,
);
CacheableExpression? lengthCheck;
if (node.hasRestPattern) {
int minLength = node.patterns.length - 1;
if (minLength > 0) {
CacheableExpression constExpression = matchingCache.createIntConstant(
minLength,
fileOffset: node.fileOffset,
),
);
lengthCheck = matchingCache.createComparisonExpression(
lengthGet,
greaterThanOrEqualsName.text,
constExpression,
new DelayedInstanceInvocation(
lengthGet,
node.lengthCheckTarget,
node.lengthCheckType!,
[constExpression],
fileOffset: node.fileOffset,
),
fileOffset: node.fileOffset,
);
}
} else {
int length = node.patterns.length;
CacheableExpression constExpression = matchingCache.createIntConstant(
length,
fileOffset: node.fileOffset,
);
CacheableExpression? lengthCheck;
if (node.hasRestPattern) {
int minLength = node.patterns.length - 1;
if (minLength > 0) {
CacheableExpression constExpression = matchingCache.createIntConstant(
minLength,
if (length == 0) {
lengthCheck = matchingCache.createComparisonExpression(
lengthGet,
lessThanOrEqualsName.text,
constExpression,
new DelayedInstanceInvocation(
lengthGet,
node.lengthCheckTarget,
node.lengthCheckType!,
[constExpression],
fileOffset: node.fileOffset,
),
fileOffset: node.fileOffset,
);
} else {
lengthCheck = matchingCache.createEqualsExpression(
lengthGet,
constExpression,
new DelayedEqualsExpression(
lengthGet,
constExpression,
node.lengthCheckTarget,
node.lengthCheckType!,
fileOffset: node.fileOffset,
),
fileOffset: node.fileOffset,
);
}
}
DelayedExpression? matchingExpression;
if (isExpression != null && lengthCheck != null) {
matchingExpression = matchingCache.createAndExpression(
isExpression,
lengthCheck,
fileOffset: node.fileOffset,
);
} else if (isExpression != null) {
matchingExpression = isExpression;
} else if (lengthCheck != null) {
matchingExpression = lengthCheck;
}
bool hasSeenRestPattern = false;
for (int i = 0; i < node.patterns.length; i++) {
CacheableExpression elementExpression;
Pattern elementPattern = node.patterns[i];
if (elementPattern is RestPattern) {
hasSeenRestPattern = true;
Pattern? subPattern = elementPattern.subPattern;
if (subPattern == null) {
continue;
}
int nextIndex = i + 1;
int headSize = i;
int tailSize = node.patterns.length - nextIndex;
DelayedExpression expression;
if (tailSize > 0) {
expression = new DelayedInstanceInvocation(
typedMatchedExpression,
node.sublistTarget,
node.sublistType!,
[
new IntegerExpression(headSize, fileOffset: node.fileOffset),
new DelayedInstanceInvocation(
lengthGet,
node.minusTarget,
node.minusType!,
[new IntegerExpression(tailSize, fileOffset: node.fileOffset)],
fileOffset: node.fileOffset,
),
],
fileOffset: node.fileOffset,
);
lengthCheck = matchingCache.createComparisonExpression(
lengthGet,
greaterThanOrEqualsName.text,
constExpression,
new DelayedInstanceInvocation(
lengthGet,
node.lengthCheckTarget,
node.lengthCheckType!,
[constExpression],
fileOffset: node.fileOffset,
),
} else {
expression = new DelayedInstanceInvocation(
typedMatchedExpression,
node.sublistTarget,
node.sublistType!,
[new IntegerExpression(headSize, fileOffset: node.fileOffset)],
fileOffset: node.fileOffset,
);
}
} else {
int length = node.patterns.length;
CacheableExpression constExpression = matchingCache.createIntConstant(
length,
elementExpression = matchingCache.createSublistExpression(
typedMatchedExpression,
lengthGet,
headSize,
tailSize,
expression,
fileOffset: node.fileOffset,
);
if (length == 0) {
lengthCheck = matchingCache.createComparisonExpression(
lengthGet,
lessThanOrEqualsName.text,
constExpression,
} else {
if (!hasSeenRestPattern) {
int index = i;
elementExpression = matchingCache.createHeadIndexExpression(
typedMatchedExpression,
index,
new DelayedInstanceInvocation(
lengthGet,
node.lengthCheckTarget,
node.lengthCheckType!,
[constExpression],
typedMatchedExpression,
node.indexGetTarget,
node.indexGetType!,
[new IntegerExpression(index, fileOffset: node.fileOffset)],
fileOffset: node.fileOffset,
),
fileOffset: node.fileOffset,
);
} else {
lengthCheck = matchingCache.createEqualsExpression(
int index = node.patterns.length - i;
elementExpression = matchingCache.createTailIndexExpression(
typedMatchedExpression,
lengthGet,
constExpression,
new DelayedEqualsExpression(
lengthGet,
constExpression,
node.lengthCheckTarget,
node.lengthCheckType!,
fileOffset: node.fileOffset,
),
fileOffset: node.fileOffset,
);
}
}
DelayedExpression? matchingExpression;
if (isExpression != null && lengthCheck != null) {
matchingExpression = matchingCache.createAndExpression(
isExpression,
lengthCheck,
fileOffset: node.fileOffset,
);
} else if (isExpression != null) {
matchingExpression = isExpression;
} else if (lengthCheck != null) {
matchingExpression = lengthCheck;
}
bool hasSeenRestPattern = false;
for (int i = 0; i < node.patterns.length; i++) {
CacheableExpression elementExpression;
Pattern elementPattern = node.patterns[i];
if (elementPattern is RestPattern) {
hasSeenRestPattern = true;
Pattern? subPattern = elementPattern.subPattern;
if (subPattern == null) {
continue;
}
int nextIndex = i + 1;
int headSize = i;
int tailSize = node.patterns.length - nextIndex;
DelayedExpression expression;
if (tailSize > 0) {
expression = new DelayedInstanceInvocation(
index,
new DelayedInstanceInvocation(
typedMatchedExpression,
node.sublistTarget,
node.sublistType!,
node.indexGetTarget,
node.indexGetType!,
[
new IntegerExpression(headSize, fileOffset: node.fileOffset),
new DelayedInstanceInvocation(
lengthGet,
node.minusTarget,
node.minusType!,
[
new IntegerExpression(
tailSize,
fileOffset: node.fileOffset,
),
],
[new IntegerExpression(index, fileOffset: node.fileOffset)],
fileOffset: node.fileOffset,
),
],
fileOffset: node.fileOffset,
);
} else {
expression = new DelayedInstanceInvocation(
typedMatchedExpression,
node.sublistTarget,
node.sublistType!,
[new IntegerExpression(headSize, fileOffset: node.fileOffset)],
fileOffset: node.fileOffset,
);
}
elementExpression = matchingCache.createSublistExpression(
typedMatchedExpression,
lengthGet,
headSize,
tailSize,
expression,
),
fileOffset: node.fileOffset,
);
} else {
if (!hasSeenRestPattern) {
int index = i;
elementExpression = matchingCache.createHeadIndexExpression(
typedMatchedExpression,
index,
new DelayedInstanceInvocation(
typedMatchedExpression,
node.indexGetTarget,
node.indexGetType!,
[new IntegerExpression(index, fileOffset: node.fileOffset)],
fileOffset: node.fileOffset,
),
fileOffset: node.fileOffset,
);
} else {
int index = node.patterns.length - i;
elementExpression = matchingCache.createTailIndexExpression(
typedMatchedExpression,
lengthGet,
index,
new DelayedInstanceInvocation(
typedMatchedExpression,
node.indexGetTarget,
node.indexGetType!,
[
new DelayedInstanceInvocation(
lengthGet,
node.minusTarget,
node.minusType!,
[new IntegerExpression(index, fileOffset: node.fileOffset)],
fileOffset: node.fileOffset,
),
],
fileOffset: node.fileOffset,
),
fileOffset: node.fileOffset,
);
}
}
DelayedExpression elementMatcher = visitPattern(
elementPattern,
elementExpression,
);
matchingExpression = DelayedAndExpression.merge(
matchingExpression,
elementMatcher,
fileOffset: node.fileOffset,
);
}
return matchingExpression ??
new BooleanExpression(true, fileOffset: node.fileOffset);
DelayedExpression elementMatcher = visitPattern(
elementPattern,
elementExpression,
);
matchingExpression = DelayedAndExpression.merge(
matchingExpression,
elementMatcher,
fileOffset: node.fileOffset,
);
}
return matchingExpression ??
new BooleanExpression(true, fileOffset: node.fileOffset);
}
@override
@@ -341,123 +332,118 @@ class MatchingExpressionVisitor
MapPattern node,
CacheableExpression matchedExpression,
) {
if (node.isNeverPattern) {
return matchedExpression;
} else {
matchedExpression = matchedExpression.promote(node.matchedValueType!);
matchedExpression = matchedExpression.promote(node.matchedValueType!);
CacheableExpression? isExpression;
CacheableExpression typedMatchedExpression;
if (node.needsCheck) {
isExpression = matchingCache.createIsExpression(
matchedExpression,
node.requiredType!,
fileOffset: node.fileOffset,
);
typedMatchedExpression = new PromotedCacheableExpression(
matchedExpression,
node.requiredType!,
);
} else {
typedMatchedExpression = matchedExpression;
}
DelayedExpression? matchingExpression;
if (isExpression != null) {
matchingExpression = isExpression;
}
InterfaceType requiredType = node.requiredType as InterfaceType;
assert(
requiredType.classNode == coreTypes.mapClass &&
requiredType.typeArguments.length == 2,
CacheableExpression? isExpression;
CacheableExpression typedMatchedExpression;
if (node.needsCheck) {
isExpression = matchingCache.createIsExpression(
matchedExpression,
node.requiredType!,
fileOffset: node.fileOffset,
);
DartType valueType = requiredType.typeArguments[1];
for (MapPatternEntry entry in node.entries) {
if (entry is MapPatternRestEntry) continue;
CacheableExpression keyExpression = matchingCache
.createConstantExpression(
entry.keyValue!,
entry.keyType!,
fileOffset: entry.key.fileOffset,
);
CacheableExpression containsExpression = matchingCache
.createContainsKeyExpression(
typedMatchedExpression = new PromotedCacheableExpression(
matchedExpression,
node.requiredType!,
);
} else {
typedMatchedExpression = matchedExpression;
}
DelayedExpression? matchingExpression;
if (isExpression != null) {
matchingExpression = isExpression;
}
InterfaceType requiredType = node.requiredType as InterfaceType;
assert(
requiredType.classNode == coreTypes.mapClass &&
requiredType.typeArguments.length == 2,
);
DartType valueType = requiredType.typeArguments[1];
for (MapPatternEntry entry in node.entries) {
if (entry is MapPatternRestEntry) continue;
CacheableExpression keyExpression = matchingCache
.createConstantExpression(
entry.keyValue!,
entry.keyType!,
fileOffset: entry.key.fileOffset,
);
CacheableExpression containsExpression = matchingCache
.createContainsKeyExpression(
typedMatchedExpression,
keyExpression,
new DelayedInstanceInvocation(
typedMatchedExpression,
keyExpression,
new DelayedInstanceInvocation(
typedMatchedExpression,
node.containsKeyTarget,
node.containsKeyType!,
[keyExpression],
fileOffset: entry.fileOffset,
),
fileOffset: entry.fileOffset,
);
CacheableExpression valueExpression = matchingCache
.createIndexExpression(
typedMatchedExpression,
keyExpression,
new DelayedInstanceInvocation(
typedMatchedExpression,
node.indexGetTarget,
node.indexGetType!,
[keyExpression],
fileOffset: entry.fileOffset,
),
fileOffset: entry.fileOffset,
);
matchingExpression = DelayedAndExpression.merge(
matchingExpression,
new DelayedOrExpression(
new DelayedNullCheckExpression(
valueExpression,
fileOffset: entry.fileOffset,
),
new DelayedAndExpression(
new DelayedIsExpression(
new FixedExpression(
createNullLiteral(fileOffset: entry.fileOffset),
const NullType(),
),
valueType,
fileOffset: entry.fileOffset,
),
containsExpression,
node.containsKeyTarget,
node.containsKeyType!,
[keyExpression],
fileOffset: entry.fileOffset,
),
fileOffset: entry.fileOffset,
);
CacheableExpression valueExpression = matchingCache.createIndexExpression(
typedMatchedExpression,
keyExpression,
new DelayedInstanceInvocation(
typedMatchedExpression,
node.indexGetTarget,
node.indexGetType!,
[keyExpression],
fileOffset: entry.fileOffset,
),
fileOffset: entry.fileOffset,
);
matchingExpression = DelayedAndExpression.merge(
matchingExpression,
new DelayedOrExpression(
new DelayedNullCheckExpression(
valueExpression,
fileOffset: entry.fileOffset,
),
new DelayedAndExpression(
new DelayedIsExpression(
new FixedExpression(
createNullLiteral(fileOffset: entry.fileOffset),
const NullType(),
),
valueType,
fileOffset: entry.fileOffset,
),
containsExpression,
fileOffset: entry.fileOffset,
),
fileOffset: entry.fileOffset,
);
valueExpression = new PromotedCacheableExpression(
valueExpression,
valueType,
);
),
fileOffset: entry.fileOffset,
);
valueExpression = new PromotedCacheableExpression(
valueExpression,
valueType,
);
DelayedExpression subExpression = visitPattern(
entry.value,
valueExpression,
DelayedExpression subExpression = visitPattern(
entry.value,
valueExpression,
);
if (!subExpression.uses(valueExpression)) {
// Ensure that we perform the lookup even if we don't use the result.
matchingExpression = DelayedAndExpression.merge(
matchingExpression,
new EffectExpression(valueExpression, subExpression),
fileOffset: node.fileOffset,
);
} else {
matchingExpression = DelayedAndExpression.merge(
matchingExpression,
subExpression,
fileOffset: node.fileOffset,
);
if (!subExpression.uses(valueExpression)) {
// Ensure that we perform the lookup even if we don't use the result.
matchingExpression = DelayedAndExpression.merge(
matchingExpression,
new EffectExpression(valueExpression, subExpression),
fileOffset: node.fileOffset,
);
} else {
matchingExpression = DelayedAndExpression.merge(
matchingExpression,
subExpression,
fileOffset: node.fileOffset,
);
}
}
// Coverage-ignore(suite): Not run.
return matchingExpression ??
new BooleanExpression(true, fileOffset: node.fileOffset);
}
// Coverage-ignore(suite): Not run.
return matchingExpression ??
new BooleanExpression(true, fileOffset: node.fileOffset);
}
@override
@@ -7,7 +7,7 @@ static method test(core::List<core::int> list) → dynamic {
{
final synthesized core::List<core::int> #0#0 = list;
final const synthesized core::int #0#3 = #C1;
if(!(let final dynamic #t1 = #0#0 as core::List<core::int> in (#0#0 as core::List<core::int>).{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t2 = v = (#0#0 as core::List<core::int>).{core::List::[]}(0){(core::int) → core::int} in true)))
if(!(let final dynamic #t1 = #0#0 as core::List<core::int> in (#0#0 as core::List<core::int>).{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t2 = v = (#0#0 as core::List<core::int>).{core::List::[]}(0){(core::int) → core::num} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(42, v);
@@ -7,7 +7,7 @@ static method test(core::List<core::int> list) → dynamic {
{
final synthesized core::List<core::int> #0#0 = list;
final const synthesized core::int #0#3 = #C1;
if(!(let final dynamic #t1 = #0#0 as core::List<core::int> in (#0#0 as core::List<core::int>).{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t2 = v = (#0#0 as core::List<core::int>).{core::List::[]}(0){(core::int) → core::int} in true)))
if(!(let final dynamic #t1 = #0#0 as core::List<core::int> in (#0#0 as core::List<core::int>).{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t2 = v = (#0#0 as core::List<core::int>).{core::List::[]}(0){(core::int) → core::num} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(42, v);
@@ -7,7 +7,7 @@ static method test(core::List<core::int> list) → dynamic {
{
final synthesized core::List<core::int> #0#0 = list;
final const synthesized core::int #0#3 = #C1;
if(!(let final dynamic #t1 = #0#0 as{Unchecked} core::List<core::int> in (#0#0 as{Unchecked} core::List<core::int>).{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t2 = v = (#0#0 as{Unchecked} core::List<core::int>).{core::List::[]}(0){(core::int) → core::int} in true)))
if(!(let final dynamic #t1 = #0#0 as{Unchecked} core::List<core::int> in (#0#0 as{Unchecked} core::List<core::int>).{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t2 = v = (#0#0 as{Unchecked} core::List<core::int>).{core::List::[]}(0){(core::int) → core::num} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(42, v);
@@ -6,7 +6,8 @@ static method main() → void {
try {
{
final synthesized Never #0#0 = throw "A";
if(!#0#0)
final const synthesized core::int #0#2 = #C1;
if(!#0#0.{core::List::length}{core::int}.{core::num::<=}(#C1){(core::num) → core::bool})
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -16,3 +17,7 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 0
}
@@ -6,7 +6,8 @@ static method main() → void {
try {
{
final synthesized Never #0#0 = throw "A";
if(!#0#0)
final const synthesized core::int #0#2 = #C1;
if(!#0#0.{core::List::length}{core::int}.{core::num::<=}(#C1){(core::num) → core::bool})
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -16,3 +17,7 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 0
}
@@ -6,7 +6,8 @@ static method main() → void {
try {
{
final synthesized Never #0#0 = throw "A";
if(!#0#0)
final const synthesized core::int #0#2 = #C1;
if(!#0#0.{core::List::length}{core::int}.{core::num::<=}(#C1){(core::num) → core::bool})
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -16,3 +17,7 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 0
}
@@ -0,0 +1,54 @@
// Copyright (c) 2026, 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.
extension type JsonMap1<T>(Map<String, Object?> _)
implements Map<String, Object?> {
T operator [](String key) => _[key] as T;
}
void parseJson1(JsonMap1 map) {
if (map case {"key": "value"}) print("ok");
}
extension type JsonMap2<T>(Map<String, Object?> _)
implements Map<String, Object?> {
bool containsKey(String key) => _.containsKey(key);
}
void parseJson2(JsonMap2 map) {
if (map case {"key": "value"}) print("ok");
}
extension type JsonMap3<T>(Map<String, Object?> _)
implements Map<String, Object?> {
int get length => _.length;
}
void parseJson3(JsonMap3 map) {
if (map case {"key": "value"}) print("ok");
}
extension type JsonList1<T>(List<Object?> _) implements List<Object?> {
T operator [](int index) => _[index] as T;
}
void parseJson4(JsonList1 list) {
if (list case ["value"]) print("ok");
}
extension type JsonList2<T>(List<Object?> _) implements List<Object?> {
int get length => _.length;
}
void parseJson5(JsonList2 list) {
if (list case ["value"]) print("ok");
}
extension type JsonList3<T>(List<Object?> _) implements List<Object?> {
List<T> sublist(int start, [int? end]) => _.sublist(start, end).cast<T>();
}
void parseJson6(JsonList3 list) {
if (list case ["value"]) print("ok");
}
@@ -0,0 +1,161 @@
library;
import self as self;
import "dart:core" as core;
extension type JsonMap1<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
operator [] = self::JsonMap1|[];
constructor • = self::JsonMap1|constructor#;
constructor tearoff • = self::JsonMap1|constructor#_#new#tearOff;
}
extension type JsonMap2<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
method containsKey = self::JsonMap2|containsKey;
method tearoff containsKey = self::JsonMap2|get#containsKey;
constructor • = self::JsonMap2|constructor#;
constructor tearoff • = self::JsonMap2|constructor#_#new#tearOff;
}
extension type JsonMap3<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
get length = self::JsonMap3|get#length;
constructor • = self::JsonMap3|constructor#;
constructor tearoff • = self::JsonMap3|constructor#_#new#tearOff;
}
extension type JsonList1<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
operator [] = self::JsonList1|[];
constructor • = self::JsonList1|constructor#;
constructor tearoff • = self::JsonList1|constructor#_#new#tearOff;
}
extension type JsonList2<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
get length = self::JsonList2|get#length;
constructor • = self::JsonList2|constructor#;
constructor tearoff • = self::JsonList2|constructor#_#new#tearOff;
}
extension type JsonList3<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
method sublist = self::JsonList3|sublist;
method tearoff sublist = self::JsonList3|get#sublist;
constructor • = self::JsonList3|constructor#;
constructor tearoff • = self::JsonList3|constructor#_#new#tearOff;
}
static extension-type-member method JsonMap1|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc0#formal) → self::JsonMap1<self::JsonMap1|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap1<self::JsonMap1|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc0#formal;
return #this;
}
static extension-type-member synthetic method JsonMap1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc0#formal) → self::JsonMap1<self::JsonMap1|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap1|constructor#<self::JsonMap1|constructor#_#new#tearOff::T%>(_#wc0#formal);
static extension-type-member method JsonMap1|[]<T extends core::Object? = dynamic>(lowered final self::JsonMap1<self::JsonMap1|[]::T%> /* erasure=core::Map<core::String, core::Object?> */ #this, core::String key) → self::JsonMap1|[]::T%
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::[]}(key){(core::Object?) → core::Object?} as self::JsonMap1|[]::T%;
static method parseJson1(self::JsonMap1<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap1<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t1 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t2 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonMap2|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc1#formal) → self::JsonMap2<self::JsonMap2|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap2<self::JsonMap2|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc1#formal;
return #this;
}
static extension-type-member synthetic method JsonMap2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc1#formal) → self::JsonMap2<self::JsonMap2|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap2|constructor#<self::JsonMap2|constructor#_#new#tearOff::T%>(_#wc1#formal);
static extension-type-member method JsonMap2|containsKey<T extends core::Object? = dynamic>(lowered final self::JsonMap2<self::JsonMap2|containsKey::T%> /* erasure=core::Map<core::String, core::Object?> */ #this, core::String key) → core::bool
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::containsKey}(key){(core::Object?) → core::bool};
static extension-type-member method JsonMap2|get#containsKey<T extends core::Object? = dynamic>(lowered final self::JsonMap2<self::JsonMap2|get#containsKey::T%> /* erasure=core::Map<core::String, core::Object?> */ #this) → (core::String) → core::bool
return (core::String key) → core::bool => self::JsonMap2|containsKey<self::JsonMap2|get#containsKey::T%>(#this, key);
static method parseJson2(self::JsonMap2<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap2<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t3 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t4 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonMap3|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc2#formal) → self::JsonMap3<self::JsonMap3|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap3<self::JsonMap3|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc2#formal;
return #this;
}
static extension-type-member synthetic method JsonMap3|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc2#formal) → self::JsonMap3<self::JsonMap3|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap3|constructor#<self::JsonMap3|constructor#_#new#tearOff::T%>(_#wc2#formal);
static extension-type-member method JsonMap3|get#length<T extends core::Object? = dynamic>(lowered final self::JsonMap3<self::JsonMap3|get#length::T%> /* erasure=core::Map<core::String, core::Object?> */ #this) → core::int
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::length}{core::int};
static method parseJson3(self::JsonMap3<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap3<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t5 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t6 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonList1|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc3#formal) → self::JsonList1<self::JsonList1|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList1<self::JsonList1|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc3#formal;
return #this;
}
static extension-type-member synthetic method JsonList1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc3#formal) → self::JsonList1<self::JsonList1|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList1|constructor#<self::JsonList1|constructor#_#new#tearOff::T%>(_#wc3#formal);
static extension-type-member method JsonList1|[]<T extends core::Object? = dynamic>(lowered final self::JsonList1<self::JsonList1|[]::T%> /* erasure=core::List<core::Object?> */ #this, core::int index) → self::JsonList1|[]::T%
return (#this as{Unchecked} core::List<core::Object?>).{core::List::[]}(index){(core::int) → core::Object?} as self::JsonList1|[]::T%;
static method parseJson4(self::JsonList1<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList1<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
static extension-type-member method JsonList2|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc4#formal) → self::JsonList2<self::JsonList2|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList2<self::JsonList2|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc4#formal;
return #this;
}
static extension-type-member synthetic method JsonList2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc4#formal) → self::JsonList2<self::JsonList2|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList2|constructor#<self::JsonList2|constructor#_#new#tearOff::T%>(_#wc4#formal);
static extension-type-member method JsonList2|get#length<T extends core::Object? = dynamic>(lowered final self::JsonList2<self::JsonList2|get#length::T%> /* erasure=core::List<core::Object?> */ #this) → core::int
return (#this as{Unchecked} core::List<core::Object?>).{core::List::length}{core::int};
static method parseJson5(self::JsonList2<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList2<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
static extension-type-member method JsonList3|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc5#formal) → self::JsonList3<self::JsonList3|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList3<self::JsonList3|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc5#formal;
return #this;
}
static extension-type-member synthetic method JsonList3|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc5#formal) → self::JsonList3<self::JsonList3|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList3|constructor#<self::JsonList3|constructor#_#new#tearOff::T%>(_#wc5#formal);
static extension-type-member method JsonList3|sublist<T extends core::Object? = dynamic>(lowered final self::JsonList3<self::JsonList3|sublist::T%> /* erasure=core::List<core::Object?> */ #this, core::int start, [core::int? end = #C4]) → core::List<self::JsonList3|sublist::T%>
return (#this as{Unchecked} core::List<core::Object?>).{core::List::sublist}(start, end){(core::int, [core::int?]) → core::List<core::Object?>}.{core::List::cast}<self::JsonList3|sublist::T%>(){() → core::List<self::JsonList3|sublist::T%>};
static extension-type-member method JsonList3|get#sublist<T extends core::Object? = dynamic>(lowered final self::JsonList3<self::JsonList3|get#sublist::T%> /* erasure=core::List<core::Object?> */ #this) → (core::int, [core::int?]) → core::List<self::JsonList3|get#sublist::T%>
return (core::int start, [core::int? end = #C4]) → core::List<self::JsonList3|get#sublist::T%> => self::JsonList3|sublist<self::JsonList3|get#sublist::T%>(#this, start, end);
static method parseJson6(self::JsonList3<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList3<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
constants {
#C1 = "key"
#C2 = "value"
#C3 = 1
#C4 = null
}
@@ -0,0 +1,161 @@
library;
import self as self;
import "dart:core" as core;
extension type JsonMap1<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
operator [] = self::JsonMap1|[];
constructor • = self::JsonMap1|constructor#;
constructor tearoff • = self::JsonMap1|constructor#_#new#tearOff;
}
extension type JsonMap2<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
method containsKey = self::JsonMap2|containsKey;
method tearoff containsKey = self::JsonMap2|get#containsKey;
constructor • = self::JsonMap2|constructor#;
constructor tearoff • = self::JsonMap2|constructor#_#new#tearOff;
}
extension type JsonMap3<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
get length = self::JsonMap3|get#length;
constructor • = self::JsonMap3|constructor#;
constructor tearoff • = self::JsonMap3|constructor#_#new#tearOff;
}
extension type JsonList1<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
operator [] = self::JsonList1|[];
constructor • = self::JsonList1|constructor#;
constructor tearoff • = self::JsonList1|constructor#_#new#tearOff;
}
extension type JsonList2<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
get length = self::JsonList2|get#length;
constructor • = self::JsonList2|constructor#;
constructor tearoff • = self::JsonList2|constructor#_#new#tearOff;
}
extension type JsonList3<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
method sublist = self::JsonList3|sublist;
method tearoff sublist = self::JsonList3|get#sublist;
constructor • = self::JsonList3|constructor#;
constructor tearoff • = self::JsonList3|constructor#_#new#tearOff;
}
static extension-type-member method JsonMap1|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc0#formal) → self::JsonMap1<self::JsonMap1|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap1<self::JsonMap1|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc0#formal;
return #this;
}
static extension-type-member synthetic method JsonMap1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc0#formal) → self::JsonMap1<self::JsonMap1|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap1|constructor#<self::JsonMap1|constructor#_#new#tearOff::T%>(_#wc0#formal);
static extension-type-member method JsonMap1|[]<T extends core::Object? = dynamic>(lowered final self::JsonMap1<self::JsonMap1|[]::T%> /* erasure=core::Map<core::String, core::Object?> */ #this, core::String key) → self::JsonMap1|[]::T%
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::[]}(key){(core::Object?) → core::Object?} as self::JsonMap1|[]::T%;
static method parseJson1(self::JsonMap1<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap1<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t1 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t2 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonMap2|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc1#formal) → self::JsonMap2<self::JsonMap2|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap2<self::JsonMap2|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc1#formal;
return #this;
}
static extension-type-member synthetic method JsonMap2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc1#formal) → self::JsonMap2<self::JsonMap2|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap2|constructor#<self::JsonMap2|constructor#_#new#tearOff::T%>(_#wc1#formal);
static extension-type-member method JsonMap2|containsKey<T extends core::Object? = dynamic>(lowered final self::JsonMap2<self::JsonMap2|containsKey::T%> /* erasure=core::Map<core::String, core::Object?> */ #this, core::String key) → core::bool
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::containsKey}(key){(core::Object?) → core::bool};
static extension-type-member method JsonMap2|get#containsKey<T extends core::Object? = dynamic>(lowered final self::JsonMap2<self::JsonMap2|get#containsKey::T%> /* erasure=core::Map<core::String, core::Object?> */ #this) → (core::String) → core::bool
return (core::String key) → core::bool => self::JsonMap2|containsKey<self::JsonMap2|get#containsKey::T%>(#this, key);
static method parseJson2(self::JsonMap2<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap2<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t3 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t4 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonMap3|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc2#formal) → self::JsonMap3<self::JsonMap3|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap3<self::JsonMap3|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc2#formal;
return #this;
}
static extension-type-member synthetic method JsonMap3|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc2#formal) → self::JsonMap3<self::JsonMap3|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap3|constructor#<self::JsonMap3|constructor#_#new#tearOff::T%>(_#wc2#formal);
static extension-type-member method JsonMap3|get#length<T extends core::Object? = dynamic>(lowered final self::JsonMap3<self::JsonMap3|get#length::T%> /* erasure=core::Map<core::String, core::Object?> */ #this) → core::int
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::length}{core::int};
static method parseJson3(self::JsonMap3<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap3<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t5 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t6 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonList1|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc3#formal) → self::JsonList1<self::JsonList1|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList1<self::JsonList1|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc3#formal;
return #this;
}
static extension-type-member synthetic method JsonList1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc3#formal) → self::JsonList1<self::JsonList1|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList1|constructor#<self::JsonList1|constructor#_#new#tearOff::T%>(_#wc3#formal);
static extension-type-member method JsonList1|[]<T extends core::Object? = dynamic>(lowered final self::JsonList1<self::JsonList1|[]::T%> /* erasure=core::List<core::Object?> */ #this, core::int index) → self::JsonList1|[]::T%
return (#this as{Unchecked} core::List<core::Object?>).{core::List::[]}(index){(core::int) → core::Object?} as self::JsonList1|[]::T%;
static method parseJson4(self::JsonList1<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList1<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
static extension-type-member method JsonList2|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc4#formal) → self::JsonList2<self::JsonList2|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList2<self::JsonList2|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc4#formal;
return #this;
}
static extension-type-member synthetic method JsonList2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc4#formal) → self::JsonList2<self::JsonList2|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList2|constructor#<self::JsonList2|constructor#_#new#tearOff::T%>(_#wc4#formal);
static extension-type-member method JsonList2|get#length<T extends core::Object? = dynamic>(lowered final self::JsonList2<self::JsonList2|get#length::T%> /* erasure=core::List<core::Object?> */ #this) → core::int
return (#this as{Unchecked} core::List<core::Object?>).{core::List::length}{core::int};
static method parseJson5(self::JsonList2<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList2<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
static extension-type-member method JsonList3|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc5#formal) → self::JsonList3<self::JsonList3|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList3<self::JsonList3|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc5#formal;
return #this;
}
static extension-type-member synthetic method JsonList3|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc5#formal) → self::JsonList3<self::JsonList3|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList3|constructor#<self::JsonList3|constructor#_#new#tearOff::T%>(_#wc5#formal);
static extension-type-member method JsonList3|sublist<T extends core::Object? = dynamic>(lowered final self::JsonList3<self::JsonList3|sublist::T%> /* erasure=core::List<core::Object?> */ #this, core::int start, [core::int? end = #C4]) → core::List<self::JsonList3|sublist::T%>
return (#this as{Unchecked} core::List<core::Object?>).{core::List::sublist}(start, end){(core::int, [core::int?]) → core::List<core::Object?>}.{core::List::cast}<self::JsonList3|sublist::T%>(){() → core::List<self::JsonList3|sublist::T%>};
static extension-type-member method JsonList3|get#sublist<T extends core::Object? = dynamic>(lowered final self::JsonList3<self::JsonList3|get#sublist::T%> /* erasure=core::List<core::Object?> */ #this) → (core::int, [core::int?]) → core::List<self::JsonList3|get#sublist::T%>
return (core::int start, [core::int? end = #C4]) → core::List<self::JsonList3|get#sublist::T%> => self::JsonList3|sublist<self::JsonList3|get#sublist::T%>(#this, start, end);
static method parseJson6(self::JsonList3<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList3<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
constants {
#C1 = "key"
#C2 = "value"
#C3 = 1
#C4 = null
}
@@ -0,0 +1,94 @@
library;
import self as self;
import "dart:core" as core;
extension type JsonMap1<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
operator [] = self::JsonMap1|[];
constructor • = self::JsonMap1|constructor#;
constructor tearoff • = self::JsonMap1|constructor#_#new#tearOff;
}
extension type JsonMap2<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
method containsKey = self::JsonMap2|containsKey;
method tearoff containsKey = self::JsonMap2|get#containsKey;
constructor • = self::JsonMap2|constructor#;
constructor tearoff • = self::JsonMap2|constructor#_#new#tearOff;
}
extension type JsonMap3<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
get length = self::JsonMap3|get#length;
constructor • = self::JsonMap3|constructor#;
constructor tearoff • = self::JsonMap3|constructor#_#new#tearOff;
}
extension type JsonList1<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
operator [] = self::JsonList1|[];
constructor • = self::JsonList1|constructor#;
constructor tearoff • = self::JsonList1|constructor#_#new#tearOff;
}
extension type JsonList2<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
get length = self::JsonList2|get#length;
constructor • = self::JsonList2|constructor#;
constructor tearoff • = self::JsonList2|constructor#_#new#tearOff;
}
extension type JsonList3<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
method sublist = self::JsonList3|sublist;
method tearoff sublist = self::JsonList3|get#sublist;
constructor • = self::JsonList3|constructor#;
constructor tearoff • = self::JsonList3|constructor#_#new#tearOff;
}
static extension-type-member method JsonMap1|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc0#formal) → self::JsonMap1<self::JsonMap1|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */
;
static extension-type-member synthetic method JsonMap1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc0#formal) → self::JsonMap1<self::JsonMap1|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap1|constructor#<self::JsonMap1|constructor#_#new#tearOff::T%>(_#wc0#formal);
static extension-type-member method JsonMap1|[]<T extends core::Object? = dynamic>(lowered final self::JsonMap1<self::JsonMap1|[]::T%> /* erasure=core::Map<core::String, core::Object?> */ #this, core::String key) → self::JsonMap1|[]::T%
;
static method parseJson1(self::JsonMap1<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void
;
static extension-type-member method JsonMap2|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc1#formal) → self::JsonMap2<self::JsonMap2|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */
;
static extension-type-member synthetic method JsonMap2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc1#formal) → self::JsonMap2<self::JsonMap2|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap2|constructor#<self::JsonMap2|constructor#_#new#tearOff::T%>(_#wc1#formal);
static extension-type-member method JsonMap2|containsKey<T extends core::Object? = dynamic>(lowered final self::JsonMap2<self::JsonMap2|containsKey::T%> /* erasure=core::Map<core::String, core::Object?> */ #this, core::String key) → core::bool
;
static extension-type-member method JsonMap2|get#containsKey<T extends core::Object? = dynamic>(lowered final self::JsonMap2<self::JsonMap2|get#containsKey::T%> /* erasure=core::Map<core::String, core::Object?> */ #this) → (core::String) → core::bool
return (core::String key) → core::bool => self::JsonMap2|containsKey<self::JsonMap2|get#containsKey::T%>(#this, key);
static method parseJson2(self::JsonMap2<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void
;
static extension-type-member method JsonMap3|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc2#formal) → self::JsonMap3<self::JsonMap3|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */
;
static extension-type-member synthetic method JsonMap3|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc2#formal) → self::JsonMap3<self::JsonMap3|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap3|constructor#<self::JsonMap3|constructor#_#new#tearOff::T%>(_#wc2#formal);
static extension-type-member method JsonMap3|get#length<T extends core::Object? = dynamic>(lowered final self::JsonMap3<self::JsonMap3|get#length::T%> /* erasure=core::Map<core::String, core::Object?> */ #this) → core::int
;
static method parseJson3(self::JsonMap3<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void
;
static extension-type-member method JsonList1|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc3#formal) → self::JsonList1<self::JsonList1|constructor#::T%> /* erasure=core::List<core::Object?> */
;
static extension-type-member synthetic method JsonList1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc3#formal) → self::JsonList1<self::JsonList1|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList1|constructor#<self::JsonList1|constructor#_#new#tearOff::T%>(_#wc3#formal);
static extension-type-member method JsonList1|[]<T extends core::Object? = dynamic>(lowered final self::JsonList1<self::JsonList1|[]::T%> /* erasure=core::List<core::Object?> */ #this, core::int index) → self::JsonList1|[]::T%
;
static method parseJson4(self::JsonList1<dynamic> /* erasure=core::List<core::Object?> */ list) → void
;
static extension-type-member method JsonList2|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc4#formal) → self::JsonList2<self::JsonList2|constructor#::T%> /* erasure=core::List<core::Object?> */
;
static extension-type-member synthetic method JsonList2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc4#formal) → self::JsonList2<self::JsonList2|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList2|constructor#<self::JsonList2|constructor#_#new#tearOff::T%>(_#wc4#formal);
static extension-type-member method JsonList2|get#length<T extends core::Object? = dynamic>(lowered final self::JsonList2<self::JsonList2|get#length::T%> /* erasure=core::List<core::Object?> */ #this) → core::int
;
static method parseJson5(self::JsonList2<dynamic> /* erasure=core::List<core::Object?> */ list) → void
;
static extension-type-member method JsonList3|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc5#formal) → self::JsonList3<self::JsonList3|constructor#::T%> /* erasure=core::List<core::Object?> */
;
static extension-type-member synthetic method JsonList3|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc5#formal) → self::JsonList3<self::JsonList3|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList3|constructor#<self::JsonList3|constructor#_#new#tearOff::T%>(_#wc5#formal);
static extension-type-member method JsonList3|sublist<T extends core::Object? = dynamic>(lowered final self::JsonList3<self::JsonList3|sublist::T%> /* erasure=core::List<core::Object?> */ #this, core::int start, [core::int? end]) → core::List<self::JsonList3|sublist::T%>
;
static extension-type-member method JsonList3|get#sublist<T extends core::Object? = dynamic>(lowered final self::JsonList3<self::JsonList3|get#sublist::T%> /* erasure=core::List<core::Object?> */ #this) → (core::int, [core::int?]) → core::List<self::JsonList3|get#sublist::T%>
return (core::int start, [core::int? end]) → core::List<self::JsonList3|get#sublist::T%> => self::JsonList3|sublist<self::JsonList3|get#sublist::T%>(#this, start, end);
static method parseJson6(self::JsonList3<dynamic> /* erasure=core::List<core::Object?> */ list) → void
;
@@ -0,0 +1,167 @@
library;
import self as self;
import "dart:core" as core;
extension type JsonMap1<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
operator [] = self::JsonMap1|[];
constructor • = self::JsonMap1|constructor#;
constructor tearoff • = self::JsonMap1|constructor#_#new#tearOff;
}
extension type JsonMap2<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
method containsKey = self::JsonMap2|containsKey;
method tearoff containsKey = self::JsonMap2|get#containsKey;
constructor • = self::JsonMap2|constructor#;
constructor tearoff • = self::JsonMap2|constructor#_#new#tearOff;
}
extension type JsonMap3<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _) implements core::Map<core::String, core::Object?> {
abstract extension-type-member representation-field get _() → core::Map<core::String, core::Object?>;
get length = self::JsonMap3|get#length;
constructor • = self::JsonMap3|constructor#;
constructor tearoff • = self::JsonMap3|constructor#_#new#tearOff;
}
extension type JsonList1<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
operator [] = self::JsonList1|[];
constructor • = self::JsonList1|constructor#;
constructor tearoff • = self::JsonList1|constructor#_#new#tearOff;
}
extension type JsonList2<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
get length = self::JsonList2|get#length;
constructor • = self::JsonList2|constructor#;
constructor tearoff • = self::JsonList2|constructor#_#new#tearOff;
}
extension type JsonList3<T extends core::Object? = dynamic>(core::List<core::Object?> _) implements core::List<core::Object?> {
abstract extension-type-member representation-field get _() → core::List<core::Object?>;
method sublist = self::JsonList3|sublist;
method tearoff sublist = self::JsonList3|get#sublist;
constructor • = self::JsonList3|constructor#;
constructor tearoff • = self::JsonList3|constructor#_#new#tearOff;
}
static extension-type-member method JsonMap1|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc0#formal) → self::JsonMap1<self::JsonMap1|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap1<self::JsonMap1|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc0#formal;
return #this;
}
static extension-type-member synthetic method JsonMap1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc0#formal) → self::JsonMap1<self::JsonMap1|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap1|constructor#<self::JsonMap1|constructor#_#new#tearOff::T%>(_#wc0#formal);
static extension-type-member method JsonMap1|[]<T extends core::Object? = dynamic>(lowered final self::JsonMap1<self::JsonMap1|[]::T%> /* erasure=core::Map<core::String, core::Object?> */ #this, core::String key) → self::JsonMap1|[]::T%
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::[]}(key){(core::Object?) → core::Object?} as self::JsonMap1|[]::T%;
static method parseJson1(self::JsonMap1<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap1<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t1 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t2 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonMap2|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc1#formal) → self::JsonMap2<self::JsonMap2|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap2<self::JsonMap2|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc1#formal;
return #this;
}
static extension-type-member synthetic method JsonMap2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc1#formal) → self::JsonMap2<self::JsonMap2|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap2|constructor#<self::JsonMap2|constructor#_#new#tearOff::T%>(_#wc1#formal);
static extension-type-member method JsonMap2|containsKey<T extends core::Object? = dynamic>(lowered final self::JsonMap2<self::JsonMap2|containsKey::T%> /* erasure=core::Map<core::String, core::Object?> */ #this, core::String key) → core::bool
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::containsKey}(key){(core::Object?) → core::bool};
static extension-type-member method JsonMap2|get#containsKey<T extends core::Object? = dynamic>(lowered final self::JsonMap2<self::JsonMap2|get#containsKey::T%> /* erasure=core::Map<core::String, core::Object?> */ #this) → (core::String) → core::bool
return (core::String key) → core::bool => self::JsonMap2|containsKey<self::JsonMap2|get#containsKey::T%>(#this, key);
static method parseJson2(self::JsonMap2<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap2<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t3 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t4 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonMap3|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::Map<core::String, core::Object?> _#wc2#formal) → self::JsonMap3<self::JsonMap3|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ {
lowered final self::JsonMap3<self::JsonMap3|constructor#::T%> /* erasure=core::Map<core::String, core::Object?> */ #this = _#wc2#formal;
return #this;
}
static extension-type-member synthetic method JsonMap3|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::Map<core::String, core::Object?> _#wc2#formal) → self::JsonMap3<self::JsonMap3|constructor#_#new#tearOff::T%> /* erasure=core::Map<core::String, core::Object?> */
return self::JsonMap3|constructor#<self::JsonMap3|constructor#_#new#tearOff::T%>(_#wc2#formal);
static extension-type-member method JsonMap3|get#length<T extends core::Object? = dynamic>(lowered final self::JsonMap3<self::JsonMap3|get#length::T%> /* erasure=core::Map<core::String, core::Object?> */ #this) → core::int
return (#this as{Unchecked} core::Map<core::String, core::Object?>).{core::Map::length}{core::int};
static method parseJson3(self::JsonMap3<dynamic> /* erasure=core::Map<core::String, core::Object?> */ map) → void {
{
final synthesized self::JsonMap3<dynamic> /* erasure=core::Map<core::String, core::Object?> */ #0#0 = map;
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::String #0#1 = #C1;
final const synthesized core::String #0#4 = #C2;
if((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t5 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && #C2 =={core::String::==}{(core::Object) → core::bool} (#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t6 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}))
core::print("ok");
}
}
static extension-type-member method JsonList1|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc3#formal) → self::JsonList1<self::JsonList1|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList1<self::JsonList1|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc3#formal;
return #this;
}
static extension-type-member synthetic method JsonList1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc3#formal) → self::JsonList1<self::JsonList1|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList1|constructor#<self::JsonList1|constructor#_#new#tearOff::T%>(_#wc3#formal);
static extension-type-member method JsonList1|[]<T extends core::Object? = dynamic>(lowered final self::JsonList1<self::JsonList1|[]::T%> /* erasure=core::List<core::Object?> */ #this, core::int index) → self::JsonList1|[]::T%
return (#this as{Unchecked} core::List<core::Object?>).{core::List::[]}(index){(core::int) → core::Object?} as self::JsonList1|[]::T%;
static method parseJson4(self::JsonList1<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList1<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
static extension-type-member method JsonList2|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc4#formal) → self::JsonList2<self::JsonList2|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList2<self::JsonList2|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc4#formal;
return #this;
}
static extension-type-member synthetic method JsonList2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc4#formal) → self::JsonList2<self::JsonList2|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList2|constructor#<self::JsonList2|constructor#_#new#tearOff::T%>(_#wc4#formal);
static extension-type-member method JsonList2|get#length<T extends core::Object? = dynamic>(lowered final self::JsonList2<self::JsonList2|get#length::T%> /* erasure=core::List<core::Object?> */ #this) → core::int
return (#this as{Unchecked} core::List<core::Object?>).{core::List::length}{core::int};
static method parseJson5(self::JsonList2<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList2<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
static extension-type-member method JsonList3|constructor#<T extends core::Object? = dynamic>(wildcard initializing-formal core::List<core::Object?> _#wc5#formal) → self::JsonList3<self::JsonList3|constructor#::T%> /* erasure=core::List<core::Object?> */ {
lowered final self::JsonList3<self::JsonList3|constructor#::T%> /* erasure=core::List<core::Object?> */ #this = _#wc5#formal;
return #this;
}
static extension-type-member synthetic method JsonList3|constructor#_#new#tearOff<T extends core::Object? = dynamic>(core::List<core::Object?> _#wc5#formal) → self::JsonList3<self::JsonList3|constructor#_#new#tearOff::T%> /* erasure=core::List<core::Object?> */
return self::JsonList3|constructor#<self::JsonList3|constructor#_#new#tearOff::T%>(_#wc5#formal);
static extension-type-member method JsonList3|sublist<T extends core::Object? = dynamic>(lowered final self::JsonList3<self::JsonList3|sublist::T%> /* erasure=core::List<core::Object?> */ #this, core::int start, [core::int? end = #C4]) → core::List<self::JsonList3|sublist::T%>
return (#this as{Unchecked} core::List<core::Object?>).{core::List::sublist}(start, end){(core::int, [core::int?]) → core::List<core::Object?>}.{core::List::cast}<self::JsonList3|sublist::T%>(){() → core::List<self::JsonList3|sublist::T%>};
static extension-type-member method JsonList3|get#sublist<T extends core::Object? = dynamic>(lowered final self::JsonList3<self::JsonList3|get#sublist::T%> /* erasure=core::List<core::Object?> */ #this) → (core::int, [core::int?]) → core::List<self::JsonList3|get#sublist::T%>
return (core::int start, [core::int? end = #C4]) → core::List<self::JsonList3|get#sublist::T%> => self::JsonList3|sublist<self::JsonList3|get#sublist::T%>(#this, start, end);
static method parseJson6(self::JsonList3<dynamic> /* erasure=core::List<core::Object?> */ list) → void {
{
final synthesized self::JsonList3<dynamic> /* erasure=core::List<core::Object?> */ #0#0 = list;
final const synthesized core::int #0#2 = #C3;
final const synthesized core::String #0#5 = #C2;
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C3 && #C2 =={core::String::==}{(core::Object) → core::bool} #0#0.{core::List::[]}(0){(core::int) → core::Object?})
core::print("ok");
}
}
constants {
#C1 = "key"
#C2 = "value"
#C3 = 1
#C4 = null
}
Extra constant evaluation status:
Evaluated: IsExpression @ org-dartlang-testcase:///issue63315.dart:11:22 -> BoolConstant(true)
Evaluated: IsExpression @ org-dartlang-testcase:///issue63315.dart:20:22 -> BoolConstant(true)
Evaluated: IsExpression @ org-dartlang-testcase:///issue63315.dart:29:22 -> BoolConstant(true)
Extra constant evaluation: evaluated: 167, effectively constant: 3
@@ -0,0 +1,38 @@
extension type JsonMap1<T>(Map<String, Object?> _)
implements Map<String, Object?> {
T operator [](String key) => _[key] as T;
}
void parseJson1(JsonMap1 map) {}
extension type JsonMap2<T>(Map<String, Object?> _)
implements Map<String, Object?> {
bool containsKey(String key) => _.containsKey(key);
}
void parseJson2(JsonMap2 map) {}
extension type JsonMap3<T>(Map<String, Object?> _)
implements Map<String, Object?> {
int get length => _.length;
}
void parseJson3(JsonMap3 map) {}
extension type JsonList1<T>(List<Object?> _) implements List<Object?> {
T operator [](int index) => _[index] as T;
}
void parseJson4(JsonList1 list) {}
extension type JsonList2<T>(List<Object?> _) implements List<Object?> {
int get length => _.length;
}
void parseJson5(JsonList2 list) {}
extension type JsonList3<T>(List<Object?> _) implements List<Object?> {
List<T> sublist(int start, [int? end]) => _.sublist(start, end).cast<T>();
}
void parseJson6(JsonList3 list) {}
@@ -0,0 +1,38 @@
extension type JsonList1<T>(List<Object?> _) implements List<Object?> {
T operator [](int index) => _[index] as T;
}
extension type JsonList2<T>(List<Object?> _) implements List<Object?> {
int get length => _.length;
}
extension type JsonList3<T>(List<Object?> _) implements List<Object?> {
List<T> sublist(int start, [int? end]) => _.sublist(start, end).cast<T>();
}
extension type JsonMap1<T>(Map<String, Object?> _)
implements Map<String, Object?> {
T operator [](String key) => _[key] as T;
}
extension type JsonMap2<T>(Map<String, Object?> _)
implements Map<String, Object?> {
bool containsKey(String key) => _.containsKey(key);
}
extension type JsonMap3<T>(Map<String, Object?> _)
implements Map<String, Object?> {
int get length => _.length;
}
void parseJson1(JsonMap1 map) {}
void parseJson2(JsonMap2 map) {}
void parseJson3(JsonMap3 map) {}
void parseJson4(JsonList1 list) {}
void parseJson5(JsonList2 list) {}
void parseJson6(JsonList3 list) {}
@@ -155,7 +155,7 @@ static method main() → dynamic {
synthesized core::int? #0#6;
synthesized core::bool #0#6#isSet = false;
final const synthesized core::String #0#4 = #C7;
if(!((!((#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t30 = #0#3#isSet = true in #0#3 = #0#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{self::MyMap::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t31 = x1 = (#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t32 = #0#3#isSet = true in #0#3 = #0#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) as{Unchecked} core::int in true) && (!((#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t33 = #0#6#isSet = true in #0#6 = #0#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{self::MyMap::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t34 = x2 = (#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t35 = #0#6#isSet = true in #0#6 = #0#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) as{Unchecked} core::int in true)))
if(!((!((#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t30 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{core::Map::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t31 = x1 = (#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t32 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) as{Unchecked} core::int in true) && (!((#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t33 = #0#6#isSet = true in #0#6 = #0#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{core::Map::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t34 = x2 = (#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t35 = #0#6#isSet = true in #0#6 = #0#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) as{Unchecked} core::int in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(self::hasUnsoundNullSafety ?{core::String} self::unsoundResult : self::soundResult, map.{self::MyMap::log}{core::String});
@@ -170,7 +170,7 @@ static method main() → dynamic {
synthesized core::int? #1#6;
synthesized core::bool #1#6#isSet = false;
final const synthesized core::String #1#4 = #C7;
if(!((!((#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t36 = #1#3#isSet = true in #1#3 = #1#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{self::MyMap::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t37 = y1 = (#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t38 = #1#3#isSet = true in #1#3 = #1#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) as{Unchecked} core::int in true) && (!((#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t39 = #1#6#isSet = true in #1#6 = #1#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{self::MyMap::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t40 = y2 = (#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t41 = #1#6#isSet = true in #1#6 = #1#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) as{Unchecked} core::int in true)))
if(!((!((#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t36 = #1#3#isSet = true in #1#3 = #1#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{core::Map::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t37 = y1 = (#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t38 = #1#3#isSet = true in #1#3 = #1#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) as{Unchecked} core::int in true) && (!((#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t39 = #1#6#isSet = true in #1#6 = #1#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{core::Map::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t40 = y2 = (#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t41 = #1#6#isSet = true in #1#6 = #1#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) as{Unchecked} core::int in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(self::hasUnsoundNullSafety ?{core::String} self::unsoundResult : self::soundResult, map.{self::MyMap::log}{core::String});
@@ -155,7 +155,7 @@ static method main() → dynamic {
synthesized core::int? #0#6;
synthesized core::bool #0#6#isSet = false;
final const synthesized core::String #0#4 = #C7;
if(!((!((#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t30 = #0#3#isSet = true in #0#3 = #0#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{self::MyMap::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t31 = x1 = (#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t32 = #0#3#isSet = true in #0#3 = #0#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) as{Unchecked} core::int in true) && (!((#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t33 = #0#6#isSet = true in #0#6 = #0#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{self::MyMap::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t34 = x2 = (#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t35 = #0#6#isSet = true in #0#6 = #0#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) as{Unchecked} core::int in true)))
if(!((!((#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t30 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{core::Map::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t31 = x1 = (#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t32 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) as{Unchecked} core::int in true) && (!((#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t33 = #0#6#isSet = true in #0#6 = #0#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{core::Map::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t34 = x2 = (#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t35 = #0#6#isSet = true in #0#6 = #0#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) as{Unchecked} core::int in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(self::hasUnsoundNullSafety ?{core::String} self::unsoundResult : self::soundResult, map.{self::MyMap::log}{core::String});
@@ -170,7 +170,7 @@ static method main() → dynamic {
synthesized core::int? #1#6;
synthesized core::bool #1#6#isSet = false;
final const synthesized core::String #1#4 = #C7;
if(!((!((#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t36 = #1#3#isSet = true in #1#3 = #1#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{self::MyMap::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t37 = y1 = (#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t38 = #1#3#isSet = true in #1#3 = #1#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) as{Unchecked} core::int in true) && (!((#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t39 = #1#6#isSet = true in #1#6 = #1#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{self::MyMap::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t40 = y2 = (#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t41 = #1#6#isSet = true in #1#6 = #1#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) as{Unchecked} core::int in true)))
if(!((!((#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t36 = #1#3#isSet = true in #1#3 = #1#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{core::Map::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t37 = y1 = (#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t38 = #1#3#isSet = true in #1#3 = #1#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) as{Unchecked} core::int in true) && (!((#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t39 = #1#6#isSet = true in #1#6 = #1#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{core::Map::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t40 = y2 = (#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t41 = #1#6#isSet = true in #1#6 = #1#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) as{Unchecked} core::int in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(self::hasUnsoundNullSafety ?{core::String} self::unsoundResult : self::soundResult, map.{self::MyMap::log}{core::String});
@@ -155,7 +155,7 @@ static method main() → dynamic {
synthesized core::int? #0#6;
synthesized core::bool #0#6#isSet = false;
final const synthesized core::String #0#4 = #C7;
if(!((!((#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t38 = #0#3#isSet = true in #0#3 = #0#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{self::MyMap::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t39 = x1 = let core::int? #t40 = #0#3#isSet ?{core::int?} #0#3 : let final dynamic #t41 = #0#3#isSet = true in #0#3 = #0#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?} in #t40 == null ?{core::int} #t40 as{Unchecked} core::int : #t40{core::int} in true) && (!((#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t42 = #0#6#isSet = true in #0#6 = #0#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{self::MyMap::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t43 = x2 = let core::int? #t44 = #0#6#isSet ?{core::int?} #0#6 : let final dynamic #t45 = #0#6#isSet = true in #0#6 = #0#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?} in #t44 == null ?{core::int} #t44 as{Unchecked} core::int : #t44{core::int} in true)))
if(!((!((#0#3#isSet ?{core::int?} #0#3 : let final dynamic #t38 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{core::Map::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t39 = x1 = let core::int? #t40 = #0#3#isSet ?{core::int?} #0#3 : let final dynamic #t41 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C5){(core::Object?) → core::int?} in #t40 == null ?{core::int} #t40 as{Unchecked} core::int : #t40{core::int} in true) && (!((#0#6#isSet ?{core::int?} #0#6 : let final dynamic #t42 = #0#6#isSet = true in #0#6 = #0#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #0#0.{core::Map::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t43 = x2 = let core::int? #t44 = #0#6#isSet ?{core::int?} #0#6 : let final dynamic #t45 = #0#6#isSet = true in #0#6 = #0#0.{core::Map::[]}(#C7){(core::Object?) → core::int?} in #t44 == null ?{core::int} #t44 as{Unchecked} core::int : #t44{core::int} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(self::hasUnsoundNullSafety ?{core::String} self::unsoundResult : self::soundResult, map.{self::MyMap::log}{core::String});
@@ -170,7 +170,7 @@ static method main() → dynamic {
synthesized core::int? #1#6;
synthesized core::bool #1#6#isSet = false;
final const synthesized core::String #1#4 = #C7;
if(!((!((#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t46 = #1#3#isSet = true in #1#3 = #1#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{self::MyMap::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t47 = y1 = let core::int? #t48 = #1#3#isSet ?{core::int?} #1#3 : let final dynamic #t49 = #1#3#isSet = true in #1#3 = #1#0.{self::MyMap::[]}(#C5){(core::Object?) → core::int?} in #t48 == null ?{core::int} #t48 as{Unchecked} core::int : #t48{core::int} in true) && (!((#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t50 = #1#6#isSet = true in #1#6 = #1#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{self::MyMap::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t51 = y2 = let core::int? #t52 = #1#6#isSet ?{core::int?} #1#6 : let final dynamic #t53 = #1#6#isSet = true in #1#6 = #1#0.{self::MyMap::[]}(#C7){(core::Object?) → core::int?} in #t52 == null ?{core::int} #t52 as{Unchecked} core::int : #t52{core::int} in true)))
if(!((!((#1#3#isSet ?{core::int?} #1#3 : let final dynamic #t46 = #1#3#isSet = true in #1#3 = #1#0.{core::Map::[]}(#C5){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{core::Map::containsKey}(#C5){(core::Object?) → core::bool}) && (let final dynamic #t47 = y1 = let core::int? #t48 = #1#3#isSet ?{core::int?} #1#3 : let final dynamic #t49 = #1#3#isSet = true in #1#3 = #1#0.{core::Map::[]}(#C5){(core::Object?) → core::int?} in #t48 == null ?{core::int} #t48 as{Unchecked} core::int : #t48{core::int} in true) && (!((#1#6#isSet ?{core::int?} #1#6 : let final dynamic #t50 = #1#6#isSet = true in #1#6 = #1#0.{core::Map::[]}(#C7){(core::Object?) → core::int?}) == null) || null is core::int && #1#0.{core::Map::containsKey}(#C7){(core::Object?) → core::bool}) && (let final dynamic #t51 = y2 = let core::int? #t52 = #1#6#isSet ?{core::int?} #1#6 : let final dynamic #t53 = #1#6#isSet = true in #1#6 = #1#0.{core::Map::[]}(#C7){(core::Object?) → core::int?} in #t52 == null ?{core::int} #t52 as{Unchecked} core::int : #t52{core::int} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
self::expect(self::hasUnsoundNullSafety ?{core::String} self::unsoundResult : self::soundResult, map.{self::MyMap::log}{core::String});
@@ -157,8 +157,8 @@ static method main() → dynamic {
{
hoisted core::int x;
hoisted core::int y;
if(#0#0.{self::A::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C5 && ((#0#4#isSet ?{core::int} #0#4 : let final dynamic #t1 = #0#4#isSet = true in #0#4 = #0#0.{self::A::[]}(0){(core::int) → core::int}) is core::int && (let final dynamic #t2 = x = #0#4#isSet ?{core::int} #0#4 : let final dynamic #t3 = #0#4#isSet = true in #0#4 = #0#0.{self::A::[]}(0){(core::int) → core::int} in true)) && (#0#5#isSet ?{core::int} #0#5 : let final dynamic #t4 = #0#5#isSet = true in #0#5 = #0#0.{self::A::[]}(1){(core::int) → core::int}) is core::int) {
y = #0#5#isSet ?{core::int} #0#5 : let final dynamic #t5 = #0#5#isSet = true in #0#5 = #0#0.{self::A::[]}(1){(core::int) → core::int};
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C5 && ((#0#4#isSet ?{core::int} #0#4 : let final dynamic #t1 = #0#4#isSet = true in #0#4 = #0#0.{core::List::[]}(0){(core::int) → core::int}) is core::int && (let final dynamic #t2 = x = #0#4#isSet ?{core::int} #0#4 : let final dynamic #t3 = #0#4#isSet = true in #0#4 = #0#0.{core::List::[]}(0){(core::int) → core::int} in true)) && (#0#5#isSet ?{core::int} #0#5 : let final dynamic #t4 = #0#5#isSet = true in #0#5 = #0#0.{core::List::[]}(1){(core::int) → core::int}) is core::int) {
y = #0#5#isSet ?{core::int} #0#5 : let final dynamic #t5 = #0#5#isSet = true in #0#5 = #0#0.{core::List::[]}(1){(core::int) → core::int};
{
self::expectEquals(x, 0);
self::expectEquals(y, 0);
@@ -157,8 +157,8 @@ static method main() → dynamic {
{
hoisted core::int x;
hoisted core::int y;
if(#0#0.{self::A::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C5 && ((#0#4#isSet ?{core::int} #0#4 : let final dynamic #t1 = #0#4#isSet = true in #0#4 = #0#0.{self::A::[]}(0){(core::int) → core::int}) is core::int && (let final dynamic #t2 = x = #0#4#isSet ?{core::int} #0#4 : let final dynamic #t3 = #0#4#isSet = true in #0#4 = #0#0.{self::A::[]}(0){(core::int) → core::int} in true)) && (#0#5#isSet ?{core::int} #0#5 : let final dynamic #t4 = #0#5#isSet = true in #0#5 = #0#0.{self::A::[]}(1){(core::int) → core::int}) is core::int) {
y = #0#5#isSet ?{core::int} #0#5 : let final dynamic #t5 = #0#5#isSet = true in #0#5 = #0#0.{self::A::[]}(1){(core::int) → core::int};
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C5 && ((#0#4#isSet ?{core::int} #0#4 : let final dynamic #t1 = #0#4#isSet = true in #0#4 = #0#0.{core::List::[]}(0){(core::int) → core::int}) is core::int && (let final dynamic #t2 = x = #0#4#isSet ?{core::int} #0#4 : let final dynamic #t3 = #0#4#isSet = true in #0#4 = #0#0.{core::List::[]}(0){(core::int) → core::int} in true)) && (#0#5#isSet ?{core::int} #0#5 : let final dynamic #t4 = #0#5#isSet = true in #0#5 = #0#0.{core::List::[]}(1){(core::int) → core::int}) is core::int) {
y = #0#5#isSet ?{core::int} #0#5 : let final dynamic #t5 = #0#5#isSet = true in #0#5 = #0#0.{core::List::[]}(1){(core::int) → core::int};
{
self::expectEquals(x, 0);
self::expectEquals(y, 0);
@@ -534,8 +534,8 @@ static method main() → dynamic {
{
hoisted core::int x;
hoisted core::int y;
if(#0#0.{self::A::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C8 && ((#0#4#isSet ?{core::int} #0#4 : let final dynamic #t10 = #0#4#isSet = true in #0#4 = #0#0.{self::A::[]}(0){(core::int) → core::int}) is core::int && (let final dynamic #t11 = x = #0#4#isSet ?{core::int} #0#4 : let final dynamic #t12 = #0#4#isSet = true in #0#4 = #0#0.{self::A::[]}(0){(core::int) → core::int} in true)) && (#0#5#isSet ?{core::int} #0#5 : let final dynamic #t13 = #0#5#isSet = true in #0#5 = #0#0.{self::A::[]}(1){(core::int) → core::int}) is core::int) {
y = #0#5#isSet ?{core::int} #0#5 : let final dynamic #t14 = #0#5#isSet = true in #0#5 = #0#0.{self::A::[]}(1){(core::int) → core::int};
if(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C8 && ((#0#4#isSet ?{core::int} #0#4 : let final dynamic #t10 = #0#4#isSet = true in #0#4 = #0#0.{core::List::[]}(0){(core::int) → core::int}) is core::int && (let final dynamic #t11 = x = #0#4#isSet ?{core::int} #0#4 : let final dynamic #t12 = #0#4#isSet = true in #0#4 = #0#0.{core::List::[]}(0){(core::int) → core::int} in true)) && (#0#5#isSet ?{core::int} #0#5 : let final dynamic #t13 = #0#5#isSet = true in #0#5 = #0#0.{core::List::[]}(1){(core::int) → core::int}) is core::int) {
y = #0#5#isSet ?{core::int} #0#5 : let final dynamic #t14 = #0#5#isSet = true in #0#5 = #0#0.{core::List::[]}(1){(core::int) → core::int};
{
self::expectEquals(x, 0);
self::expectEquals(y, 0);
@@ -4,10 +4,11 @@ import "dart:core" as core;
static method main() → void {
try {
has-declared-initializer core::Object? y;
hoisted has-declared-initializer core::Object? y;
{
final synthesized Never #0#0 = throw 42;
if(!#0#0)
final const synthesized core::int #0#2 = #C1;
if(!(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = y = #0#0.{core::List::[]}(0){(core::int) → core::Object?} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -17,3 +18,7 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 1
}
@@ -4,10 +4,11 @@ import "dart:core" as core;
static method main() → void {
try {
has-declared-initializer core::Object? y;
hoisted has-declared-initializer core::Object? y;
{
final synthesized Never #0#0 = throw 42;
if(!#0#0)
final const synthesized core::int #0#2 = #C1;
if(!(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = y = #0#0.{core::List::[]}(0){(core::int) → core::Object?} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -17,3 +18,7 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 1
}
@@ -4,10 +4,11 @@ import "dart:core" as core;
static method main() → void {
try {
has-declared-initializer core::Object? y;
hoisted has-declared-initializer core::Object? y;
{
final synthesized Never #0#0 = throw 42;
if(!#0#0)
final const synthesized core::int #0#2 = #C1;
if(!(#0#0.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = y = #0#0.{core::List::[]}(0){(core::int) → core::Object?} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -17,3 +18,7 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 1
}
@@ -4,10 +4,13 @@ import "dart:core" as core;
static method main() → void {
try {
has-declared-initializer core::Object? b;
hoisted has-declared-initializer core::Object? b;
{
final synthesized Never #0#0 = throw <core::int, core::int>{42: 42};
if(!#0#0)
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::int #0#1 = #C1;
if(!((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t1 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && (let final dynamic #t2 = b = #0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t3 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -17,3 +20,7 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 42
}
@@ -4,10 +4,13 @@ import "dart:core" as core;
static method main() → void {
try {
has-declared-initializer core::Object? b;
hoisted has-declared-initializer core::Object? b;
{
final synthesized Never #0#0 = throw <core::int, core::int>{42: 42};
if(!#0#0)
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::int #0#1 = #C1;
if(!((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t1 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && (let final dynamic #t2 = b = #0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t3 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -17,3 +20,7 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 42
}
@@ -4,10 +4,13 @@ import "dart:core" as core;
static method main() → void {
try {
has-declared-initializer core::Object? b;
hoisted has-declared-initializer core::Object? b;
{
final synthesized Never #0#0 = throw <core::int, core::int>{42: 42};
if(!#0#0)
synthesized core::Object? #0#3;
synthesized core::bool #0#3#isSet = false;
final const synthesized core::int #0#1 = #C1;
if(!((!((#0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t1 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?}) == null) || null is core::Object? && #0#0.{core::Map::containsKey}(#C1){(core::Object?) → core::bool}) && (let final dynamic #t2 = b = #0#3#isSet ?{core::Object?} #0#3 : let final dynamic #t3 = #0#3#isSet = true in #0#3 = #0#0.{core::Map::[]}(#C1){(core::Object?) → core::Object?} in true)))
throw{for-error-handling} new core::StateError::•("Pattern matching error");
}
}
@@ -17,3 +20,11 @@ static method main() → void {
}
throw "Missing exception";
}
constants {
#C1 = 42
}
Extra constant evaluation status:
Evaluated: IsExpression @ org-dartlang-testcase:///never_map.dart:7:12 -> BoolConstant(true)
Extra constant evaluation: evaluated: 34, effectively constant: 1
-23
View File
@@ -364,7 +364,6 @@ class NullCheckPattern extends Pattern {
class ListPattern extends Pattern {
static const int FlagNeedsCheck = 1 << 0;
static const int FlagHasRestPattern = 1 << 1;
static const int FlagIsNeverPattern = 1 << 2;
int flags = 0;
@@ -403,17 +402,6 @@ class ListPattern extends Pattern {
/// This is set during inference.
DartType? lookupType;
/// If `true`, this list pattern is performed on an expression of type
/// `Never`.
///
/// This is set during inference.
bool get isNeverPattern => flags & FlagIsNeverPattern != 0;
void set isNeverPattern(bool value) {
flags = value
? (flags | FlagIsNeverPattern)
: (flags & ~FlagIsNeverPattern);
}
/// If `true`, this list pattern contains a rest pattern.
///
/// This is set during inference.
@@ -966,7 +954,6 @@ class AssignedVariablePattern extends Pattern {
class MapPattern extends Pattern {
static const int FlagNeedsCheck = 1 << 0;
static const int FlagIsNeverPattern = 1 << 1;
int flags = 0;
@@ -1008,16 +995,6 @@ class MapPattern extends Pattern {
/// This is set during inference.
DartType? lookupType;
/// If `true`, this map pattern is performed on an expression of type `Never`.
///
/// This is set during inference.
bool get isNeverPattern => flags & FlagIsNeverPattern != 0;
void set isNeverPattern(bool value) {
flags = value
? (flags | FlagIsNeverPattern)
: (flags & ~FlagIsNeverPattern);
}
/// Reference to the target of the `containsKey` method of the map.
///
/// This is set during inference.