Version 2.12.0-166.0.dev
Merge commit '474edbe27f891acf1090f4c5c32b3bcbf94892cb' into 'dev'
diff --git a/DEPS b/DEPS
index 4f282eb..012166d 100644
--- a/DEPS
+++ b/DEPS
@@ -68,7 +68,7 @@
"gperftools_revision": "180bfa10d7cb38e8b3784d60943d50e8fcef0dcb",
# Revisions of /third_party/* dependencies.
- "args_rev": "6921e2f63796368bbe65a64ad943df84932dff55",
+ "args_rev": "2c6a221f45e4e0ef447b5d09101bf8a52e1ccd36",
"async_rev": "695b3ac280f107c84adf7488743abfdfaaeea68f",
"bazel_worker_rev": "060c55a933d39798681a4f533b161b81dc48d77e",
"benchmark_harness_rev": "ec6b646f5443faa871e126ac1ba248c94ca06257",
diff --git a/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart b/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
index 0c9fe04..5cade7b 100644
--- a/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
+++ b/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
@@ -4,6 +4,8 @@
// ignore_for_file: avoid_function_literals_in_foreach_calls
+import 'dart:math' show pow;
+
import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:fixnum/fixnum.dart';
@@ -31,38 +33,29 @@
// integers.
const requiredDigits = 11106;
-class Benchmark extends BenchmarkBase {
- final List<String> strings;
- Benchmark(String name, int bits)
- : strings = generateStrings(bits),
+class ParseBigIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final BigInt seed;
+ final List<String> strings = [];
+
+ ParseBigIntBenchmark(String name, this.bits)
+ : seed = (BigInt.one << bits) - BigInt.one,
super(name);
- static List<String> generateStrings(int bits) {
- List<String> strings = [];
- BigInt seed = (BigInt.one << bits) - BigInt.one;
+ @override
+ void setup() {
var b = seed;
- var restartDelta = BigInt.zero;
var totalLength = 0;
while (totalLength < requiredDigits) {
if (b.bitLength < bits) {
- restartDelta += seed >> 20;
- restartDelta += BigInt.one;
- // Restart from a slighly reduced seed to generate different numbers.
- b = seed - restartDelta;
+ b = seed;
}
final string = b.toString();
strings.add(string);
totalLength += string.length;
- var delta = b >> 8;
- if (delta == BigInt.zero) delta = BigInt.one;
- b = b - delta;
+ b = b - (b >> 8);
}
- return strings;
}
-}
-
-class ParseBigIntBenchmark extends Benchmark {
- ParseBigIntBenchmark(String name, int bits) : super(name, bits);
@override
void run() {
@@ -75,8 +68,31 @@
}
}
-class ParseInt64Benchmark extends Benchmark {
- ParseInt64Benchmark(String name, int bits) : super(name, bits);
+int int64UnsignedBitLength(Int64 i) => i.isNegative ? 64 : i.bitLength;
+
+class ParseInt64Benchmark extends BenchmarkBase {
+ final int bits;
+ final Int64 seed;
+ final List<String> strings = [];
+
+ ParseInt64Benchmark(String name, this.bits)
+ : seed = (Int64.ONE << bits) - Int64.ONE,
+ super(name);
+
+ @override
+ void setup() {
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (int64UnsignedBitLength(b) < bits) {
+ b = seed;
+ }
+ final string = b.toStringUnsigned();
+ strings.add(string);
+ totalLength += string.length;
+ b = b - b.shiftRightUnsigned(8);
+ }
+ }
@override
void run() {
@@ -89,8 +105,29 @@
}
}
-class ParseIntBenchmark extends Benchmark {
- ParseIntBenchmark(String name, int bits) : super(name, bits);
+class ParseIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final int seed;
+ final List<String> strings = [];
+
+ ParseIntBenchmark(String name, this.bits)
+ : seed = (pow(2, bits) as int) - 1,
+ super(name);
+
+ @override
+ void setup() {
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (b.bitLength < bits) {
+ b = seed;
+ }
+ final string = b.toString();
+ strings.add(string);
+ totalLength += string.length;
+ b = b - b ~/ 256;
+ }
+ }
@override
void run() {
@@ -103,8 +140,33 @@
}
}
-class ParseJsBigIntBenchmark extends Benchmark {
- ParseJsBigIntBenchmark(String name, int bits) : super(name, bits);
+class ParseJsBigIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final Object seed;
+ final List<String> strings = [];
+
+ ParseJsBigIntBenchmark(String name, this.bits)
+ : seed = nativeBigInt.subtract(
+ nativeBigInt.shiftLeft(
+ nativeBigInt.one, nativeBigInt.fromInt(bits)),
+ nativeBigInt.one),
+ super(name);
+
+ @override
+ void setup() {
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (nativeBigInt.bitLength(b) < bits) {
+ b = seed;
+ }
+ final string = nativeBigInt.toStringMethod(b);
+ strings.add(string);
+ totalLength += string.length;
+ b = nativeBigInt.subtract(
+ b, nativeBigInt.shiftRight(b, nativeBigInt.eight));
+ }
+ }
@override
void run() {
@@ -117,16 +179,27 @@
}
}
-class FormatBigIntBenchmark extends Benchmark {
+class FormatBigIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final BigInt seed;
final List<BigInt> values = [];
- FormatBigIntBenchmark(String name, int bits) : super(name, bits);
+ FormatBigIntBenchmark(String name, this.bits)
+ : seed = (BigInt.one << bits) - BigInt.one,
+ super(name);
@override
void setup() {
- for (String s in strings) {
- BigInt b = BigInt.parse(s);
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (b.bitLength < bits) {
+ b = seed;
+ }
+ final string = b.toString();
values.add(b - BigInt.one); // We add 'one' back later.
+ totalLength += string.length;
+ b = b - (b >> 8);
}
}
@@ -145,16 +218,28 @@
}
}
-class FormatIntBenchmark extends Benchmark {
+class FormatIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final int seed;
final List<int> values = [];
- FormatIntBenchmark(String name, int bits) : super(name, bits);
+ FormatIntBenchmark(String name, this.bits)
+ : seed = (pow(2, bits) as int) - 1,
+ super(name);
@override
void setup() {
- for (String s in strings) {
- int b = int.parse(s);
- values.add(b - 4096); // We add this back later.
+ var b = seed;
+ var totalLength = 0;
+ int kk = b ~/ 100000;
+ while (totalLength < requiredDigits) {
+ if (b.bitLength < bits) {
+ b = seed - ++kk;
+ }
+ final string = b.toString();
+ values.add(b - 4096); // We add 'one' back later.
+ totalLength += string.length;
+ b = b - (b ~/ 256);
}
}
@@ -162,9 +247,7 @@
void run() {
for (final b0 in values) {
// Instances might cache `toString()`, so use arithmetic to create a new
- // instance to try to protect against measuring a cached string. We use
- // 4096 to avoid the arithmetic being a no-op due to rounding on web
- // integers (i.e. doubles).
+ // instance to try to protect against measuring a cached string.
final b = b0 + 4096;
final s = b.toString();
sink1 = s;
@@ -174,16 +257,27 @@
}
}
-class FormatInt64Benchmark extends Benchmark {
+class FormatInt64Benchmark extends BenchmarkBase {
+ final int bits;
+ final Int64 seed;
final List<Int64> values = [];
- FormatInt64Benchmark(String name, int bits) : super(name, bits);
+ FormatInt64Benchmark(String name, this.bits)
+ : seed = (Int64.ONE << bits) - Int64.ONE,
+ super(name);
@override
void setup() {
- for (String s in strings) {
- final b = Int64.parseInt(s);
- values.add(b - Int64.ONE); // We add this back later.
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (int64UnsignedBitLength(b) < bits) {
+ b = seed;
+ }
+ final string = b.toStringUnsigned();
+ values.add(b - Int64.ONE);
+ totalLength += string.length;
+ b = b - b.shiftRightUnsigned(8);
}
}
@@ -202,17 +296,32 @@
}
}
-class FormatJsBigIntBenchmark extends Benchmark {
+class FormatJsBigIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final Object seed;
final List<Object> values = [];
- FormatJsBigIntBenchmark(String name, int bits) : super(name, bits);
+ FormatJsBigIntBenchmark(String name, this.bits)
+ : seed = nativeBigInt.subtract(
+ nativeBigInt.shiftLeft(
+ nativeBigInt.one, nativeBigInt.fromInt(bits)),
+ nativeBigInt.one),
+ super(name);
@override
void setup() {
final one = nativeBigInt.one;
- for (String s in strings) {
- final b = nativeBigInt.parse(s);
- values.add(nativeBigInt.subtract(b, one)); // We add this back later.
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (nativeBigInt.bitLength(b) < bits) {
+ b = seed;
+ }
+ final string = nativeBigInt.toStringMethod(b);
+ values.add(nativeBigInt.subtract(b, one)); // We add 'one' back later.
+ totalLength += string.length;
+ b = nativeBigInt.subtract(
+ b, nativeBigInt.shiftRight(b, nativeBigInt.eight));
}
}
@@ -262,9 +371,6 @@
final benchmarks = [
() => ParseIntBenchmark('Int.parse.0009.bits', 9),
() => ParseIntBenchmark('Int.parse.0032.bits', 32),
- // Use '63' bits to avoid 64-bit arithmetic overflowing to negative. Keep
- // the name as '64' to help comparisons. The effect of an incorrect number
- // is reduced since benchmark results are normalized to a 'per digit' score
() => ParseIntBenchmark('Int.parse.0064.bits', 63),
() => ParseInt64Benchmark('Int64.parse.0009.bits', 9),
() => ParseInt64Benchmark('Int64.parse.0032.bits', 32),
@@ -283,7 +389,7 @@
selectParseNativeBigIntBenchmark('JsBigInt.parse.4096.bits', 4096),
() => FormatIntBenchmark('Int.toString.0009.bits', 9),
() => FormatIntBenchmark('Int.toString.0032.bits', 32),
- () => FormatIntBenchmark('Int.toString.0064.bits', 63), // '63': See above.
+ () => FormatIntBenchmark('Int.toString.0064.bits', 63),
() => FormatInt64Benchmark('Int64.toString.0009.bits', 9),
() => FormatInt64Benchmark('Int64.toString.0032.bits', 32),
() => FormatInt64Benchmark('Int64.toString.0064.bits', 64),
diff --git a/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart b/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
index 5656eac..26a796f 100644
--- a/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
+++ b/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
@@ -33,38 +33,29 @@
// integers.
const requiredDigits = 11106;
-class Benchmark extends BenchmarkBase {
- final List<String> strings;
- Benchmark(String name, int bits)
- : strings = generateStrings(bits),
+class ParseBigIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final BigInt seed;
+ final List<String> strings = [];
+
+ ParseBigIntBenchmark(String name, this.bits)
+ : seed = (BigInt.one << bits) - BigInt.one,
super(name);
- static List<String> generateStrings(int bits) {
- List<String> strings = [];
- BigInt seed = (BigInt.one << bits) - BigInt.one;
+ @override
+ void setup() {
var b = seed;
- var restartDelta = BigInt.zero;
var totalLength = 0;
while (totalLength < requiredDigits) {
if (b.bitLength < bits) {
- restartDelta += seed >> 20;
- restartDelta += BigInt.one;
- // Restart from a slighly reduced seed to generate different numbers.
- b = seed - restartDelta;
+ b = seed;
}
final string = b.toString();
strings.add(string);
totalLength += string.length;
- var delta = b >> 8;
- if (delta == BigInt.zero) delta = BigInt.one;
- b = b - delta;
+ b = b - (b >> 8);
}
- return strings;
}
-}
-
-class ParseBigIntBenchmark extends Benchmark {
- ParseBigIntBenchmark(String name, int bits) : super(name, bits);
@override
void run() {
@@ -77,8 +68,31 @@
}
}
-class ParseInt64Benchmark extends Benchmark {
- ParseInt64Benchmark(String name, int bits) : super(name, bits);
+int int64UnsignedBitLength(Int64 i) => i.isNegative ? 64 : i.bitLength;
+
+class ParseInt64Benchmark extends BenchmarkBase {
+ final int bits;
+ final Int64 seed;
+ final List<String> strings = [];
+
+ ParseInt64Benchmark(String name, this.bits)
+ : seed = (Int64.ONE << bits) - Int64.ONE,
+ super(name);
+
+ @override
+ void setup() {
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (int64UnsignedBitLength(b) < bits) {
+ b = seed;
+ }
+ final string = b.toStringUnsigned();
+ strings.add(string);
+ totalLength += string.length;
+ b = b - b.shiftRightUnsigned(8);
+ }
+ }
@override
void run() {
@@ -91,22 +105,33 @@
}
}
-class ParseIntBenchmark extends Benchmark {
- ParseIntBenchmark(String name, int bits) : super(name, bits);
+class ParseJsBigIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final Object seed;
+ final List<String> strings = [];
+
+ ParseJsBigIntBenchmark(String name, this.bits)
+ : seed = nativeBigInt.subtract(
+ nativeBigInt.shiftLeft(
+ nativeBigInt.one, nativeBigInt.fromInt(bits)),
+ nativeBigInt.one),
+ super(name);
@override
- void run() {
- for (final s in strings) {
- final b = int.parse(s);
- sink1 = s;
- sink2 = b;
+ void setup() {
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (nativeBigInt.bitLength(b) < bits) {
+ b = seed;
+ }
+ final string = nativeBigInt.toStringMethod(b);
+ strings.add(string);
+ totalLength += string.length;
+ b = nativeBigInt.subtract(
+ b, nativeBigInt.shiftRight(b, nativeBigInt.eight));
}
- check(sink2.isEven);
}
-}
-
-class ParseJsBigIntBenchmark extends Benchmark {
- ParseJsBigIntBenchmark(String name, int bits) : super(name, bits);
@override
void run() {
@@ -119,16 +144,27 @@
}
}
-class FormatBigIntBenchmark extends Benchmark {
+class FormatBigIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final BigInt seed;
final List<BigInt> values = [];
- FormatBigIntBenchmark(String name, int bits) : super(name, bits);
+ FormatBigIntBenchmark(String name, this.bits)
+ : seed = (BigInt.one << bits) - BigInt.one,
+ super(name);
@override
void setup() {
- for (String s in strings) {
- BigInt b = BigInt.parse(s);
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (b.bitLength < bits) {
+ b = seed;
+ }
+ final string = b.toString();
values.add(b - BigInt.one); // We add 'one' back later.
+ totalLength += string.length;
+ b = b - (b >> 8);
}
}
@@ -147,45 +183,27 @@
}
}
-class FormatIntBenchmark extends Benchmark {
- final List<int> values = [];
-
- FormatIntBenchmark(String name, int bits) : super(name, bits);
-
- @override
- void setup() {
- for (String s in strings) {
- int b = int.parse(s);
- values.add(b - 4096); // We add this back later.
- }
- }
-
- @override
- void run() {
- for (final b0 in values) {
- // Instances might cache `toString()`, so use arithmetic to create a new
- // instance to try to protect against measuring a cached string. We use
- // 4096 to avoid the arithmetic being a no-op due to rounding on web
- // integers (i.e. doubles).
- final b = b0 + 4096;
- final s = b.toString();
- sink1 = s;
- sink2 = b;
- }
- check(sink2.isEven);
- }
-}
-
-class FormatInt64Benchmark extends Benchmark {
+class FormatInt64Benchmark extends BenchmarkBase {
+ final int bits;
+ final Int64 seed;
final List<Int64> values = [];
- FormatInt64Benchmark(String name, int bits) : super(name, bits);
+ FormatInt64Benchmark(String name, this.bits)
+ : seed = (Int64.ONE << bits) - Int64.ONE,
+ super(name);
@override
void setup() {
- for (String s in strings) {
- final b = Int64.parseInt(s);
- values.add(b - Int64.ONE); // We add this back later.
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (int64UnsignedBitLength(b) < bits) {
+ b = seed;
+ }
+ final string = b.toStringUnsigned();
+ values.add(b - Int64.ONE);
+ totalLength += string.length;
+ b = b - b.shiftRightUnsigned(8);
}
}
@@ -204,17 +222,32 @@
}
}
-class FormatJsBigIntBenchmark extends Benchmark {
+class FormatJsBigIntBenchmark extends BenchmarkBase {
+ final int bits;
+ final Object seed;
final List<Object> values = [];
- FormatJsBigIntBenchmark(String name, int bits) : super(name, bits);
+ FormatJsBigIntBenchmark(String name, this.bits)
+ : seed = nativeBigInt.subtract(
+ nativeBigInt.shiftLeft(
+ nativeBigInt.one, nativeBigInt.fromInt(bits)),
+ nativeBigInt.one),
+ super(name);
@override
void setup() {
final one = nativeBigInt.one;
- for (String s in strings) {
- final b = nativeBigInt.parse(s);
- values.add(nativeBigInt.subtract(b, one)); // We add this back later.
+ var b = seed;
+ var totalLength = 0;
+ while (totalLength < requiredDigits) {
+ if (nativeBigInt.bitLength(b) < bits) {
+ b = seed;
+ }
+ final string = nativeBigInt.toStringMethod(b);
+ values.add(nativeBigInt.subtract(b, one)); // We add 'one' back later.
+ totalLength += string.length;
+ b = nativeBigInt.subtract(
+ b, nativeBigInt.shiftRight(b, nativeBigInt.eight));
}
}
@@ -262,12 +295,6 @@
void main() {
final benchmarks = [
- () => ParseIntBenchmark('Int.parse.0009.bits', 9),
- () => ParseIntBenchmark('Int.parse.0032.bits', 32),
- // Use '63' bits to avoid 64-bit arithmetic overflowing to negative. Keep
- // the name as '64' to help comparisons. The effect of an incorrect number
- // is reduced since benchmark results are normalized to a 'per digit' score
- () => ParseIntBenchmark('Int.parse.0064.bits', 63),
() => ParseInt64Benchmark('Int64.parse.0009.bits', 9),
() => ParseInt64Benchmark('Int64.parse.0032.bits', 32),
() => ParseInt64Benchmark('Int64.parse.0064.bits', 64),
@@ -283,9 +310,6 @@
selectParseNativeBigIntBenchmark('JsBigInt.parse.0256.bits', 256),
selectParseNativeBigIntBenchmark('JsBigInt.parse.1024.bits', 1024),
selectParseNativeBigIntBenchmark('JsBigInt.parse.4096.bits', 4096),
- () => FormatIntBenchmark('Int.toString.0009.bits', 9),
- () => FormatIntBenchmark('Int.toString.0032.bits', 32),
- () => FormatIntBenchmark('Int.toString.0064.bits', 63), // '63': See above.
() => FormatInt64Benchmark('Int64.toString.0009.bits', 9),
() => FormatInt64Benchmark('Int64.toString.0032.bits', 32),
() => FormatInt64Benchmark('Int64.toString.0064.bits', 64),
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 818914f..2ef2bf1 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -298,7 +298,7 @@
ExpressionInfo<Variable, Type> invert() =>
new ExpressionInfo<Variable, Type>(after, ifFalse, ifTrue);
- ExpressionInfo<Variable, Type> rebaseForward(
+ ExpressionInfo<Variable, Type>? rebaseForward(
TypeOperations<Variable, Type> typeOperations,
FlowModel<Variable, Type> base) =>
new ExpressionInfo(base, ifTrue.rebaseForward(typeOperations, base),
@@ -3757,11 +3757,11 @@
_storeExpressionVariable(expression, variable);
VariableModel<Variable, Type> variableModel = _current.infoFor(variable);
if (allowLocalBooleanVarsToPromote) {
- ExpressionInfo<Variable, Type>? expressionInfo =
- variableModel.ssaNode?.expressionInfo;
+ ExpressionInfo<Variable, Type>? expressionInfo = variableModel
+ .ssaNode?.expressionInfo
+ ?.rebaseForward(typeOperations, _current);
if (expressionInfo != null) {
- _storeExpressionInfo(
- expression, expressionInfo.rebaseForward(typeOperations, _current));
+ _storeExpressionInfo(expression, expressionInfo);
}
}
return variableModel.promotedTypes?.last;
@@ -3951,10 +3951,10 @@
}
@override
- ExpressionInfo<Variable, Type> rebaseForward(
+ ExpressionInfo<Variable, Type>? rebaseForward(
TypeOperations<Variable, Type> typeOperations,
FlowModel<Variable, Type> base) =>
- new _NullInfo(base);
+ null;
}
/// [_FlowContext] representing a language construct for which flow analysis
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index e9740e2..f8c1de7 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -2586,18 +2586,11 @@
]);
});
- test('variableRead() restores the notion of whether a value is null', () {
- // This is not a necessary part of the design of
- // https://github.com/dart-lang/language/issues/1274; it's more of a happy
- // accident of how it was implemented: since we store an ExpressionInfo
- // object in the SSA node to keep track of the consequences of the
- // variable's value on flow analysis, and since the _NullInfo type is a
- // subtype of ExpressionInfo, that means that when a literal `null` is
- // written to a variable, and we read it later, we recognize the value as
- // being `null` for purposes of comparison to other other variables. Even
- // though this feature is a happy accident of the implementation strategy,
- // it's important to test it to make sure it doesn't regress, since users
- // might come to rely on it.
+ test("variableRead() doesn't restore the notion of whether a value is null",
+ () {
+ // Note: we have the available infrastructure to do this if we want, but
+ // we think it will give an inconsistent feel because comparisons like
+ // `if (i == null)` *don't* promote.
var h = Harness(allowLocalBooleanVarsToPromote: true);
var x = Var('x', 'int?');
var y = Var('y', 'int?');
@@ -2611,7 +2604,9 @@
checkNotPromoted(x),
checkNotPromoted(y),
], [
- checkPromoted(x, 'int'),
+ // Even though x != y and y is known to contain the value `null`, we
+ // don't promote x.
+ checkNotPromoted(x),
checkNotPromoted(y),
]),
]);
diff --git a/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart b/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
index a08df3c..7405b0e 100644
--- a/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart
@@ -95,8 +95,8 @@
HighlightRegionType.ENUM: SemanticTokenTypes.enum_,
HighlightRegionType.ENUM_CONSTANT: SemanticTokenTypes.enumMember,
HighlightRegionType.FUNCTION_TYPE_ALIAS: SemanticTokenTypes.type,
- HighlightRegionType.INSTANCE_FIELD_DECLARATION: SemanticTokenTypes.property,
- HighlightRegionType.INSTANCE_FIELD_REFERENCE: SemanticTokenTypes.property,
+ HighlightRegionType.INSTANCE_FIELD_DECLARATION: SemanticTokenTypes.variable,
+ HighlightRegionType.INSTANCE_FIELD_REFERENCE: SemanticTokenTypes.variable,
HighlightRegionType.INSTANCE_GETTER_DECLARATION: SemanticTokenTypes.property,
HighlightRegionType.INSTANCE_GETTER_REFERENCE: SemanticTokenTypes.property,
HighlightRegionType.INSTANCE_METHOD_DECLARATION: SemanticTokenTypes.method,
diff --git a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
index 5c6836b..04c0427 100644
--- a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
+++ b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
@@ -104,7 +104,7 @@
_Token('/// field docs', SemanticTokenTypes.comment,
[SemanticTokenModifiers.documentation]),
_Token('String', SemanticTokenTypes.class_),
- _Token('myField', SemanticTokenTypes.property,
+ _Token('myField', SemanticTokenTypes.variable,
[SemanticTokenModifiers.declaration]),
_Token("'FieldVal'", SemanticTokenTypes.string),
_Token('/// static field docs', SemanticTokenTypes.comment,
diff --git a/pkg/compiler/test/inference/data/general.dart b/pkg/compiler/test/inference/data/general.dart
index 209f884..275cd19 100644
--- a/pkg/compiler/test/inference/data/general.dart
+++ b/pkg/compiler/test/inference/data/general.dart
@@ -809,8 +809,9 @@
return new CascadeHelper()
.. /*update: [exact=CascadeHelper]*/ a = "hello"
.. /*update: [exact=CascadeHelper]*/ b = 42
- .. /*[exact=CascadeHelper]*/ /*update: [exact=CascadeHelper]*/ i
- /*invoke: [subclass=JSPositiveInt]*/ += 1;
+ .. /*[exact=CascadeHelper]*/ i
+ /*invoke: [subclass=JSPositiveInt]*/ /*update: [exact=CascadeHelper]*/ +=
+ 1;
}
/*member: CascadeHelper.:[exact=CascadeHelper]*/
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 509c236..d42d1d5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -516,7 +516,6 @@
bool isPostIncDec: false}) {
return new CompoundPropertySet(receiver, name, binaryOperator, value,
forEffect: voidContext,
- readOnlyReceiver: false,
readOffset: fileOffset,
binaryOffset: offset,
writeOffset: fileOffset)
@@ -994,19 +993,16 @@
Expression buildAssignment(Expression value, {bool voidContext: false}) {
VariableDeclaration variable;
Expression receiverValue;
- bool readOnlyReceiver;
if (isNullAware) {
variable = _forest.createVariableDeclarationForValue(receiver);
receiverValue = _helper.createVariableGet(variable, fileOffset,
forNullGuardedAccess: true);
- readOnlyReceiver = true;
} else {
receiverValue = receiver;
- readOnlyReceiver = false;
}
Expression result = _forest.createIndexSet(
fileOffset, receiverValue, index, value,
- forEffect: voidContext, readOnlyReceiver: readOnlyReceiver);
+ forEffect: voidContext);
if (isNullAware) {
result = new NullAwareMethodInvocation(variable, result)
..fileOffset = fileOffset;
@@ -1019,23 +1015,19 @@
{bool voidContext: false}) {
VariableDeclaration variable;
Expression receiverValue;
- bool readOnlyReceiver;
if (isNullAware) {
variable = _forest.createVariableDeclarationForValue(receiver);
receiverValue = _helper.createVariableGet(variable, fileOffset,
forNullGuardedAccess: true);
- readOnlyReceiver = true;
} else {
receiverValue = receiver;
- readOnlyReceiver = false;
}
Expression result = new IfNullIndexSet(receiverValue, index, value,
readOffset: fileOffset,
testOffset: offset,
writeOffset: fileOffset,
- forEffect: voidContext,
- readOnlyReceiver: readOnlyReceiver)
+ forEffect: voidContext)
..fileOffset = offset;
if (isNullAware) {
result = new NullAwareMethodInvocation(variable, result)
@@ -1051,15 +1043,12 @@
bool isPostIncDec: false}) {
VariableDeclaration variable;
Expression receiverValue;
- bool readOnlyReceiver;
if (isNullAware) {
variable = _forest.createVariableDeclarationForValue(receiver);
receiverValue = _helper.createVariableGet(variable, fileOffset,
forNullGuardedAccess: true);
- readOnlyReceiver = true;
} else {
receiverValue = receiver;
- readOnlyReceiver = false;
}
Expression result = new CompoundIndexSet(
@@ -1068,8 +1057,7 @@
binaryOffset: offset,
writeOffset: fileOffset,
forEffect: voidContext,
- forPostIncDec: isPostIncDec,
- readOnlyReceiver: readOnlyReceiver);
+ forPostIncDec: isPostIncDec);
if (isNullAware) {
result = new NullAwareMethodInvocation(variable, result)
..fileOffset = fileOffset;
@@ -1166,7 +1154,7 @@
_reportNonNullableInNullAwareWarningIfNeeded();
Expression receiver = _helper.forest.createThisExpression(fileOffset);
return _forest.createIndexSet(fileOffset, receiver, index, value,
- forEffect: voidContext, readOnlyReceiver: true);
+ forEffect: voidContext);
}
@override
@@ -1178,8 +1166,7 @@
readOffset: fileOffset,
testOffset: offset,
writeOffset: fileOffset,
- forEffect: voidContext,
- readOnlyReceiver: true)
+ forEffect: voidContext)
..fileOffset = offset;
}
@@ -1195,8 +1182,7 @@
binaryOffset: offset,
writeOffset: fileOffset,
forEffect: voidContext,
- forPostIncDec: isPostIncDec,
- readOnlyReceiver: true);
+ forPostIncDec: isPostIncDec);
}
@override
@@ -1723,8 +1709,7 @@
_helper.createVariableGet(extensionThis, fileOffset),
writeTarget,
value,
- forEffect: forEffect,
- readOnlyReceiver: true);
+ forEffect: forEffect);
}
write.fileOffset = offset;
return write;
@@ -2040,24 +2025,22 @@
_helper.createVariableGet(variable, variable.fileOffset,
forNullGuardedAccess: true),
value,
- forEffect: voidContext,
- readOnlyReceiver: true))
+ forEffect: voidContext))
..fileOffset = fileOffset;
} else {
- return _createWrite(fileOffset, receiver, value,
- forEffect: voidContext, readOnlyReceiver: false);
+ return _createWrite(fileOffset, receiver, value, forEffect: voidContext);
}
}
Expression _createWrite(int offset, Expression receiver, Expression value,
- {bool readOnlyReceiver, bool forEffect}) {
+ {bool forEffect}) {
Expression write;
if (writeTarget == null) {
write = _makeInvalidWrite(value);
} else {
write = new ExtensionSet(
extension, explicitTypeArguments, receiver, writeTarget, value,
- readOnlyReceiver: readOnlyReceiver, forEffect: forEffect);
+ forEffect: forEffect);
}
write.fileOffset = offset;
return write;
@@ -2077,8 +2060,7 @@
_helper.createVariableGet(variable, receiver.fileOffset,
forNullGuardedAccess: true),
value,
- forEffect: voidContext,
- readOnlyReceiver: true);
+ forEffect: voidContext);
return new NullAwareExtension(
variable,
new IfNullSet(read, write, forEffect: voidContext)
@@ -2113,13 +2095,11 @@
_helper.createVariableGet(variable, receiver.fileOffset,
forNullGuardedAccess: true),
binary,
- forEffect: voidContext,
- readOnlyReceiver: true);
+ forEffect: voidContext);
return new NullAwareExtension(variable, write)..fileOffset = offset;
} else {
return new CompoundExtensionSet(extension, explicitTypeArguments,
receiver, targetName, readTarget, binaryOperator, value, writeTarget,
- readOnlyReceiver: false,
forEffect: voidContext,
readOffset: fileOffset,
binaryOffset: offset,
@@ -2150,8 +2130,7 @@
_helper.createVariableGet(variable, receiver.fileOffset,
forNullGuardedAccess: true),
binary,
- forEffect: voidContext,
- readOnlyReceiver: true)
+ forEffect: voidContext)
..fileOffset = fileOffset);
return new NullAwareExtension(
variable, new LocalPostIncDec(read, write)..fileOffset = offset)
@@ -2167,7 +2146,7 @@
VariableDeclaration write = _helper.forest
.createVariableDeclarationForValue(_createWrite(fileOffset,
_helper.createVariableGet(variable, receiver.fileOffset), binary,
- forEffect: voidContext, readOnlyReceiver: true)
+ forEffect: voidContext)
..fileOffset = fileOffset);
return new PropertyPostIncDec(variable, read, write)..fileOffset = offset;
}
@@ -2419,15 +2398,12 @@
{bool voidContext: false}) {
VariableDeclaration variable;
Expression receiverValue;
- bool readOnlyReceiver;
if (isNullAware) {
variable = _forest.createVariableDeclarationForValue(receiver);
receiverValue = _helper.createVariableGet(variable, fileOffset,
forNullGuardedAccess: true);
- readOnlyReceiver = true;
} else {
receiverValue = receiver;
- readOnlyReceiver = false;
}
Expression result = new IfNullExtensionIndexSet(
extension,
@@ -2440,8 +2416,7 @@
readOffset: fileOffset,
testOffset: offset,
writeOffset: fileOffset,
- forEffect: voidContext,
- readOnlyReceiver: readOnlyReceiver)
+ forEffect: voidContext)
..fileOffset = offset;
if (isNullAware) {
result = new NullAwareMethodInvocation(variable, result)
@@ -2457,15 +2432,12 @@
bool isPostIncDec: false}) {
VariableDeclaration variable;
Expression receiverValue;
- bool readOnlyReceiver;
if (isNullAware) {
variable = _forest.createVariableDeclarationForValue(receiver);
receiverValue = _helper.createVariableGet(variable, fileOffset,
forNullGuardedAccess: true);
- readOnlyReceiver = true;
} else {
receiverValue = receiver;
- readOnlyReceiver = false;
}
Expression result = new CompoundExtensionIndexSet(
extension,
@@ -2480,8 +2452,7 @@
binaryOffset: offset,
writeOffset: fileOffset,
forEffect: voidContext,
- forPostIncDec: isPostIncDec,
- readOnlyReceiver: readOnlyReceiver);
+ forPostIncDec: isPostIncDec);
if (isNullAware) {
result = new NullAwareMethodInvocation(variable, result)
..fileOffset = fileOffset;
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 273a4e7..75946bb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -706,12 +706,10 @@
IndexSet createIndexSet(
int fileOffset, Expression receiver, Expression index, Expression value,
- {bool forEffect, bool readOnlyReceiver}) {
+ {bool forEffect}) {
assert(fileOffset != null);
assert(forEffect != null);
- assert(readOnlyReceiver != null);
- return new IndexSet(receiver, index, value,
- forEffect: forEffect, readOnlyReceiver: readOnlyReceiver)
+ return new IndexSet(receiver, index, value, forEffect: forEffect)
..fileOffset = fileOffset;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index c5f9600..6dd3745 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -61,20 +61,6 @@
InferenceVisitor(this.inferrer);
- Expression _clone(Expression node) {
- if (node is ThisExpression) {
- return new ThisExpression()..fileOffset = node.fileOffset;
- } else if (node is VariableGet) {
- assert(
- node.variable.isFinal,
- "Trying to clone VariableGet of non-final variable"
- " ${node.variable}.");
- return new VariableGet(node.variable, node.promotedType)
- ..fileOffset = node.fileOffset;
- }
- throw new UnsupportedError("Clone not supported for ${node.runtimeType}.");
- }
-
ExpressionInferenceResult _unhandledExpression(
Expression node, DartType typeContext) {
unhandled("${node.runtimeType}", "InferenceVisitor", node.fileOffset,
@@ -500,7 +486,7 @@
}
VariableDeclaration receiverVariable;
- if (node.forEffect || node.readOnlyReceiver) {
+ if (node.forEffect || isPureExpression(receiver)) {
// No need for receiver variable.
} else {
receiverVariable = createVariable(receiver, receiverResult.inferredType);
@@ -551,9 +537,9 @@
VariableDeclaration receiverVariable;
Expression readReceiver;
Expression writeReceiver;
- if (node.readOnlyReceiver && identical(receiver, node.receiver)) {
+ if (isPureExpression(receiver)) {
readReceiver = receiver;
- writeReceiver = _clone(receiver);
+ writeReceiver = clonePureExpression(receiver);
} else {
receiverVariable = createVariable(receiver, receiverType);
readReceiver = createVariableGet(receiverVariable);
@@ -2749,9 +2735,9 @@
VariableDeclaration receiverVariable;
Expression readReceiver;
Expression writeReceiver;
- if (node.readOnlyReceiver && identical(receiver, node.receiver)) {
+ if (isPureExpression(receiver)) {
readReceiver = receiver;
- writeReceiver = _clone(receiver);
+ writeReceiver = clonePureExpression(receiver);
} else {
receiverVariable = createVariable(receiver, receiverType);
inferrer.instrumentation?.record(
@@ -3004,7 +2990,7 @@
DartType receiverType = receiverResult.nullAwareActionType;
VariableDeclaration receiverVariable;
- if (!node.forEffect && !node.readOnlyReceiver) {
+ if (!node.forEffect && !isPureExpression(receiver)) {
receiverVariable = createVariable(receiver, receiverType);
receiver = createVariableGet(receiverVariable);
}
@@ -3023,7 +3009,7 @@
Expression index = inferrer.ensureAssignableResult(indexType, indexResult);
VariableDeclaration indexVariable;
- if (!node.forEffect) {
+ if (!node.forEffect && !isPureExpression(index)) {
indexVariable = createVariable(index, indexResult.inferredType);
index = createVariableGet(indexVariable);
}
@@ -3033,9 +3019,14 @@
Expression value = inferrer.ensureAssignableResult(valueType, valueResult);
VariableDeclaration valueVariable;
- if (!node.forEffect) {
+ Expression returnedValue;
+ if (node.forEffect) {
+ } else if (isPureExpression(value)) {
+ returnedValue = clonePureExpression(value);
+ } else {
valueVariable = createVariable(value, valueResult.inferredType);
value = createVariableGet(valueVariable);
+ returnedValue = createVariableGet(valueVariable);
}
// The inferred type is that inferred type of the value expression and not
@@ -3049,14 +3040,15 @@
if (node.forEffect) {
replacement = assignment;
} else {
- assert(indexVariable != null);
- assert(valueVariable != null);
VariableDeclaration assignmentVariable =
createVariable(assignment, const VoidType());
- replacement = createLet(
- indexVariable,
- createLet(valueVariable,
- createLet(assignmentVariable, createVariableGet(valueVariable))));
+ replacement = createLet(assignmentVariable, returnedValue);
+ if (valueVariable != null) {
+ replacement = createLet(valueVariable, replacement);
+ }
+ if (indexVariable != null) {
+ replacement = createLet(indexVariable, replacement);
+ }
if (receiverVariable != null) {
replacement = createLet(receiverVariable, replacement);
}
@@ -3083,14 +3075,25 @@
Expression index = inferrer.ensureAssignableResult(indexType, indexResult);
- VariableDeclaration indexVariable =
- createVariable(index, indexResult.inferredType);
+ VariableDeclaration indexVariable;
+ if (!isPureExpression(index)) {
+ indexVariable = createVariable(index, indexResult.inferredType);
+ index = createVariableGet(indexVariable);
+ }
ExpressionInferenceResult valueResult = inferrer
.inferExpression(node.value, valueType, true, isVoidAllowed: true);
Expression value = inferrer.ensureAssignableResult(valueType, valueResult);
- VariableDeclaration valueVariable =
- createVariable(value, valueResult.inferredType);
+
+ VariableDeclaration valueVariable;
+ Expression returnedValue;
+ if (isPureExpression(value)) {
+ returnedValue = clonePureExpression(value);
+ } else {
+ valueVariable = createVariable(value, valueResult.inferredType);
+ value = createVariableGet(valueVariable);
+ returnedValue = createVariableGet(valueVariable);
+ }
// The inferred type is that inferred type of the value expression and not
// the type of the value parameter.
@@ -3098,8 +3101,8 @@
Expression assignment;
if (indexSetTarget.isMissing) {
- assignment = inferrer.createMissingSuperIndexSet(node.fileOffset,
- createVariableGet(indexVariable), createVariableGet(valueVariable));
+ assignment =
+ inferrer.createMissingSuperIndexSet(node.fileOffset, index, value);
} else {
assert(indexSetTarget.isInstanceMember || indexSetTarget.isObjectMember);
inferrer.instrumentation?.record(
@@ -3109,21 +3112,20 @@
new InstrumentationValueForMember(node.setter));
assignment = new SuperMethodInvocation(
indexSetName,
- new Arguments(<Expression>[
- createVariableGet(indexVariable),
- createVariableGet(valueVariable)
- ])
+ new Arguments(<Expression>[index, value])
..fileOffset = node.fileOffset,
indexSetTarget.member)
..fileOffset = node.fileOffset;
}
VariableDeclaration assignmentVariable =
createVariable(assignment, const VoidType());
- Expression replacement = new Let(
- indexVariable,
- createLet(valueVariable,
- createLet(assignmentVariable, createVariableGet(valueVariable))))
- ..fileOffset = node.fileOffset;
+ Expression replacement = createLet(assignmentVariable, returnedValue);
+ if (valueVariable != null) {
+ replacement = createLet(valueVariable, replacement);
+ }
+ if (indexVariable != null) {
+ replacement = createLet(indexVariable, replacement);
+ }
return new ExpressionInferenceResult(inferredType, replacement);
}
@@ -3143,8 +3145,11 @@
Expression receiver =
inferrer.ensureAssignableResult(receiverType, receiverResult);
- VariableDeclaration receiverVariable =
- createVariable(receiver, receiverType);
+ VariableDeclaration receiverVariable;
+ if (!isPureExpression(receiver)) {
+ receiverVariable = createVariable(receiver, receiverType);
+ receiver = createVariableGet(receiverVariable);
+ }
ObjectAccessTarget target = new ExtensionAccessTarget(
node.setter, null, ProcedureKind.Operator, extensionTypeArguments);
@@ -3157,40 +3162,38 @@
Expression index = inferrer.ensureAssignableResult(indexType, indexResult);
- VariableDeclaration indexVariable =
- createVariable(index, indexResult.inferredType);
-
ExpressionInferenceResult valueResult = inferrer
.inferExpression(node.value, valueType, true, isVoidAllowed: true);
Expression value = inferrer.ensureAssignableResult(valueType, valueResult);
- VariableDeclaration valueVariable =
- createVariable(value, valueResult.inferredType);
+
+ VariableDeclaration valueVariable;
+ Expression returnedValue;
+ if (isPureExpression(value)) {
+ returnedValue = clonePureExpression(value);
+ } else {
+ valueVariable = createVariable(value, valueResult.inferredType);
+ value = createVariableGet(valueVariable);
+ returnedValue = createVariableGet(valueVariable);
+ }
// The inferred type is that inferred type of the value expression and not
// the type of the value parameter.
DartType inferredType = valueResult.inferredType;
- Expression assignment = _computeIndexSet(
- node.fileOffset,
- createVariableGet(receiverVariable),
- receiverType,
- target,
- createVariableGet(indexVariable),
- indexType,
- createVariableGet(valueVariable),
- valueType);
+ Expression assignment = _computeIndexSet(node.fileOffset, receiver,
+ receiverType, target, index, indexType, value, valueType);
VariableDeclaration assignmentVariable =
createVariable(assignment, const VoidType());
- Expression replacement = new Let(
- receiverVariable,
- createLet(
- indexVariable,
- createLet(
- valueVariable,
- createLet(
- assignmentVariable, createVariableGet(valueVariable)))))
- ..fileOffset = node.fileOffset;
+ Expression replacement = createLet(assignmentVariable, returnedValue);
+ if (valueVariable != null) {
+ replacement = createLet(valueVariable, replacement);
+ }
+ if (receiverVariable != null) {
+ replacement = createLet(receiverVariable, replacement);
+ }
+ replacement.fileOffset = node.fileOffset;
+
return new ExpressionInferenceResult(inferredType, replacement);
}
@@ -3207,8 +3210,8 @@
VariableDeclaration receiverVariable;
Expression readReceiver = receiver;
Expression writeReceiver;
- if (node.readOnlyReceiver && identical(receiver, node.receiver)) {
- writeReceiver = _clone(readReceiver);
+ if (isPureExpression(readReceiver)) {
+ writeReceiver = clonePureExpression(readReceiver);
} else {
receiverVariable = createVariable(readReceiver, receiverType);
readReceiver = createVariableGet(receiverVariable);
@@ -3237,9 +3240,17 @@
ExpressionInferenceResult indexResult = inferrer
.inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
- VariableDeclaration indexVariable = createVariableForResult(indexResult);
+ VariableDeclaration indexVariable;
+ Expression readIndex = indexResult.expression;
+ Expression writeIndex;
+ if (isPureExpression(readIndex)) {
+ writeIndex = clonePureExpression(readIndex);
+ } else {
+ indexVariable = createVariable(readIndex, indexResult.inferredType);
+ readIndex = createVariableGet(indexVariable);
+ writeIndex = createVariableGet(indexVariable);
+ }
- Expression readIndex = createVariableGet(indexVariable);
readIndex = inferrer.ensureAssignable(
readIndexType, indexResult.inferredType, readIndex);
@@ -3261,7 +3272,6 @@
.findInterfaceMember(readType, equalsName, node.testOffset)
.member;
- Expression writeIndex = createVariableGet(indexVariable);
writeIndex = inferrer.ensureAssignable(
writeIndexType, indexResult.inferredType, writeIndex);
@@ -3276,11 +3286,15 @@
inferrer.library.library);
VariableDeclaration valueVariable;
+ Expression returnedValue;
if (node.forEffect) {
// No need for value variable.
+ } else if (isPureExpression(value)) {
+ returnedValue = clonePureExpression(value);
} else {
valueVariable = createVariable(value, valueResult.inferredType);
value = createVariableGet(valueVariable);
+ returnedValue = createVariableGet(valueVariable);
}
Expression write = _computeIndexSet(
@@ -3313,7 +3327,7 @@
ConditionalExpression conditional = new ConditionalExpression(equalsNull,
write, new NullLiteral()..fileOffset = node.testOffset, inferredType)
..fileOffset = node.testOffset;
- inner = createLet(indexVariable, conditional);
+ inner = conditional;
} else {
// Encode `Extension(o)[a] ??= b` as, if `node.readOnlyReceiver` is false,
// as:
@@ -3339,8 +3353,6 @@
// : readVariable
//
//
- assert(valueVariable != null);
-
VariableDeclaration readVariable = createVariable(read, readType);
Expression equalsNull = inferrer.createEqualsNull(
node.testOffset, createVariableGet(readVariable), equalsMember);
@@ -3351,14 +3363,17 @@
!identical(nonNullableReadType, readType)) {
variableGet.promotedType = nonNullableReadType;
}
+ Expression result = createLet(writeVariable, returnedValue);
+ if (valueVariable != null) {
+ result = createLet(valueVariable, result);
+ }
ConditionalExpression conditional = new ConditionalExpression(
- equalsNull,
- createLet(valueVariable,
- createLet(writeVariable, createVariableGet(valueVariable))),
- variableGet,
- inferredType)
+ equalsNull, result, variableGet, inferredType)
..fileOffset = node.fileOffset;
- inner = createLet(indexVariable, createLet(readVariable, conditional));
+ inner = createLet(readVariable, conditional);
+ }
+ if (indexVariable != null) {
+ inner = createLet(indexVariable, inner);
}
Expression replacement;
@@ -3402,13 +3417,20 @@
ExpressionInferenceResult indexResult = inferrer
.inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
- VariableDeclaration indexVariable = createVariableForResult(indexResult);
+ VariableDeclaration indexVariable;
+ Expression readIndex = indexResult.expression;
+ Expression writeIndex;
+ if (isPureExpression(readIndex)) {
+ writeIndex = clonePureExpression(readIndex);
+ } else {
+ indexVariable = createVariable(readIndex, indexResult.inferredType);
+ readIndex = createVariableGet(indexVariable);
+ writeIndex = createVariableGet(indexVariable);
+ }
- Expression readIndex = createVariableGet(indexVariable);
readIndex = inferrer.ensureAssignable(
readIndexType, indexResult.inferredType, readIndex);
- Expression writeIndex = createVariableGet(indexVariable);
writeIndex = inferrer.ensureAssignable(
writeIndexType, indexResult.inferredType, writeIndex);
@@ -3445,11 +3467,15 @@
inferrer.library.library);
VariableDeclaration valueVariable;
+ Expression returnedValue;
if (node.forEffect) {
// No need for a value variable.
+ } else if (isPureExpression(value)) {
+ returnedValue = clonePureExpression(value);
} else {
valueVariable = createVariable(value, valueResult.inferredType);
value = createVariableGet(valueVariable);
+ returnedValue = createVariableGet(valueVariable);
}
Expression write;
@@ -3479,12 +3505,12 @@
// let v1 = a in
// super[v1] == null ? super.[]=(v1, b) : null
//
+ assert(valueVariable == null);
Expression equalsNull =
inferrer.createEqualsNull(node.testOffset, read, equalsMember);
- ConditionalExpression conditional = new ConditionalExpression(equalsNull,
- write, new NullLiteral()..fileOffset = node.testOffset, inferredType)
+ replacement = new ConditionalExpression(equalsNull, write,
+ new NullLiteral()..fileOffset = node.testOffset, inferredType)
..fileOffset = node.testOffset;
- replacement = createLet(indexVariable, conditional);
} else {
// Encode `o[a] ??= b` as:
//
@@ -3496,29 +3522,29 @@
// v3)
// : v2
//
- assert(valueVariable != null);
VariableDeclaration readVariable = createVariable(read, readType);
Expression equalsNull = inferrer.createEqualsNull(
node.testOffset, createVariableGet(readVariable), equalsMember);
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- VariableGet variableGet = createVariableGet(readVariable);
+ VariableGet readVariableGet = createVariableGet(readVariable);
if (inferrer.library.isNonNullableByDefault &&
!identical(nonNullableReadType, readType)) {
- variableGet.promotedType = nonNullableReadType;
+ readVariableGet.promotedType = nonNullableReadType;
+ }
+ Expression result = createLet(writeVariable, returnedValue);
+ if (valueVariable != null) {
+ result = createLet(valueVariable, result);
}
ConditionalExpression conditional = new ConditionalExpression(
- equalsNull,
- createLet(valueVariable,
- createLet(writeVariable, createVariableGet(valueVariable))),
- variableGet,
- inferredType)
+ equalsNull, result, readVariableGet, inferredType)
..fileOffset = node.fileOffset;
- replacement =
- createLet(indexVariable, createLet(readVariable, conditional));
+ replacement = createLet(readVariable, conditional);
}
-
+ if (indexVariable != null) {
+ replacement = createLet(indexVariable, replacement);
+ }
return new ExpressionInferenceResult(inferredType, replacement);
}
@@ -3541,9 +3567,9 @@
VariableDeclaration receiverVariable;
Expression readReceiver;
Expression writeReceiver;
- if (node.readOnlyReceiver && identical(receiver, node.receiver)) {
+ if (isPureExpression(receiver)) {
readReceiver = receiver;
- writeReceiver = _clone(receiver);
+ writeReceiver = clonePureExpression(receiver);
} else {
receiverVariable = createVariable(receiver, receiverType);
readReceiver = createVariableGet(receiverVariable);
@@ -3570,9 +3596,17 @@
ExpressionInferenceResult indexResult = inferrer
.inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
- VariableDeclaration indexVariable = createVariableForResult(indexResult);
+ VariableDeclaration indexVariable;
+ Expression readIndex = indexResult.expression;
+ Expression writeIndex;
+ if (isPureExpression(readIndex)) {
+ writeIndex = clonePureExpression(readIndex);
+ } else {
+ indexVariable = createVariable(readIndex, indexResult.inferredType);
+ readIndex = createVariableGet(indexVariable);
+ writeIndex = createVariableGet(indexVariable);
+ }
- Expression readIndex = createVariableGet(indexVariable);
readIndex = inferrer.ensureAssignable(
readIndexType, indexResult.inferredType, readIndex);
@@ -3594,7 +3628,6 @@
.findInterfaceMember(readType, equalsName, node.testOffset)
.member;
- Expression writeIndex = createVariableGet(indexVariable);
writeIndex = inferrer.ensureAssignable(
writeIndexType, indexResult.inferredType, writeIndex);
@@ -3609,11 +3642,15 @@
inferrer.library.library);
VariableDeclaration valueVariable;
+ Expression returnedValue;
if (node.forEffect) {
// No need for a value variable.
+ } else if (isPureExpression(value)) {
+ returnedValue = clonePureExpression(value);
} else {
valueVariable = createVariable(value, valueResult.inferredType);
value = createVariableGet(valueVariable);
+ returnedValue = createVariableGet(valueVariable);
}
Expression write = _computeIndexSet(
@@ -3635,12 +3672,12 @@
// receiverVariable[indexVariable] == null
// ? receiverVariable.[]=(indexVariable, b) : null
//
+ assert(valueVariable == null);
Expression equalsNull =
inferrer.createEqualsNull(node.testOffset, read, equalsMember);
- ConditionalExpression conditional = new ConditionalExpression(equalsNull,
- write, new NullLiteral()..fileOffset = node.testOffset, inferredType)
+ replacement = new ConditionalExpression(equalsNull, write,
+ new NullLiteral()..fileOffset = node.testOffset, inferredType)
..fileOffset = node.testOffset;
- replacement = createLet(indexVariable, conditional);
} else {
// Encode `Extension(o)[a] ??= b` as:
//
@@ -3654,27 +3691,27 @@
// valueVariable)
// : readVariable
//
- assert(valueVariable != null);
-
VariableDeclaration readVariable = createVariable(read, readType);
Expression equalsNull = inferrer.createEqualsNull(
node.testOffset, createVariableGet(readVariable), equalsMember);
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- VariableGet variableGet = createVariableGet(readVariable);
+ VariableGet readVariableGet = createVariableGet(readVariable);
if (inferrer.library.isNonNullableByDefault &&
!identical(nonNullableReadType, readType)) {
- variableGet.promotedType = nonNullableReadType;
+ readVariableGet.promotedType = nonNullableReadType;
+ }
+ Expression result = createLet(writeVariable, returnedValue);
+ if (valueVariable != null) {
+ result = createLet(valueVariable, result);
}
ConditionalExpression conditional = new ConditionalExpression(
- equalsNull,
- createLet(valueVariable,
- createLet(writeVariable, createVariableGet(valueVariable))),
- variableGet,
- inferredType)
+ equalsNull, result, readVariableGet, inferredType)
..fileOffset = node.fileOffset;
- replacement =
- createLet(indexVariable, createLet(readVariable, conditional));
+ replacement = createLet(readVariable, conditional);
+ }
+ if (indexVariable != null) {
+ replacement = createLet(indexVariable, replacement);
}
if (receiverVariable != null) {
replacement = new Let(receiverVariable, replacement);
@@ -4384,14 +4421,12 @@
case ObjectAccessTargetKind.missing:
write = inferrer.createMissingIndexSet(
fileOffset, receiver, receiverType, index, value,
- forEffect: true, readOnlyReceiver: true);
+ forEffect: true);
break;
case ObjectAccessTargetKind.ambiguous:
write = inferrer.createMissingIndexSet(
fileOffset, receiver, receiverType, index, value,
- forEffect: true,
- readOnlyReceiver: true,
- extensionAccessCandidates: writeTarget.candidates);
+ forEffect: true, extensionAccessCandidates: writeTarget.candidates);
break;
case ObjectAccessTargetKind.extensionMember:
case ObjectAccessTargetKind.nullableExtensionMember:
@@ -4858,8 +4893,8 @@
VariableDeclaration receiverVariable;
Expression readReceiver = receiver;
Expression writeReceiver;
- if (node.readOnlyReceiver) {
- writeReceiver = _clone(readReceiver);
+ if (isPureExpression(readReceiver)) {
+ writeReceiver = clonePureExpression(readReceiver);
} else {
receiverVariable = createVariable(readReceiver, receiverType);
readReceiver = createVariableGet(receiverVariable);
@@ -4878,9 +4913,18 @@
ExpressionInferenceResult indexResult = inferrer
.inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
- VariableDeclaration indexVariable = createVariableForResult(indexResult);
- Expression readIndex = createVariableGet(indexVariable);
+ VariableDeclaration indexVariable;
+ Expression readIndex = indexResult.expression;
+ Expression writeIndex;
+ if (isPureExpression(readIndex)) {
+ writeIndex = clonePureExpression(readIndex);
+ } else {
+ indexVariable = createVariable(readIndex, indexResult.inferredType);
+ readIndex = createVariableGet(indexVariable);
+ writeIndex = createVariableGet(indexVariable);
+ }
+
readIndex = inferrer.ensureAssignable(
readIndexType, indexResult.inferredType, readIndex);
@@ -4926,7 +4970,6 @@
Expression binary = binaryResult.expression;
DartType binaryType = binaryResult.inferredType;
- Expression writeIndex = createVariableGet(indexVariable);
writeIndex = inferrer.ensureAssignable(
writeIndexType, indexResult.inferredType, writeIndex);
@@ -4960,7 +5003,7 @@
//
// let v1 = o in let v2 = a in v1.[]=(v2, v1.[](v2) + b)
//
- inner = createLet(indexVariable, write);
+ inner = write;
} else if (node.forPostIncDec) {
// Encode `o[a]++` as:
//
@@ -4974,10 +5017,8 @@
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- inner = createLet(
- indexVariable,
- createLet(leftVariable,
- createLet(writeVariable, createVariableGet(leftVariable))));
+ inner = createLet(leftVariable,
+ createLet(writeVariable, createVariableGet(leftVariable)));
} else {
// Encode `o[a] += b` as:
//
@@ -4991,10 +5032,11 @@
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- inner = createLet(
- indexVariable,
- createLet(valueVariable,
- createLet(writeVariable, createVariableGet(valueVariable))));
+ inner = createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable)));
+ }
+ if (indexVariable != null) {
+ inner = createLet(indexVariable, inner);
}
Expression replacement;
@@ -5156,9 +5198,18 @@
ExpressionInferenceResult indexResult = inferrer
.inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
- VariableDeclaration indexVariable = createVariableForResult(indexResult);
- Expression readIndex = createVariableGet(indexVariable);
+ VariableDeclaration indexVariable;
+ Expression readIndex = indexResult.expression;
+ Expression writeIndex;
+ if (isPureExpression(readIndex)) {
+ writeIndex = clonePureExpression(readIndex);
+ } else {
+ indexVariable = createVariable(readIndex, indexResult.inferredType);
+ readIndex = createVariableGet(indexVariable);
+ writeIndex = createVariableGet(indexVariable);
+ }
+
readIndex = inferrer.ensureAssignable(
readIndexType, indexResult.inferredType, readIndex);
@@ -5213,7 +5264,6 @@
Expression binary = binaryResult.expression;
DartType binaryType = binaryResult.inferredType;
- Expression writeIndex = createVariableGet(indexVariable);
writeIndex = inferrer.ensureAssignable(
writeIndexType, indexResult.inferredType, writeIndex);
@@ -5260,7 +5310,7 @@
//
// let v1 = a in super.[]=(v1, super.[](v1) + b)
//
- replacement = createLet(indexVariable, write);
+ replacement = write;
} else if (node.forPostIncDec) {
// Encode `super[a]++` as:
//
@@ -5273,10 +5323,8 @@
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- replacement = createLet(
- indexVariable,
- createLet(leftVariable,
- createLet(writeVariable, createVariableGet(leftVariable))));
+ replacement = createLet(leftVariable,
+ createLet(writeVariable, createVariableGet(leftVariable)));
} else {
// Encode `super[a] += b` as:
//
@@ -5290,12 +5338,12 @@
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- replacement = createLet(
- indexVariable,
- createLet(valueVariable,
- createLet(writeVariable, createVariableGet(valueVariable))));
+ replacement = createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable)));
}
-
+ if (indexVariable != null) {
+ replacement = createLet(indexVariable, replacement);
+ }
return new ExpressionInferenceResult(
node.forPostIncDec ? readType : binaryType, replacement);
}
@@ -5324,9 +5372,9 @@
VariableDeclaration receiverVariable;
Expression readReceiver;
Expression writeReceiver;
- if (node.readOnlyReceiver && identical(receiver, node.receiver)) {
+ if (isPureExpression(receiver)) {
readReceiver = receiver;
- writeReceiver = _clone(receiver);
+ writeReceiver = clonePureExpression(receiver);
} else {
receiverVariable = createVariable(receiver, receiverType);
readReceiver = createVariableGet(receiverVariable);
@@ -5337,9 +5385,18 @@
ExpressionInferenceResult indexResult = inferrer
.inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
- VariableDeclaration indexVariable = createVariableForResult(indexResult);
- Expression readIndex = createVariableGet(indexVariable);
+ VariableDeclaration indexVariable;
+ Expression readIndex = indexResult.expression;
+ Expression writeIndex;
+ if (isPureExpression(readIndex)) {
+ writeIndex = clonePureExpression(readIndex);
+ } else {
+ indexVariable = createVariable(readIndex, indexResult.inferredType);
+ readIndex = createVariableGet(indexVariable);
+ writeIndex = createVariableGet(indexVariable);
+ }
+
readIndex = inferrer.ensureAssignable(
readIndexType, indexResult.inferredType, readIndex);
@@ -5387,7 +5444,6 @@
Expression binary = binaryResult.expression;
DartType binaryType = binaryResult.inferredType;
- Expression writeIndex = createVariableGet(indexVariable);
writeIndex = inferrer.ensureAssignable(
writeIndexType, indexResult.inferredType, writeIndex);
binary = inferrer.ensureAssignable(valueType, binaryType, binary,
@@ -5422,7 +5478,7 @@
// let indexVariable = a in
// receiverVariable.[]=(receiverVariable, o.[](indexVariable) + b)
//
- replacement = createLet(indexVariable, write);
+ replacement = write;
} else if (node.forPostIncDec) {
// Encode `Extension(o)[a]++` as:
//
@@ -5438,10 +5494,8 @@
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- replacement = createLet(
- indexVariable,
- createLet(leftVariable,
- createLet(writeVariable, createVariableGet(leftVariable))));
+ replacement = createLet(leftVariable,
+ createLet(writeVariable, createVariableGet(leftVariable)));
} else {
// Encode `Extension(o)[a] += b` as:
//
@@ -5457,12 +5511,12 @@
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- replacement = createLet(
- indexVariable,
- createLet(valueVariable,
- createLet(writeVariable, createVariableGet(valueVariable))));
+ replacement = createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable)));
}
-
+ if (indexVariable != null) {
+ replacement = createLet(indexVariable, replacement);
+ }
if (receiverVariable != null) {
replacement = new Let(receiverVariable, replacement);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 56a9bd8..1f6acdd 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -1785,10 +1785,6 @@
/// The member used for the write operation.
final Member setter;
- /// If `true`, the receiver is read-only and therefore doesn't need a
- /// temporary variable for its value.
- final bool readOnlyReceiver;
-
/// If `true`, the expression is only need for effect and not for its value.
final bool forEffect;
@@ -1810,13 +1806,11 @@
this.binaryName,
this.rhs,
this.setter,
- {this.readOnlyReceiver,
- this.forEffect,
+ {this.forEffect,
this.readOffset,
this.binaryOffset,
this.writeOffset})
- : assert(readOnlyReceiver != null),
- assert(forEffect != null),
+ : assert(forEffect != null),
assert(readOffset != null),
assert(binaryOffset != null),
assert(writeOffset != null) {
@@ -1885,10 +1879,6 @@
/// If `true`, the expression is only need for effect and not for its value.
final bool forEffect;
- /// If `true`, the receiver is read-only and therefore doesn't need a
- /// temporary variable for its value.
- final bool readOnlyReceiver;
-
/// The file offset for the read operation.
final int readOffset;
@@ -1900,13 +1890,8 @@
CompoundPropertySet(
this.receiver, this.propertyName, this.binaryName, this.rhs,
- {this.forEffect,
- this.readOnlyReceiver,
- this.readOffset,
- this.binaryOffset,
- this.writeOffset})
+ {this.forEffect, this.readOffset, this.binaryOffset, this.writeOffset})
: assert(forEffect != null),
- assert(readOnlyReceiver != null),
assert(readOffset != null),
assert(binaryOffset != null),
assert(writeOffset != null) {
@@ -2253,12 +2238,8 @@
final bool forEffect;
- final bool readOnlyReceiver;
-
- IndexSet(this.receiver, this.index, this.value,
- {this.forEffect, this.readOnlyReceiver})
- : assert(forEffect != null),
- assert(readOnlyReceiver != null) {
+ IndexSet(this.receiver, this.index, this.value, {this.forEffect})
+ : assert(forEffect != null) {
receiver?.parent = this;
index?.parent = this;
value?.parent = this;
@@ -2446,6 +2427,20 @@
String toString() {
return "ExtensionIndexSet(${toStringInternal()})";
}
+
+ @override
+ void toTextInternal(AstPrinter printer) {
+ printer.write(extension.name);
+ if (explicitTypeArguments != null) {
+ printer.writeTypeArguments(explicitTypeArguments);
+ }
+ printer.write('(');
+ printer.writeExpression(receiver);
+ printer.write(')[');
+ printer.writeExpression(index);
+ printer.write('] = ');
+ printer.writeExpression(value);
+ }
}
/// Internal expression representing an if-null index assignment.
@@ -2493,16 +2488,8 @@
/// If `true`, the expression is only need for effect and not for its value.
final bool forEffect;
- /// If `true`, the receiver is read-only and therefore doesn't need a
- /// temporary variable for its value.
- final bool readOnlyReceiver;
-
IfNullIndexSet(this.receiver, this.index, this.value,
- {this.readOffset,
- this.testOffset,
- this.writeOffset,
- this.forEffect,
- this.readOnlyReceiver: false})
+ {this.readOffset, this.testOffset, this.writeOffset, this.forEffect})
: assert(readOffset != null),
assert(testOffset != null),
assert(writeOffset != null),
@@ -2688,24 +2675,15 @@
/// If `true`, the expression is only need for effect and not for its value.
final bool forEffect;
- /// If `true`, the receiver is read-only and therefore doesn't need a
- /// temporary variable for its value.
- final bool readOnlyReceiver;
-
IfNullExtensionIndexSet(this.extension, this.explicitTypeArguments,
this.receiver, this.getter, this.setter, this.index, this.value,
- {this.readOffset,
- this.testOffset,
- this.writeOffset,
- this.forEffect,
- this.readOnlyReceiver})
+ {this.readOffset, this.testOffset, this.writeOffset, this.forEffect})
: assert(explicitTypeArguments == null ||
explicitTypeArguments.length == extension.typeParameters.length),
assert(readOffset != null),
assert(testOffset != null),
assert(writeOffset != null),
- assert(forEffect != null),
- assert(readOnlyReceiver != null) {
+ assert(forEffect != null) {
receiver?.parent = this;
index?.parent = this;
value?.parent = this;
@@ -2792,17 +2770,12 @@
/// If `true`, the expression is a post-fix inc/dec expression.
final bool forPostIncDec;
- /// If `true`, the receiver is read-only and therefore doesn't need a
- /// temporary variable for its value.
- final bool readOnlyReceiver;
-
CompoundIndexSet(this.receiver, this.index, this.binaryName, this.rhs,
{this.readOffset,
this.binaryOffset,
this.writeOffset,
this.forEffect,
- this.forPostIncDec,
- this.readOnlyReceiver: false})
+ this.forPostIncDec})
: assert(forEffect != null) {
receiver?.parent = this;
index?.parent = this;
@@ -3248,10 +3221,6 @@
/// If `true`, the expression is a post-fix inc/dec expression.
final bool forPostIncDec;
- /// If `true` the receiver can be cloned instead of creating a temporary
- /// variable.
- final bool readOnlyReceiver;
-
CompoundExtensionIndexSet(
this.extension,
this.explicitTypeArguments,
@@ -3265,16 +3234,14 @@
this.binaryOffset,
this.writeOffset,
this.forEffect,
- this.forPostIncDec,
- this.readOnlyReceiver})
+ this.forPostIncDec})
: assert(explicitTypeArguments == null ||
explicitTypeArguments.length == extension.typeParameters.length),
assert(readOffset != null),
assert(binaryOffset != null),
assert(writeOffset != null),
assert(forEffect != null),
- assert(forPostIncDec != null),
- assert(readOnlyReceiver != null) {
+ assert(forPostIncDec != null) {
receiver?.parent = this;
index?.parent = this;
rhs?.parent = this;
@@ -3359,16 +3326,11 @@
/// value.
final bool forEffect;
- /// If `true` the receiver can be cloned instead of creating a temporary
- /// variable.
- final bool readOnlyReceiver;
-
ExtensionSet(this.extension, this.explicitTypeArguments, this.receiver,
this.target, this.value,
- {this.readOnlyReceiver, this.forEffect})
+ {this.forEffect})
: assert(explicitTypeArguments == null ||
explicitTypeArguments.length == extension.typeParameters.length),
- assert(readOnlyReceiver != null),
assert(forEffect != null) {
receiver?.parent = this;
value?.parent = this;
@@ -3776,3 +3738,33 @@
return new ExpressionStatement(expression)
..fileOffset = expression.fileOffset;
}
+
+/// Returns `true` if [node] is a pure expression.
+///
+/// A pure expression is an expression that is deterministic and side effect
+/// free, such as `this` or a variable get of a final variable.
+bool isPureExpression(Expression node) {
+ if (node is ThisExpression) {
+ return true;
+ } else if (node is VariableGet) {
+ return node.variable.isFinal && !node.variable.isLate;
+ }
+ return false;
+}
+
+/// Returns a clone of [node].
+///
+/// This assumes that `isPureExpression(node)` is `true`.
+Expression clonePureExpression(Expression node) {
+ if (node is ThisExpression) {
+ return new ThisExpression()..fileOffset = node.fileOffset;
+ } else if (node is VariableGet) {
+ assert(
+ node.variable.isFinal && !node.variable.isLate,
+ "Trying to clone VariableGet of non-final variable"
+ " ${node.variable}.");
+ return new VariableGet(node.variable, node.promotedType)
+ ..fileOffset = node.fileOffset;
+ }
+ throw new UnsupportedError("Clone not supported for ${node.runtimeType}.");
+}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 0324ac4..830562f 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -3949,13 +3949,11 @@
Expression createMissingIndexSet(int fileOffset, Expression receiver,
DartType receiverType, Expression index, Expression value,
{bool forEffect,
- bool readOnlyReceiver,
List<ExtensionAccessCandidate> extensionAccessCandidates}) {
assert(forEffect != null);
- assert(readOnlyReceiver != null);
if (isTopLevel) {
return engine.forest.createIndexSet(fileOffset, receiver, index, value,
- forEffect: forEffect, readOnlyReceiver: readOnlyReceiver);
+ forEffect: forEffect);
} else {
return _reportMissingOrAmbiguousMember(
fileOffset,
diff --git a/pkg/front_end/lib/src/fasta/util/textual_outline.dart b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
index 676582d..6b5d823 100644
--- a/pkg/front_end/lib/src/fasta/util/textual_outline.dart
+++ b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
@@ -11,6 +11,9 @@
import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart';
+import 'package:_fe_analyzer_shared/src/scanner/abstract_scanner.dart'
+ show ScannerConfiguration;
+
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
show ErrorToken, LanguageVersionToken, Scanner;
@@ -418,7 +421,8 @@
// "show A, B, C hide A show A" would be empty.
String textualOutline(List<int> rawBytes,
- {bool throwOnUnexpected: false,
+ {ScannerConfiguration configuration,
+ bool throwOnUnexpected: false,
bool performModelling: false,
bool addMarkerForUnknownForTest: false}) {
Uint8List bytes = new Uint8List(rawBytes.length + 1);
@@ -428,8 +432,9 @@
BoxedInt originalPosition = new BoxedInt(0);
- Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: false,
- languageVersionChanged:
+ Utf8BytesScanner scanner = new Utf8BytesScanner(bytes,
+ includeComments: false,
+ configuration: configuration, languageVersionChanged:
(Scanner scanner, LanguageVersionToken languageVersion) {
parsedChunks.add(
new _LanguageVersionChunk(languageVersion.major, languageVersion.minor)
diff --git a/pkg/front_end/test/fasta/textual_outline_suite.dart b/pkg/front_end/test/fasta/textual_outline_suite.dart
index 702b2fc..f0dbb30 100644
--- a/pkg/front_end/test/fasta/textual_outline_suite.dart
+++ b/pkg/front_end/test/fasta/textual_outline_suite.dart
@@ -6,6 +6,9 @@
import 'dart:io';
+import 'package:_fe_analyzer_shared/src/scanner/abstract_scanner.dart'
+ show ScannerConfiguration;
+
import 'package:dart_style/dart_style.dart' show DartFormatter;
import 'package:front_end/src/fasta/util/textual_outline.dart';
@@ -78,7 +81,9 @@
String result = textualOutline(bytes,
throwOnUnexpected: true,
performModelling: modelled,
- addMarkerForUnknownForTest: modelled);
+ addMarkerForUnknownForTest: modelled,
+ configuration:
+ const ScannerConfiguration(enableExtensionMethods: true));
if (result == null) {
return new Result(
null, context.expectationSet["EmptyOutput"], description.uri);
diff --git a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
index 7279fce..c0fd0e7a 100644
--- a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
+++ b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
@@ -588,7 +588,6 @@
readOffset: TreeNode.noOffset,
binaryOffset: TreeNode.noOffset,
writeOffset: TreeNode.noOffset,
- readOnlyReceiver: false,
forEffect: false),
'''
0.foo += 1''');
@@ -608,7 +607,27 @@
void _testSuperIndexSet() {}
-void _testExtensionIndexSet() {}
+void _testExtensionIndexSet() {
+ Library library = new Library(dummyUri);
+ Extension extension = new Extension(
+ name: 'Extension', typeParameters: [new TypeParameter('T')]);
+ library.addExtension(extension);
+ Procedure setter =
+ new Procedure(new Name(''), ProcedureKind.Method, new FunctionNode(null));
+ library.addProcedure(setter);
+
+ testExpression(
+ new ExtensionIndexSet(extension, null, new IntLiteral(0), setter,
+ new IntLiteral(1), new IntLiteral(2)),
+ '''
+Extension(0)[1] = 2''');
+
+ testExpression(
+ new ExtensionIndexSet(extension, [const VoidType()], new IntLiteral(0),
+ setter, new IntLiteral(1), new IntLiteral(2)),
+ '''
+Extension<void>(0)[1] = 2''');
+}
void _testIfNullIndexSet() {}
diff --git a/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect
index 94df769..cdead34 100644
--- a/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect
@@ -1,7 +1,24 @@
-extension A ;
-on C (){}
-extension B ;
-on C (){}
+extension A on C {
+ void method() {}
+ int get getter => 42;
+ void set setter(int value) {}
+ int get property => 42;
+ int operator +(int i) => i;
+ int operator -() => 0;
+ int operator [](int i) => i;
+}
+
+extension B on C {
+ void method() {}
+ int get getter => 42;
+ void set setter(int value) {}
+ void set property(int value) {}
+ int operator +(int i) => i;
+ int operator -() => 0;
+ void operator []=(int i, int j) {}
+}
+
class C {}
+
errors(C c) {}
main() {}
diff --git a/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..181cba7e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+class C {}
+
+errors(C c) {}
+
+extension A on C {
+ int get getter => 42;
+ int get property => 42;
+ int operator +(int i) => i;
+ int operator -() => 0;
+ int operator [](int i) => i;
+ void method() {}
+ void set setter(int value) {}
+}
+
+extension B on C {
+ int get getter => 42;
+ int operator +(int i) => i;
+ int operator -() => 0;
+ void method() {}
+ void operator []=(int i, int j) {}
+ void set property(int value) {}
+ void set setter(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect
index dc4aa33..29e0b7f 100644
--- a/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect
@@ -4,8 +4,14 @@
@pragma('dart2js:noInline')
static staticMethod() {}
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ @pragma('dart2js:noInline')
+ extensionInstanceMethod() {}
+ @pragma('dart2js:noInline')
+ static extensionStaticMethod() {}
+}
+
@pragma('dart2js:noInline')
topLevelMethod() {}
main() {}
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/annotations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ad11530
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/annotations.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class Class {
+ @pragma('dart2js:noInline')
+ instanceMethod() {}
+ @pragma('dart2js:noInline')
+ static staticMethod() {}
+}
+
+extension Extension on Class {
+ @pragma('dart2js:noInline')
+ extensionInstanceMethod() {}
+ @pragma('dart2js:noInline')
+ static extensionStaticMethod() {}
+}
+
+main() {}
+@pragma('dart2js:noInline')
+topLevelMethod() {}
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.textual_outline.expect
index 49c2279..101e634 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.textual_outline.expect
@@ -1,3 +1,7 @@
-extension Extension ;
-on int (){}
+extension Extension on int {
+ syncStarMethod() sync* {}
+ asyncMethod() async {}
+ asyncStarMethod() async* {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52c36dd
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+extension Extension on int {
+ asyncMethod() async {}
+ asyncStarMethod() async* {}
+ syncStarMethod() sync* {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/bounds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/bounds.dart.textual_outline.expect
index fe2d23d..fe4b2b0 100644
--- a/pkg/front_end/testcases/extensions/bounds.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/bounds.dart.textual_outline.expect
@@ -1,9 +1,29 @@
-extension Extension1<T extends Object> (){}
-on T (){}
-extension Extension2<T extends String> (){}
-on T (){}
-extension Extension3<T extends dynamic> (){}
-on T (){}
-extension Extension4<T> (){}
-on T (){}
+extension Extension1<T extends Object> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+}
+
+extension Extension2<T extends String> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+}
+
+extension Extension3<T extends dynamic> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+}
+
+extension Extension4<T> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe4b2b0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,29 @@
+extension Extension1<T extends Object> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+}
+
+extension Extension2<T extends String> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+}
+
+extension Extension3<T extends dynamic> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+}
+
+extension Extension4<T> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect
index fe33481..3fef925 100644
--- a/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect
@@ -1,7 +1,7 @@
-extension ;
-mixin on int {}
-extension extension ;
-on int (){}
-extension as ;
-on int (){}
+extension mixin on int {}
+
+extension extension on int {}
+
+extension as on int {}
+
void main() {}
diff --git a/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..94a2d44
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+extension as on int {}
+
+extension extension on int {}
+
+extension mixin on int {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect
index b4fd451..cb13225 100644
--- a/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect
@@ -1,15 +1,23 @@
class A {
String get call => "My name is A";
}
+
class B {
String Function() get call => () => "My name is B";
}
-extension on ;
-int (){}
-extension on ;
-num (){}
-extension on ;
-String (){}
+
+extension on int {
+ String get call => "My name is int";
+}
+
+extension on num {
+ String get call => "My name is num";
+}
+
+extension on String {
+ String Function() get call => () => "My name is String";
+}
+
main() {}
var topLevel1 = 1(10);
var topLevel2 = 1("10");
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..30be637
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,32 @@
+A a = new A();
+B b = new B();
+
+class A {
+ String get call => "My name is A";
+}
+
+class B {
+ String Function() get call => () => "My name is B";
+}
+
+errors() {}
+
+extension on String {
+ String Function() get call => () => "My name is String";
+}
+
+extension on int {
+ String get call => "My name is int";
+}
+
+extension on num {
+ String get call => "My name is num";
+}
+
+main() {}
+var topLevel1 = 1(10);
+var topLevel2 = 1("10");
+var topLevel3 = 1.0(10);
+var topLevel4 = 1.0("10");
+var topLevel5 = a(2);
+var topLevel6 = a(2, "3");
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect
index 57b1a20..ee9c440 100644
--- a/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect
@@ -1,9 +1,16 @@
part 'check_bounds_lib.dart';
+
class A {}
+
class B extends A {}
+
class Class<T extends A> {}
-extension Extension<T extends B> (){}
-on Class<T> (){}
+
+extension Extension<T extends B> on Class<T> {
+ method() {}
+ genericMethod<S extends B>(S s) {}
+}
+
main() {}
test() {}
final A a = new A();
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b09fba
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,47 @@
+part 'check_bounds_lib.dart';
+
+class A {}
+
+class B extends A {}
+
+class Class<T extends A> {}
+
+extension Extension<T extends B> on Class<T> {
+ genericMethod<S extends B>(S s) {}
+ method() {}
+}
+
+final A a = new A();
+final Class<A> classA = new Class<A>();
+final Class<B> classB = new Class<B>();
+final field1 = classA.method();
+final field10 = Extension<A>(classA).genericMethod<B>(a);
+final field11 = Extension<B>(classA).genericMethod(a);
+final field12 = Extension<B>(classA).genericMethod<A>(a);
+final field13 = Extension<B>(classA).genericMethod<B>(a);
+final field14 = classB.method();
+final field15 = Extension(classB).method();
+final field16 = Extension<A>(classB).method();
+final field17 = Extension<B>(classB).method();
+final field18 = classB.genericMethod(a);
+final field19 = classB.genericMethod<A>(a);
+final field2 = Extension(classA).method();
+final field20 = classB.genericMethod<B>(a);
+final field21 = Extension(classB).genericMethod(a);
+final field22 = Extension(classB).genericMethod<A>(a);
+final field23 = Extension(classB).genericMethod<B>(a);
+final field24 = Extension<A>(classB).genericMethod(a);
+final field25 = Extension<A>(classB).genericMethod<A>(a);
+final field26 = Extension<A>(classB).genericMethod<B>(a);
+final field27 = Extension<B>(classB).genericMethod(a);
+final field28 = Extension<B>(classB).genericMethod<A>(a);
+final field29 = Extension<B>(classB).genericMethod<B>(a);
+final field3 = Extension<A>(classA).method();
+final field4 = Extension<B>(classA).method();
+final field5 = Extension(classA).genericMethod(a);
+final field6 = Extension(classA).genericMethod<A>(a);
+final field7 = Extension(classA).genericMethod<B>(a);
+final field8 = Extension<A>(classA).genericMethod(a);
+final field9 = Extension<A>(classA).genericMethod<A>(a);
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect
index 78776b5..4e5e0d2 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect
@@ -5,20 +5,34 @@
bool operator ==(Object other) => other is Number && value == other.value;
String toString() => 'Number($value)';
}
-extension NumberExtension ;
-on Number (){}
+
+extension NumberExtension on Number {
+ Number operator +(Object other) {}
+ Number operator -(Object other) {}
+}
+
class Class {
Number field;
Class(this.field);
}
-extension ClassExtension ;
-on Class (){}
+
+extension ClassExtension on Class {
+ Number get property => field;
+ void set property(Number value) {}
+ testImplicitProperties() {}
+}
+
class IntClass {
int field;
IntClass(this.field);
}
-extension IntClassExtension ;
-on IntClass (){}
+
+extension IntClassExtension on IntClass {
+ int get property => field;
+ void set property(int value) {}
+ testImplicitProperties() {}
+}
+
main() {}
testLocals() {}
testProperties() {}
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/compounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fada7bd
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/compounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,45 @@
+class Class {
+ Class(this.field);
+ Number field;
+}
+
+class IntClass {
+ IntClass(this.field);
+ int field;
+}
+
+class Number {
+ Number(this.value);
+ String toString() => 'Number($value)';
+ bool operator ==(Object other) => other is Number && value == other.value;
+ final int value;
+ int get hashCode => value.hashCode;
+}
+
+expect(expected, actual, [expectNull = false]) {}
+
+extension ClassExtension on Class {
+ Number get property => field;
+ testImplicitProperties() {}
+ void set property(Number value) {}
+}
+
+extension IntClassExtension on IntClass {
+ int get property => field;
+ testImplicitProperties() {}
+ void set property(int value) {}
+}
+
+extension NumberExtension on Number {
+ Number operator +(Object other) {}
+ Number operator -(Object other) {}
+}
+
+main() {}
+testExplicitIntProperties() {}
+testExplicitNullAwareIntProperties(IntClass v) {}
+testExplicitNullAwareProperties(Class v) {}
+testExplicitProperties() {}
+testIntProperties() {}
+testLocals() {}
+testProperties() {}
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect
index 1550bbb..eb8b109 100644
--- a/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect
@@ -1,5 +1,11 @@
-extension Extension ;
-on String (){}
+extension Extension on String {
+ int get noSuchMethod => 42;
+ void set hashCode(int value) {}
+ int runtimeType() {}
+ operator ==(other) => false;
+ static String toString() => 'Foo';
+}
+
main() {}
errors() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f5441b5
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+errors() {}
+expect(expected, actual) {}
+
+extension Extension on String {
+ int get noSuchMethod => 42;
+ int runtimeType() {}
+ operator ==(other) => false;
+ static String toString() => 'Foo';
+ void set hashCode(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect
index 5a2e29f..0f53c9b 100644
--- a/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect
@@ -1,10 +1,21 @@
class Class1 {}
+
class Class2 {}
-extension DuplicateExtensionName ;
-on Class1 (){}
-extension DuplicateExtensionName ;
-on Class2 (){}
-extension UniqueExtensionName ;
-on Class1 (){}
+
+extension DuplicateExtensionName on Class1 {
+ uniqueMethod1() {}
+ duplicateMethodName2() => 1;
+}
+
+extension DuplicateExtensionName on Class2 {
+ uniqueMethod2() {}
+ duplicateMethodName2() => 2;
+}
+
+extension UniqueExtensionName on Class1 {
+ duplicateMethodName1() => 1;
+ duplicateMethodName1() => 2;
+}
+
main() {}
errors() {}
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..481736e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+class Class1 {}
+
+class Class2 {}
+
+errors() {}
+
+extension DuplicateExtensionName on Class1 {
+ duplicateMethodName2() => 1;
+ uniqueMethod1() {}
+}
+
+extension DuplicateExtensionName on Class2 {
+ duplicateMethodName2() => 2;
+ uniqueMethod2() {}
+}
+
+extension UniqueExtensionName on Class1 {
+ duplicateMethodName1() => 1;
+ duplicateMethodName1() => 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect
index aa7d513..76863ce 100644
--- a/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect
@@ -1,5 +1,12 @@
class Class {}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ method0([a]) => a;
+ method1([a = 42]) => a;
+ method2({b = 87}) => b;
+ method3({c = staticMethod}) => c();
+ static staticMethod() => 123;
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dac2c87e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class Class {}
+
+expect(expected, actual) {}
+
+extension Extension on Class {
+ method0([a]) => a;
+ method1([a = 42]) => a;
+ method2({b = 87}) => b;
+ method3({c = staticMethod}) => c();
+ static staticMethod() => 123;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect
index adb6b12..dd71c14 100644
--- a/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect
@@ -1,11 +1,47 @@
class Class {
var field;
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ readGetter() {}
+ writeSetterRequired(value) {}
+ writeSetterOptional([value]) {}
+ writeSetterNamed({value}) {}
+ get tearOffGetterNoArgs => readGetter;
+ get tearOffGetterRequired => writeSetterRequired;
+ get tearOffGetterOptional => writeSetterOptional;
+ get tearOffGetterNamed => writeSetterNamed;
+ get property => this.field;
+ set property(value) {}
+ invocations(value) {}
+ tearOffs(value) {}
+ getterCalls(value) {}
+}
+
class GenericClass<T> {
T field;
}
-extension GenericExtension<T> (){}
-on GenericClass<T> (){}
+
+extension GenericExtension<T> on GenericClass<T> {
+ T readGetter() {}
+ writeSetterRequired(T value) {}
+ writeSetterOptional([T value]) {}
+ writeSetterNamed({T value}) {}
+ genericWriteSetterRequired<S extends T>(S value) {}
+ genericWriteSetterOptional<S extends T>([S value]) {}
+ genericWriteSetterNamed<S extends T>({S value}) {}
+ T get property => this.field;
+ void set property(T value) {}
+ get tearOffGetterNoArgs => readGetter;
+ get tearOffGetterRequired => writeSetterRequired;
+ get tearOffGetterOptional => writeSetterOptional;
+ get tearOffGetterNamed => writeSetterNamed;
+ get tearOffGetterGenericRequired => genericWriteSetterRequired;
+ get tearOffGetterGenericOptional => genericWriteSetterOptional;
+ get tearOffGetterGenericNamed => genericWriteSetterNamed;
+ invocations<S extends T>(S value) {}
+ tearOffs<S extends T>(S value) {}
+ getterCalls<S extends T>(S value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e4b234
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,47 @@
+class Class {
+ var field;
+}
+
+class GenericClass<T> {
+ T field;
+}
+
+extension Extension on Class {
+ get property => this.field;
+ get tearOffGetterNamed => writeSetterNamed;
+ get tearOffGetterNoArgs => readGetter;
+ get tearOffGetterOptional => writeSetterOptional;
+ get tearOffGetterRequired => writeSetterRequired;
+ getterCalls(value) {}
+ invocations(value) {}
+ readGetter() {}
+ set property(value) {}
+ tearOffs(value) {}
+ writeSetterNamed({value}) {}
+ writeSetterOptional([value]) {}
+ writeSetterRequired(value) {}
+}
+
+extension GenericExtension<T> on GenericClass<T> {
+ T get property => this.field;
+ T readGetter() {}
+ genericWriteSetterNamed<S extends T>({S value}) {}
+ genericWriteSetterOptional<S extends T>([S value]) {}
+ genericWriteSetterRequired<S extends T>(S value) {}
+ get tearOffGetterGenericNamed => genericWriteSetterNamed;
+ get tearOffGetterGenericOptional => genericWriteSetterOptional;
+ get tearOffGetterGenericRequired => genericWriteSetterRequired;
+ get tearOffGetterNamed => writeSetterNamed;
+ get tearOffGetterNoArgs => readGetter;
+ get tearOffGetterOptional => writeSetterOptional;
+ get tearOffGetterRequired => writeSetterRequired;
+ getterCalls<S extends T>(S value) {}
+ invocations<S extends T>(S value) {}
+ tearOffs<S extends T>(S value) {}
+ void set property(T value) {}
+ writeSetterNamed({T value}) {}
+ writeSetterOptional([T value]) {}
+ writeSetterRequired(T value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect
index 34dd7dc..44997e9 100644
--- a/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect
@@ -1,6 +1,33 @@
class Class<T> {
static var field;
}
-extension Extension<T> (){}
-on Class<T> (){}
+
+extension Extension<T> on Class<T> {
+ static get property => Class.field;
+ static set property(value) {}
+ static var field;
+ static readGetter() {}
+ static writeSetterRequired(value) {}
+ static writeSetterOptional([value]) {}
+ static writeSetterNamed({value}) {}
+ static genericWriteSetterRequired<S>(S value) {}
+ static genericWriteSetterOptional<S>([S value]) {}
+ static genericWriteSetterNamed<S>({S value}) {}
+ static get tearOffGetterNoArgs => readGetter;
+ static get tearOffGetterRequired => writeSetterRequired;
+ static get tearOffGetterOptional => writeSetterOptional;
+ static get tearOffGetterNamed => writeSetterNamed;
+ static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+ static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+ static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+ static invocationsFromStaticContext(int value) {}
+ static tearOffsFromStaticContext(int value) {}
+ static fieldAccessFromStaticContext() {}
+ static getterCallsFromStaticContext(int value) {}
+ invocationsFromInstanceContext(T value) {}
+ tearOffsFromInstanceContext(T value) {}
+ fieldAccessFromInstanceContext() {}
+ getterCallsFromInstanceContext(T value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cbd1559
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,33 @@
+class Class<T> {
+ static var field;
+}
+
+extension Extension<T> on Class<T> {
+ fieldAccessFromInstanceContext() {}
+ getterCallsFromInstanceContext(T value) {}
+ invocationsFromInstanceContext(T value) {}
+ static fieldAccessFromStaticContext() {}
+ static genericWriteSetterNamed<S>({S value}) {}
+ static genericWriteSetterOptional<S>([S value]) {}
+ static genericWriteSetterRequired<S>(S value) {}
+ static get property => Class.field;
+ static get tearOffGetterGenericNamed => genericWriteSetterNamed;
+ static get tearOffGetterGenericOptional => genericWriteSetterOptional;
+ static get tearOffGetterGenericRequired => genericWriteSetterRequired;
+ static get tearOffGetterNamed => writeSetterNamed;
+ static get tearOffGetterNoArgs => readGetter;
+ static get tearOffGetterOptional => writeSetterOptional;
+ static get tearOffGetterRequired => writeSetterRequired;
+ static getterCallsFromStaticContext(int value) {}
+ static invocationsFromStaticContext(int value) {}
+ static readGetter() {}
+ static set property(value) {}
+ static tearOffsFromStaticContext(int value) {}
+ static var field;
+ static writeSetterNamed({value}) {}
+ static writeSetterOptional([value]) {}
+ static writeSetterRequired(value) {}
+ tearOffsFromInstanceContext(T value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect
index 2b221a1..5ee7ab2 100644
--- a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect
@@ -1,9 +1,14 @@
class Class {
noSuchMethod(Invocation i) => 123;
}
-extension ClassExtension ;
-on Class (){}
-extension Extension ;
-on dynamic (){}
+
+extension ClassExtension on Class {
+ int method() => 42;
+}
+
+extension Extension on dynamic {
+ int method() => 87;
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df09e5e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class Class {
+ noSuchMethod(Invocation i) => 123;
+}
+
+expect(expected, actual) {}
+
+extension ClassExtension on Class {
+ int method() => 42;
+}
+
+extension Extension on dynamic {
+ int method() => 87;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect
index e338221..0bc2528 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect
@@ -2,9 +2,20 @@
int field1 = 42;
int field2 = 87;
}
-extension Extension1 ;
-on Class (){}
-extension Extension2 ;
-on Class (){}
+
+extension Extension1 on Class {
+ int get field => field1;
+ void set field(int value) {}
+ int method() => field1;
+ int genericMethod<T extends num>(T t) => field1 + t;
+}
+
+extension Extension2 on Class {
+ int get field => field2;
+ void set field(int value) {}
+ int method() => field2;
+ int genericMethod<T extends num>(T t) => field2 + t;
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..95799c3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+class Class {
+ int field1 = 42;
+ int field2 = 87;
+}
+
+expect(expected, actual) {}
+
+extension Extension1 on Class {
+ int genericMethod<T extends num>(T t) => field1 + t;
+ int get field => field1;
+ int method() => field1;
+ void set field(int value) {}
+}
+
+extension Extension2 on Class {
+ int genericMethod<T extends num>(T t) => field2 + t;
+ int get field => field2;
+ int method() => field2;
+ void set field(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect
index 1777e12..076a719 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect
@@ -1,7 +1,15 @@
class A {}
+
class B extends A {}
+
class C extends B {}
+
class GenericClass<T> {}
-extension GenericExtension<T> (){}
-on GenericClass<T> (){}
+
+extension GenericExtension<T> on GenericClass<T> {
+ T get property => null;
+ T method(T t) => null;
+ S genericMethod1<S>(S s) => null;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..79d6ba0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class GenericClass<T> {}
+
+extension GenericExtension<T> on GenericClass<T> {
+ S genericMethod1<S>(S s) => null;
+ T get property => null;
+ T method(T t) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect
index 7319a83..b8ab337 100644
--- a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect
@@ -3,9 +3,21 @@
T field2;
Class(this.field1, this.field2);
}
-extension Extension1<T extends num> (){}
-on Class<T> (){}
-extension Extension2<T extends num> (){}
-on Class<T> (){}
+
+extension Extension1<T extends num> on Class<T> {
+ static String latestType;
+ T get field {}
+ void set field(T value) {}
+ T method() {}
+ T genericMethod<S extends num>(S t) {}
+}
+
+extension Extension2<T extends num> on Class<T> {
+ T get field => field2;
+ void set field(T value) {}
+ T method() => field2;
+ T genericMethod<S extends num>(S t) => field2 + t;
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f800b7a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class Class<T extends num> {
+ Class(this.field1, this.field2);
+ T field1;
+ T field2;
+}
+
+expect(expected, actual) {}
+
+extension Extension1<T extends num> on Class<T> {
+ T genericMethod<S extends num>(S t) {}
+ T get field {}
+ T method() {}
+ static String latestType;
+ void set field(T value) {}
+}
+
+extension Extension2<T extends num> on Class<T> {
+ T genericMethod<S extends num>(S t) => field2 + t;
+ T get field => field2;
+ T method() => field2;
+ void set field(T value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect
index 0425549..c1b8b08 100644
--- a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect
@@ -1,5 +1,6 @@
class Class {}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {}
+
errors(Class c) {}
main() {}
diff --git a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..43c658b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Class {}
+
+errors(Class c) {}
+
+extension Extension on Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect
index 7519a03..8efd4bb 100644
--- a/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect
@@ -2,6 +2,11 @@
Object field;
void method1() {}
}
-extension A2 ;
-on A1 (){}
+
+extension A2 on A1 {
+ void method2() => this.method1();
+ Object method3() => this.field;
+ void method4(Object o) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca8cb86
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A1 {
+ Object field;
+ void method1() {}
+}
+
+extension A2 on A1 {
+ Object method3() => this.field;
+ void method2() => this.method1();
+ void method4(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect
index e6e0f3d..3acad15 100644
--- a/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect
@@ -1,7 +1,10 @@
class Class<T> {
T method(T a) => a;
}
-extension Extension<T> (){}
-on Class<T> (){}
+
+extension Extension<T> on Class<T> {
+ T call(T a) => method(a);
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7edde0e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class Class<T> {
+ T method(T a) => a;
+}
+
+expect(expected, actual) {}
+
+extension Extension<T> on Class<T> {
+ T call(T a) => method(a);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect
index cc9ad4c..ac6bee2 100644
--- a/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect
@@ -1,4 +1,9 @@
class Class {}
-extension Extension ;
-on Class (){}
+extension Extension on Class {
+ Extension() {}
+ Extension.named() {}
+ factory Extension.fact() => null;
+ factory Extension.redirect() = Extension;
+ method() {}
+}
main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect
index 9179aa3..26dc2e9 100644
--- a/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect
@@ -1,3 +1,10 @@
-extension E<U> (){}
-on String (){}
+extension E<U> on String {
+ U field1 = null;
+ int field2 = () { U x = null; return null; }();
+ List<U> field3 = null;
+ U Function(U) field4 = null;
+ List<U> Function(List<U>) field5 = null;
+ int field6 = <E>() { E x = null; return null; }<String>();
+ int field7 = <E>() { E x = null; return null; }<U>();
+}
main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline.expect
index 6d262f3..f9f55d9 100644
--- a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline.expect
@@ -1,3 +1,46 @@
-extension Extension<T> (){}
-on int (){}
+extension Extension<T> on int {
+ int get duplicateInstanceGetter => 0;
+ int get duplicateInstanceGetter => 0;
+ void set duplicateInstanceSetter(int value) {}
+ void set duplicateInstanceSetter(int value) {}
+ void duplicateInstanceMethod() {}
+ void duplicateInstanceMethod() {}
+ static int duplicateStaticField = 0;
+ static int duplicateStaticField = 0;
+ static int get duplicateStaticGetter => 0;
+ static int get duplicateStaticGetter => 0;
+ static void set duplicateStaticSetter(int value) {}
+ static void set duplicateStaticSetter(int value) {}
+ static void duplicateStaticMethod() {}
+ static void duplicateStaticMethod() {}
+ int get duplicateInstanceGetterPlusSetter => 0;
+ int get duplicateInstanceGetterPlusSetter => 0;
+ void set duplicateInstanceGetterPlusSetter(int value) {}
+ int get duplicateInstanceSetterPlusGetter => 0;
+ void set duplicateInstanceSetterPlusGetter(int value) {}
+ void set duplicateInstanceSetterPlusGetter(int value) {}
+ int get duplicateInstanceGetterAndSetter => 0;
+ int get duplicateInstanceGetterAndSetter => 0;
+ void set duplicateInstanceGetterAndSetter(int value) {}
+ void set duplicateInstanceGetterAndSetter(int value) {}
+ static int get duplicateStaticGetterPlusSetter => 0;
+ static int get duplicateStaticGetterPlusSetter => 0;
+ static void set duplicateStaticGetterPlusSetter(int value) {}
+ static int get duplicateStaticSetterPlusGetter => 0;
+ static void set duplicateStaticSetterPlusGetter(int value) {}
+ static void set duplicateStaticSetterPlusGetter(int value) {}
+ static int get duplicateStaticGetterAndSetter => 0;
+ static int get duplicateStaticGetterAndSetter => 0;
+ static void set duplicateStaticGetterAndSetter(int value) {}
+ static void set duplicateStaticGetterAndSetter(int value) {}
+ int get instanceGetterAndStaticSetter => 0;
+ static void set instanceGetterAndStaticSetter(int value) {}
+ static int get instanceSetterAndStaticGetter => 0;
+ void set instanceSetterAndStaticGetter(int value) {}
+ int get instanceGetterAndStaticField => 0;
+ static int instanceGetterAndStaticField = 0;
+ void set instanceSetterAndStaticField(int value) {}
+ static final int instanceGetterAndStaticField = 0;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..88f38e3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline_modelled.expect
@@ -0,0 +1,46 @@
+extension Extension<T> on int {
+ int get duplicateInstanceGetter => 0;
+ int get duplicateInstanceGetter => 0;
+ int get duplicateInstanceGetterAndSetter => 0;
+ int get duplicateInstanceGetterAndSetter => 0;
+ int get duplicateInstanceGetterPlusSetter => 0;
+ int get duplicateInstanceGetterPlusSetter => 0;
+ int get duplicateInstanceSetterPlusGetter => 0;
+ int get instanceGetterAndStaticField => 0;
+ int get instanceGetterAndStaticSetter => 0;
+ static final int instanceGetterAndStaticField = 0;
+ static int duplicateStaticField = 0;
+ static int duplicateStaticField = 0;
+ static int get duplicateStaticGetter => 0;
+ static int get duplicateStaticGetter => 0;
+ static int get duplicateStaticGetterAndSetter => 0;
+ static int get duplicateStaticGetterAndSetter => 0;
+ static int get duplicateStaticGetterPlusSetter => 0;
+ static int get duplicateStaticGetterPlusSetter => 0;
+ static int get duplicateStaticSetterPlusGetter => 0;
+ static int get instanceSetterAndStaticGetter => 0;
+ static int instanceGetterAndStaticField = 0;
+ static void duplicateStaticMethod() {}
+ static void duplicateStaticMethod() {}
+ static void set duplicateStaticGetterAndSetter(int value) {}
+ static void set duplicateStaticGetterAndSetter(int value) {}
+ static void set duplicateStaticGetterPlusSetter(int value) {}
+ static void set duplicateStaticSetter(int value) {}
+ static void set duplicateStaticSetter(int value) {}
+ static void set duplicateStaticSetterPlusGetter(int value) {}
+ static void set duplicateStaticSetterPlusGetter(int value) {}
+ static void set instanceGetterAndStaticSetter(int value) {}
+ void duplicateInstanceMethod() {}
+ void duplicateInstanceMethod() {}
+ void set duplicateInstanceGetterAndSetter(int value) {}
+ void set duplicateInstanceGetterAndSetter(int value) {}
+ void set duplicateInstanceGetterPlusSetter(int value) {}
+ void set duplicateInstanceSetter(int value) {}
+ void set duplicateInstanceSetter(int value) {}
+ void set duplicateInstanceSetterPlusGetter(int value) {}
+ void set duplicateInstanceSetterPlusGetter(int value) {}
+ void set instanceSetterAndStaticField(int value) {}
+ void set instanceSetterAndStaticGetter(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect
index ee11ab1..5ed8d9d8 100644
--- a/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect
@@ -1,7 +1,11 @@
import 'package:expect/expect.dart';
+
class C {
int get one => 1;
}
-extension E ;
-on C (){}
+
+extension E on C {
+ int get two => 2;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ed8d9d8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import 'package:expect/expect.dart';
+
+class C {
+ int get one => 1;
+}
+
+extension E on C {
+ int get two => 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect
index 6785be5..f06572f 100644
--- a/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect
@@ -1,10 +1,24 @@
class Class {
int field;
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ int get simpleSetter => field;
+ set simpleSetter(int value) {}
+ int get mutatingSetter => field;
+ set mutatingSetter(int value) {}
+ int get setterWithReturn => field;
+ set setterWithReturn(int value) {}
+ int get setterWithClosure => field;
+ set setterWithClosure(int value) {}
+ testInternal() {}
+}
+
class GenericClass<T> {}
-extension GenericExtension<T> (){}
-on GenericClass<T> (){}
+
+extension GenericExtension<T> on GenericClass<T> {
+ set setter(T value) {}
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..171d483
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+class Class {
+ int field;
+}
+
+class GenericClass<T> {}
+
+expect(expected, actual) {}
+
+extension Extension on Class {
+ int get mutatingSetter => field;
+ int get setterWithClosure => field;
+ int get setterWithReturn => field;
+ int get simpleSetter => field;
+ set mutatingSetter(int value) {}
+ set setterWithClosure(int value) {}
+ set setterWithReturn(int value) {}
+ set simpleSetter(int value) {}
+ testInternal() {}
+}
+
+extension GenericExtension<T> on GenericClass<T> {
+ set setter(T value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect
index ee14f80..1a91b18 100644
--- a/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect
@@ -1,5 +1,8 @@
class GenericClass<T> {}
-extension GenericExtension<T> (){}
-on GenericClass<T> (){}
+
+extension GenericExtension<T> on GenericClass<T> {
+ set setter(T value) {}
+}
+
error() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2d2db9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class GenericClass<T> {}
+
+error() {}
+expect(expected, actual) {}
+
+extension GenericExtension<T> on GenericClass<T> {
+ set setter(T value) {}
+}
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect
index 6f0f637..c0519a0 100644
--- a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect
@@ -1,4 +1,7 @@
class Class<T> {}
-extension Extension<T> (){}
-on Class<T> (){}
+
+extension Extension<T> on Class<T> {
+ R method<R>(T t) => null;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c0519a0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Class<T> {}
+
+extension Extension<T> on Class<T> {
+ R method<R>(T t) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect
index 7cb1042..0207a05 100644
--- a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect
@@ -2,10 +2,19 @@
int get m1 => 0;
void set m2(int x) {}
}
-extension Extension0 ;
-on Class (){}
-extension Extension1 ;
-on Class (){}
+
+extension Extension0 on Class {
+ void set m1(int x) {}
+ int get m2 => 0;
+ void set m3(int x) {}
+ int get m4 => 0;
+}
+
+extension Extension1 on Class {
+ int get m3 => 0;
+ void set m4(int x) {}
+}
+
main() {}
errors() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3da20ad
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+class Class {
+ int get m1 => 0;
+ void set m2(int x) {}
+}
+
+errors() {}
+expect(expected, actual) {}
+
+extension Extension0 on Class {
+ int get m2 => 0;
+ int get m4 => 0;
+ void set m1(int x) {}
+ void set m3(int x) {}
+}
+
+extension Extension1 on Class {
+ int get m3 => 0;
+ void set m4(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect
index 3220178..473e89a 100644
--- a/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect
@@ -1,6 +1,11 @@
class Class {
int field;
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ int get property => field;
+ void set property(int value) {}
+ int method() => field;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/if_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f29446e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/if_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class Class {
+ int field;
+}
+
+extension Extension on Class {
+ int get property => field;
+ int method() => field;
+ void set property(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect
index 1777e12..076a719 100644
--- a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect
@@ -1,7 +1,15 @@
class A {}
+
class B extends A {}
+
class C extends B {}
+
class GenericClass<T> {}
-extension GenericExtension<T> (){}
-on GenericClass<T> (){}
+
+extension GenericExtension<T> on GenericClass<T> {
+ T get property => null;
+ T method(T t) => null;
+ S genericMethod1<S>(S s) => null;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..79d6ba0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class GenericClass<T> {}
+
+extension GenericExtension<T> on GenericClass<T> {
+ S genericMethod1<S>(S s) => null;
+ T get property => null;
+ T method(T t) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect
index 7519a03..89eff23 100644
--- a/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect
@@ -2,6 +2,11 @@
Object field;
void method1() {}
}
-extension A2 ;
-on A1 (){}
+
+extension A2 on A1 {
+ void method2() => method1();
+ Object method3() => field;
+ void method4(Object o) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb7a0dd
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A1 {
+ Object field;
+ void method1() {}
+}
+
+extension A2 on A1 {
+ Object method3() => field;
+ void method2() => method1();
+ void method4(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/index.dart.strong.expect b/pkg/front_end/testcases/extensions/index.dart.strong.expect
index f9f0d76..81557be 100644
--- a/pkg/front_end/testcases/extensions/index.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.strong.expect
@@ -70,23 +70,23 @@
self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("2", let final self::MapLike<core::int*, core::String*>* #t43 = map1 in let final core::int* #t44 = 1 in let final core::String* #t45 = "2" in let final void #t46 = self::Extension|[]=<core::int*, core::String*>(#t43, #t44, #t45) in #t45);
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t43 = map1 in let final core::String* #t44 = "2" in let final void #t45 = self::Extension|[]=<core::int*, core::String*>(#t43, 1, #t44) in #t44);
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- let final self::MapLike<core::int*, core::String*>* #t47 = map1 in let final core::int* #t48 = 1 in self::Extension|[]<core::int*, core::String*>(#t47, #t48).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t47, #t48, "3") : null;
+ let final self::MapLike<core::int*, core::String*>* #t46 = map1 in let final core::int* #t47 = 1 in self::Extension|[]<core::int*, core::String*>(#t46, #t47).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t46, #t47, "3") : null;
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("2", let final self::MapLike<core::int*, core::String*>* #t49 = map1 in let final core::int* #t50 = 1 in let final core::String* #t51 = self::Extension|[]<core::int*, core::String*>(#t49, #t50) in #t51.{core::String::==}(null) ?{core::String*} let final core::String* #t52 = "4" in let final void #t53 = self::Extension|[]=<core::int*, core::String*>(#t49, #t50, #t52) in #t52 : #t51);
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t48 = map1 in let final core::int* #t49 = 1 in let final core::String* #t50 = self::Extension|[]<core::int*, core::String*>(#t48, #t49) in #t50.{core::String::==}(null) ?{core::String*} let final core::String* #t51 = "4" in let final void #t52 = self::Extension|[]=<core::int*, core::String*>(#t48, #t49, #t51) in #t51 : #t50);
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- let final self::MapLike<core::int*, core::String*>* #t54 = map1 in let final core::int* #t55 = 2 in self::Extension|[]<core::int*, core::String*>(#t54, #t55).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t54, #t55, "2") : null;
+ let final self::MapLike<core::int*, core::String*>* #t53 = map1 in let final core::int* #t54 = 2 in self::Extension|[]<core::int*, core::String*>(#t53, #t54).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t53, #t54, "2") : null;
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
- self::expect("3", let final self::MapLike<core::int*, core::String*>* #t56 = map1 in let final core::int* #t57 = 3 in let final core::String* #t58 = self::Extension|[]<core::int*, core::String*>(#t56, #t57) in #t58.{core::String::==}(null) ?{core::String*} let final core::String* #t59 = "3" in let final void #t60 = self::Extension|[]=<core::int*, core::String*>(#t56, #t57, #t59) in #t59 : #t58);
+ self::expect("3", let final self::MapLike<core::int*, core::String*>* #t55 = map1 in let final core::int* #t56 = 3 in let final core::String* #t57 = self::Extension|[]<core::int*, core::String*>(#t55, #t56) in #t57.{core::String::==}(null) ?{core::String*} let final core::String* #t58 = "3" in let final void #t59 = self::Extension|[]=<core::int*, core::String*>(#t55, #t56, #t58) in #t58 : #t57);
self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
- self::expect(1, let final self::MapLike<core::int*, core::int*>* #t61 = map2 in let final core::int* #t62 = 0 in let final core::int* #t63 = 1 in let final void #t64 = self::Extension|[]=<core::int*, core::int*>(#t61, #t62, #t63) in #t63);
- self::expect(3, let final self::MapLike<core::int*, core::int*>* #t65 = map2 in let final core::int* #t66 = 0 in let final core::int* #t67 = self::Extension|[]<core::int*, core::int*>(#t65, #t66).{core::num::+}(2) in let final void #t68 = self::Extension|[]=<core::int*, core::int*>(#t65, #t66, #t67) in #t67);
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t69 = map2 in let final core::int* #t70 = 0 in let final core::int* #t71 = self::Extension|[]<core::int*, core::int*>(#t69, #t70).{core::num::+}(2) in let final void #t72 = self::Extension|[]=<core::int*, core::int*>(#t69, #t70, #t71) in #t71);
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t73 = map2 in let final core::int* #t74 = 0 in let final core::int* #t75 = self::Extension|[]<core::int*, core::int*>(#t73, #t74) in let final void #t76 = self::Extension|[]=<core::int*, core::int*>(#t73, #t74, #t75.{core::num::+}(1)) in #t75);
+ self::expect(1, let final self::MapLike<core::int*, core::int*>* #t60 = map2 in let final core::int* #t61 = 1 in let final void #t62 = self::Extension|[]=<core::int*, core::int*>(#t60, 0, #t61) in #t61);
+ self::expect(3, let final self::MapLike<core::int*, core::int*>* #t63 = map2 in let final core::int* #t64 = 0 in let final core::int* #t65 = self::Extension|[]<core::int*, core::int*>(#t63, #t64).{core::num::+}(2) in let final void #t66 = self::Extension|[]=<core::int*, core::int*>(#t63, #t64, #t65) in #t65);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t67 = map2 in let final core::int* #t68 = 0 in let final core::int* #t69 = self::Extension|[]<core::int*, core::int*>(#t67, #t68).{core::num::+}(2) in let final void #t70 = self::Extension|[]=<core::int*, core::int*>(#t67, #t68, #t69) in #t69);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t71 = map2 in let final core::int* #t72 = 0 in let final core::int* #t73 = self::Extension|[]<core::int*, core::int*>(#t71, #t72) in let final void #t74 = self::Extension|[]=<core::int*, core::int*>(#t71, #t72, #t73.{core::num::+}(1)) in #t73);
self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t77 = map2 in let final core::int* #t78 = 0 in let final core::int* #t79 = self::Extension|[]<core::int*, core::int*>(#t77, #t78).{core::num::-}(1) in let final void #t80 = self::Extension|[]=<core::int*, core::int*>(#t77, #t78, #t79) in #t79);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t75 = map2 in let final core::int* #t76 = 0 in let final core::int* #t77 = self::Extension|[]<core::int*, core::int*>(#t75, #t76).{core::num::-}(1) in let final void #t78 = self::Extension|[]=<core::int*, core::int*>(#t75, #t76, #t77) in #t77);
self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
}
static method explicitInferredTypeArguments() → dynamic {
@@ -97,23 +97,23 @@
self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("2", let final self::MapLike<core::int*, core::String*>* #t81 = map1 in let final core::int* #t82 = 1 in let final core::String* #t83 = "2" in let final void #t84 = self::Extension|[]=<core::int*, core::String*>(#t81, #t82, #t83) in #t83);
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t79 = map1 in let final core::String* #t80 = "2" in let final void #t81 = self::Extension|[]=<core::int*, core::String*>(#t79, 1, #t80) in #t80);
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- let final self::MapLike<core::int*, core::String*>* #t85 = map1 in let final core::int* #t86 = 1 in self::Extension|[]<core::int*, core::String*>(#t85, #t86).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t85, #t86, "3") : null;
+ let final self::MapLike<core::int*, core::String*>* #t82 = map1 in let final core::int* #t83 = 1 in self::Extension|[]<core::int*, core::String*>(#t82, #t83).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t82, #t83, "3") : null;
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("2", let final self::MapLike<core::int*, core::String*>* #t87 = map1 in let final core::int* #t88 = 1 in let final core::String* #t89 = self::Extension|[]<core::int*, core::String*>(#t87, #t88) in #t89.{core::String::==}(null) ?{core::String*} let final core::String* #t90 = "4" in let final void #t91 = self::Extension|[]=<core::int*, core::String*>(#t87, #t88, #t90) in #t90 : #t89);
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t84 = map1 in let final core::int* #t85 = 1 in let final core::String* #t86 = self::Extension|[]<core::int*, core::String*>(#t84, #t85) in #t86.{core::String::==}(null) ?{core::String*} let final core::String* #t87 = "4" in let final void #t88 = self::Extension|[]=<core::int*, core::String*>(#t84, #t85, #t87) in #t87 : #t86);
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- let final self::MapLike<core::int*, core::String*>* #t92 = map1 in let final core::int* #t93 = 2 in self::Extension|[]<core::int*, core::String*>(#t92, #t93).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t92, #t93, "2") : null;
+ let final self::MapLike<core::int*, core::String*>* #t89 = map1 in let final core::int* #t90 = 2 in self::Extension|[]<core::int*, core::String*>(#t89, #t90).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t89, #t90, "2") : null;
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
- self::expect("3", let final self::MapLike<core::int*, core::String*>* #t94 = map1 in let final core::int* #t95 = 3 in let final core::String* #t96 = self::Extension|[]<core::int*, core::String*>(#t94, #t95) in #t96.{core::String::==}(null) ?{core::String*} let final core::String* #t97 = "3" in let final void #t98 = self::Extension|[]=<core::int*, core::String*>(#t94, #t95, #t97) in #t97 : #t96);
+ self::expect("3", let final self::MapLike<core::int*, core::String*>* #t91 = map1 in let final core::int* #t92 = 3 in let final core::String* #t93 = self::Extension|[]<core::int*, core::String*>(#t91, #t92) in #t93.{core::String::==}(null) ?{core::String*} let final core::String* #t94 = "3" in let final void #t95 = self::Extension|[]=<core::int*, core::String*>(#t91, #t92, #t94) in #t94 : #t93);
self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
- self::expect(1, let final self::MapLike<core::int*, core::int*>* #t99 = map2 in let final core::int* #t100 = 0 in let final core::int* #t101 = 1 in let final void #t102 = self::Extension|[]=<core::int*, core::int*>(#t99, #t100, #t101) in #t101);
- self::expect(3, let final self::MapLike<core::int*, core::int*>* #t103 = map2 in let final core::int* #t104 = 0 in let final core::int* #t105 = self::Extension|[]<core::int*, core::int*>(#t103, #t104).{core::num::+}(2) in let final void #t106 = self::Extension|[]=<core::int*, core::int*>(#t103, #t104, #t105) in #t105);
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t107 = map2 in let final core::int* #t108 = 0 in let final core::int* #t109 = self::Extension|[]<core::int*, core::int*>(#t107, #t108).{core::num::+}(2) in let final void #t110 = self::Extension|[]=<core::int*, core::int*>(#t107, #t108, #t109) in #t109);
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t111 = map2 in let final core::int* #t112 = 0 in let final core::int* #t113 = self::Extension|[]<core::int*, core::int*>(#t111, #t112) in let final void #t114 = self::Extension|[]=<core::int*, core::int*>(#t111, #t112, #t113.{core::num::+}(1)) in #t113);
+ self::expect(1, let final self::MapLike<core::int*, core::int*>* #t96 = map2 in let final core::int* #t97 = 1 in let final void #t98 = self::Extension|[]=<core::int*, core::int*>(#t96, 0, #t97) in #t97);
+ self::expect(3, let final self::MapLike<core::int*, core::int*>* #t99 = map2 in let final core::int* #t100 = 0 in let final core::int* #t101 = self::Extension|[]<core::int*, core::int*>(#t99, #t100).{core::num::+}(2) in let final void #t102 = self::Extension|[]=<core::int*, core::int*>(#t99, #t100, #t101) in #t101);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t103 = map2 in let final core::int* #t104 = 0 in let final core::int* #t105 = self::Extension|[]<core::int*, core::int*>(#t103, #t104).{core::num::+}(2) in let final void #t106 = self::Extension|[]=<core::int*, core::int*>(#t103, #t104, #t105) in #t105);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t107 = map2 in let final core::int* #t108 = 0 in let final core::int* #t109 = self::Extension|[]<core::int*, core::int*>(#t107, #t108) in let final void #t110 = self::Extension|[]=<core::int*, core::int*>(#t107, #t108, #t109.{core::num::+}(1)) in #t109);
self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t115 = map2 in let final core::int* #t116 = 0 in let final core::int* #t117 = self::Extension|[]<core::int*, core::int*>(#t115, #t116).{core::num::-}(1) in let final void #t118 = self::Extension|[]=<core::int*, core::int*>(#t115, #t116, #t117) in #t117);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t111 = map2 in let final core::int* #t112 = 0 in let final core::int* #t113 = self::Extension|[]<core::int*, core::int*>(#t111, #t112).{core::num::-}(1) in let final void #t114 = self::Extension|[]=<core::int*, core::int*>(#t111, #t112, #t113) in #t113);
self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
index 771f107..e570b06 100644
--- a/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
@@ -70,23 +70,23 @@
self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("2", let final self::MapLike<core::int*, core::String*>* #t43 = map1 in let final core::int* #t44 = 1 in let final core::String* #t45 = "2" in let final void #t46 = self::Extension|[]=<core::int*, core::String*>(#t43, #t44, #t45) in #t45);
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t43 = map1 in let final core::String* #t44 = "2" in let final void #t45 = self::Extension|[]=<core::int*, core::String*>(#t43, 1, #t44) in #t44);
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- let final self::MapLike<core::int*, core::String*>* #t47 = map1 in let final core::int* #t48 = 1 in self::Extension|[]<core::int*, core::String*>(#t47, #t48).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t47, #t48, "3") : null;
+ let final self::MapLike<core::int*, core::String*>* #t46 = map1 in let final core::int* #t47 = 1 in self::Extension|[]<core::int*, core::String*>(#t46, #t47).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t46, #t47, "3") : null;
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("2", let final self::MapLike<core::int*, core::String*>* #t49 = map1 in let final core::int* #t50 = 1 in let final core::String* #t51 = self::Extension|[]<core::int*, core::String*>(#t49, #t50) in #t51.{core::String::==}(null) ?{core::String*} let final core::String* #t52 = "4" in let final void #t53 = self::Extension|[]=<core::int*, core::String*>(#t49, #t50, #t52) in #t52 : #t51);
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t48 = map1 in let final core::int* #t49 = 1 in let final core::String* #t50 = self::Extension|[]<core::int*, core::String*>(#t48, #t49) in #t50.{core::String::==}(null) ?{core::String*} let final core::String* #t51 = "4" in let final void #t52 = self::Extension|[]=<core::int*, core::String*>(#t48, #t49, #t51) in #t51 : #t50);
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- let final self::MapLike<core::int*, core::String*>* #t54 = map1 in let final core::int* #t55 = 2 in self::Extension|[]<core::int*, core::String*>(#t54, #t55).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t54, #t55, "2") : null;
+ let final self::MapLike<core::int*, core::String*>* #t53 = map1 in let final core::int* #t54 = 2 in self::Extension|[]<core::int*, core::String*>(#t53, #t54).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t53, #t54, "2") : null;
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
- self::expect("3", let final self::MapLike<core::int*, core::String*>* #t56 = map1 in let final core::int* #t57 = 3 in let final core::String* #t58 = self::Extension|[]<core::int*, core::String*>(#t56, #t57) in #t58.{core::String::==}(null) ?{core::String*} let final core::String* #t59 = "3" in let final void #t60 = self::Extension|[]=<core::int*, core::String*>(#t56, #t57, #t59) in #t59 : #t58);
+ self::expect("3", let final self::MapLike<core::int*, core::String*>* #t55 = map1 in let final core::int* #t56 = 3 in let final core::String* #t57 = self::Extension|[]<core::int*, core::String*>(#t55, #t56) in #t57.{core::String::==}(null) ?{core::String*} let final core::String* #t58 = "3" in let final void #t59 = self::Extension|[]=<core::int*, core::String*>(#t55, #t56, #t58) in #t58 : #t57);
self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
- self::expect(1, let final self::MapLike<core::int*, core::int*>* #t61 = map2 in let final core::int* #t62 = 0 in let final core::int* #t63 = 1 in let final void #t64 = self::Extension|[]=<core::int*, core::int*>(#t61, #t62, #t63) in #t63);
- self::expect(3, let final self::MapLike<core::int*, core::int*>* #t65 = map2 in let final core::int* #t66 = 0 in let final core::int* #t67 = self::Extension|[]<core::int*, core::int*>(#t65, #t66).{core::num::+}(2) in let final void #t68 = self::Extension|[]=<core::int*, core::int*>(#t65, #t66, #t67) in #t67);
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t69 = map2 in let final core::int* #t70 = 0 in let final core::int* #t71 = self::Extension|[]<core::int*, core::int*>(#t69, #t70).{core::num::+}(2) in let final void #t72 = self::Extension|[]=<core::int*, core::int*>(#t69, #t70, #t71) in #t71);
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t73 = map2 in let final core::int* #t74 = 0 in let final core::int* #t75 = self::Extension|[]<core::int*, core::int*>(#t73, #t74) in let final void #t76 = self::Extension|[]=<core::int*, core::int*>(#t73, #t74, #t75.{core::num::+}(1)) in #t75);
+ self::expect(1, let final self::MapLike<core::int*, core::int*>* #t60 = map2 in let final core::int* #t61 = 1 in let final void #t62 = self::Extension|[]=<core::int*, core::int*>(#t60, 0, #t61) in #t61);
+ self::expect(3, let final self::MapLike<core::int*, core::int*>* #t63 = map2 in let final core::int* #t64 = 0 in let final core::int* #t65 = self::Extension|[]<core::int*, core::int*>(#t63, #t64).{core::num::+}(2) in let final void #t66 = self::Extension|[]=<core::int*, core::int*>(#t63, #t64, #t65) in #t65);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t67 = map2 in let final core::int* #t68 = 0 in let final core::int* #t69 = self::Extension|[]<core::int*, core::int*>(#t67, #t68).{core::num::+}(2) in let final void #t70 = self::Extension|[]=<core::int*, core::int*>(#t67, #t68, #t69) in #t69);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t71 = map2 in let final core::int* #t72 = 0 in let final core::int* #t73 = self::Extension|[]<core::int*, core::int*>(#t71, #t72) in let final void #t74 = self::Extension|[]=<core::int*, core::int*>(#t71, #t72, #t73.{core::num::+}(1)) in #t73);
self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t77 = map2 in let final core::int* #t78 = 0 in let final core::int* #t79 = self::Extension|[]<core::int*, core::int*>(#t77, #t78).{core::num::-}(1) in let final void #t80 = self::Extension|[]=<core::int*, core::int*>(#t77, #t78, #t79) in #t79);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t75 = map2 in let final core::int* #t76 = 0 in let final core::int* #t77 = self::Extension|[]<core::int*, core::int*>(#t75, #t76).{core::num::-}(1) in let final void #t78 = self::Extension|[]=<core::int*, core::int*>(#t75, #t76, #t77) in #t77);
self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
}
static method explicitInferredTypeArguments() → dynamic {
@@ -97,23 +97,23 @@
self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("2", let final self::MapLike<core::int*, core::String*>* #t81 = map1 in let final core::int* #t82 = 1 in let final core::String* #t83 = "2" in let final void #t84 = self::Extension|[]=<core::int*, core::String*>(#t81, #t82, #t83) in #t83);
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t79 = map1 in let final core::String* #t80 = "2" in let final void #t81 = self::Extension|[]=<core::int*, core::String*>(#t79, 1, #t80) in #t80);
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- let final self::MapLike<core::int*, core::String*>* #t85 = map1 in let final core::int* #t86 = 1 in self::Extension|[]<core::int*, core::String*>(#t85, #t86).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t85, #t86, "3") : null;
+ let final self::MapLike<core::int*, core::String*>* #t82 = map1 in let final core::int* #t83 = 1 in self::Extension|[]<core::int*, core::String*>(#t82, #t83).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t82, #t83, "3") : null;
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("2", let final self::MapLike<core::int*, core::String*>* #t87 = map1 in let final core::int* #t88 = 1 in let final core::String* #t89 = self::Extension|[]<core::int*, core::String*>(#t87, #t88) in #t89.{core::String::==}(null) ?{core::String*} let final core::String* #t90 = "4" in let final void #t91 = self::Extension|[]=<core::int*, core::String*>(#t87, #t88, #t90) in #t90 : #t89);
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t84 = map1 in let final core::int* #t85 = 1 in let final core::String* #t86 = self::Extension|[]<core::int*, core::String*>(#t84, #t85) in #t86.{core::String::==}(null) ?{core::String*} let final core::String* #t87 = "4" in let final void #t88 = self::Extension|[]=<core::int*, core::String*>(#t84, #t85, #t87) in #t87 : #t86);
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
- let final self::MapLike<core::int*, core::String*>* #t92 = map1 in let final core::int* #t93 = 2 in self::Extension|[]<core::int*, core::String*>(#t92, #t93).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t92, #t93, "2") : null;
+ let final self::MapLike<core::int*, core::String*>* #t89 = map1 in let final core::int* #t90 = 2 in self::Extension|[]<core::int*, core::String*>(#t89, #t90).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t89, #t90, "2") : null;
self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
- self::expect("3", let final self::MapLike<core::int*, core::String*>* #t94 = map1 in let final core::int* #t95 = 3 in let final core::String* #t96 = self::Extension|[]<core::int*, core::String*>(#t94, #t95) in #t96.{core::String::==}(null) ?{core::String*} let final core::String* #t97 = "3" in let final void #t98 = self::Extension|[]=<core::int*, core::String*>(#t94, #t95, #t97) in #t97 : #t96);
+ self::expect("3", let final self::MapLike<core::int*, core::String*>* #t91 = map1 in let final core::int* #t92 = 3 in let final core::String* #t93 = self::Extension|[]<core::int*, core::String*>(#t91, #t92) in #t93.{core::String::==}(null) ?{core::String*} let final core::String* #t94 = "3" in let final void #t95 = self::Extension|[]=<core::int*, core::String*>(#t91, #t92, #t94) in #t94 : #t93);
self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
- self::expect(1, let final self::MapLike<core::int*, core::int*>* #t99 = map2 in let final core::int* #t100 = 0 in let final core::int* #t101 = 1 in let final void #t102 = self::Extension|[]=<core::int*, core::int*>(#t99, #t100, #t101) in #t101);
- self::expect(3, let final self::MapLike<core::int*, core::int*>* #t103 = map2 in let final core::int* #t104 = 0 in let final core::int* #t105 = self::Extension|[]<core::int*, core::int*>(#t103, #t104).{core::num::+}(2) in let final void #t106 = self::Extension|[]=<core::int*, core::int*>(#t103, #t104, #t105) in #t105);
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t107 = map2 in let final core::int* #t108 = 0 in let final core::int* #t109 = self::Extension|[]<core::int*, core::int*>(#t107, #t108).{core::num::+}(2) in let final void #t110 = self::Extension|[]=<core::int*, core::int*>(#t107, #t108, #t109) in #t109);
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t111 = map2 in let final core::int* #t112 = 0 in let final core::int* #t113 = self::Extension|[]<core::int*, core::int*>(#t111, #t112) in let final void #t114 = self::Extension|[]=<core::int*, core::int*>(#t111, #t112, #t113.{core::num::+}(1)) in #t113);
+ self::expect(1, let final self::MapLike<core::int*, core::int*>* #t96 = map2 in let final core::int* #t97 = 1 in let final void #t98 = self::Extension|[]=<core::int*, core::int*>(#t96, 0, #t97) in #t97);
+ self::expect(3, let final self::MapLike<core::int*, core::int*>* #t99 = map2 in let final core::int* #t100 = 0 in let final core::int* #t101 = self::Extension|[]<core::int*, core::int*>(#t99, #t100).{core::num::+}(2) in let final void #t102 = self::Extension|[]=<core::int*, core::int*>(#t99, #t100, #t101) in #t101);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t103 = map2 in let final core::int* #t104 = 0 in let final core::int* #t105 = self::Extension|[]<core::int*, core::int*>(#t103, #t104).{core::num::+}(2) in let final void #t106 = self::Extension|[]=<core::int*, core::int*>(#t103, #t104, #t105) in #t105);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t107 = map2 in let final core::int* #t108 = 0 in let final core::int* #t109 = self::Extension|[]<core::int*, core::int*>(#t107, #t108) in let final void #t110 = self::Extension|[]=<core::int*, core::int*>(#t107, #t108, #t109.{core::num::+}(1)) in #t109);
self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
- self::expect(5, let final self::MapLike<core::int*, core::int*>* #t115 = map2 in let final core::int* #t116 = 0 in let final core::int* #t117 = self::Extension|[]<core::int*, core::int*>(#t115, #t116).{core::num::-}(1) in let final void #t118 = self::Extension|[]=<core::int*, core::int*>(#t115, #t116, #t117) in #t117);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t111 = map2 in let final core::int* #t112 = 0 in let final core::int* #t113 = self::Extension|[]<core::int*, core::int*>(#t111, #t112).{core::num::-}(1) in let final void #t114 = self::Extension|[]=<core::int*, core::int*>(#t111, #t112, #t113) in #t113);
self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
@@ -150,7 +150,6 @@
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:46:18 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:48:20 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:48:20 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:60:44 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:60:49 -> StringConstant("2")
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:60:49 -> StringConstant("2")
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:62:32 -> IntConstant(1)
@@ -165,7 +164,6 @@
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:68:44 -> IntConstant(3)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:68:51 -> StringConstant("3")
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:68:51 -> StringConstant("3")
-Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:72:39 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:72:44 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:72:44 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:73:39 -> IntConstant(0)
@@ -176,7 +174,6 @@
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:75:39 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:77:41 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:77:41 -> IntConstant(0)
-Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:89:31 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:89:36 -> StringConstant("2")
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:89:36 -> StringConstant("2")
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:91:19 -> IntConstant(1)
@@ -191,7 +188,6 @@
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:97:31 -> IntConstant(3)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:97:38 -> StringConstant("3")
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:97:38 -> StringConstant("3")
-Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:101:29 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:101:34 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:101:34 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:102:29 -> IntConstant(0)
@@ -202,4 +198,4 @@
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:104:29 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:106:31 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///index.dart:106:31 -> IntConstant(0)
-Extra constant evaluation: evaluated: 579, effectively constant: 78
+Extra constant evaluation: evaluated: 571, effectively constant: 74
diff --git a/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect
index ac9d9f4..78005ed 100644
--- a/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect
@@ -3,8 +3,12 @@
V get(Object key) => _map[key];
V put(K key, V value) => _map[key] = value;
}
-extension Extension<K, V> (){}
-on MapLike<K, V> (){}
+
+extension Extension<K, V> on MapLike<K, V> {
+ V operator [](Object key) => get(key);
+ void operator []=(K key, V value) => put(key, value);
+}
+
main() {}
implicit() {}
explicitWithTypeArguments() {}
diff --git a/pkg/front_end/testcases/extensions/index.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/index.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0d5ec9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/index.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class MapLike<K, V> {
+ V get(Object key) => _map[key];
+ V put(K key, V value) => _map[key] = value;
+ final Map<K, V> _map = {};
+}
+
+expect(expected, actual) {}
+explicitInferredTypeArguments() {}
+explicitWithTypeArguments() {}
+
+extension Extension<K, V> on MapLike<K, V> {
+ V operator [](Object key) => get(key);
+ void operator []=(K key, V value) => put(key, value);
+}
+
+implicit() {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect
index 296e8e0..a9ea239 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect
@@ -3,15 +3,27 @@
Class1(this.field);
String toString() => 'Class1($field)';
}
+
class Class2 {
int field;
Class2(this.field);
String toString() => 'Class2($field)';
}
-extension Extension1 ;
-on Class1 (){}
-extension Extension2 ;
-on Class2 (){}
+
+extension Extension1 on Class1 {
+ int method() {}
+ int genericMethod<T extends num>(T t) {}
+ int get property {}
+ set property(int value) {}
+}
+
+extension Extension2 on Class2 {
+ int method() {}
+ int genericMethod<T extends num>(T t) {}
+ int get property {}
+ set property(int value) {}
+}
+
main() {}
testExtension1() {}
testExtension2() {}
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e584bee
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+class Class1 {
+ Class1(this.field);
+ String toString() => 'Class1($field)';
+ int field;
+}
+
+class Class2 {
+ Class2(this.field);
+ String toString() => 'Class2($field)';
+ int field;
+}
+
+expect(expected, actual) {}
+
+extension Extension1 on Class1 {
+ int genericMethod<T extends num>(T t) {}
+ int get property {}
+ int method() {}
+ set property(int value) {}
+}
+
+extension Extension2 on Class2 {
+ int genericMethod<T extends num>(T t) {}
+ int get property {}
+ int method() {}
+ set property(int value) {}
+}
+
+main() {}
+testExtension1() {}
+testExtension2() {}
diff --git a/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect
index 9e94fcd..8e3e499 100644
--- a/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect
@@ -1,4 +1,10 @@
class Class1 {}
-extension Extension1 ;
-on Class1 (){}
+
+extension Extension1 on Class1 {
+ static staticMethod() {}
+ static get staticProperty {}
+ static set staticProperty(int value) {}
+ static var staticField = 42;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d5db1d4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Class1 {}
+
+extension Extension1 on Class1 {
+ static get staticProperty {}
+ static set staticProperty(int value) {}
+ static staticMethod() {}
+ static var staticField = 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect
index e84610c..1fd012e 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect
@@ -1,7 +1,17 @@
class A1 {}
-extension A2 ;
-on A1 (){}
+
+extension A2 on A1 {
+ A1 method1() {}
+ A1 method2<T>(T o) {}
+ A1 method3<T>([T o]) {}
+ A1 method4<T>({T o}) {}
+}
+
class B1<T> {}
-extension B2<T> (){}
-on B1<T> (){}
+
+extension B2<T> on B1<T> {
+ B1<T> method1() {}
+ B1<T> method2<S>(S o) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bfacdaa
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class A1 {}
+
+class B1<T> {}
+
+extension A2 on A1 {
+ A1 method1() {}
+ A1 method2<T>(T o) {}
+ A1 method3<T>([T o]) {}
+ A1 method4<T>({T o}) {}
+}
+
+extension B2<T> on B1<T> {
+ B1<T> method1() {}
+ B1<T> method2<S>(S o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect
index 296e8e0..5d3c178 100644
--- a/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect
@@ -3,15 +3,23 @@
Class1(this.field);
String toString() => 'Class1($field)';
}
+
class Class2 {
int field;
Class2(this.field);
String toString() => 'Class2($field)';
}
-extension Extension1 ;
-on Class1 (){}
-extension Extension2 ;
-on Class2 (){}
+
+extension Extension1 on Class1 {
+ int method() {}
+ int genericMethod<T extends num>(T t) {}
+}
+
+extension Extension2 on Class2 {
+ int method() {}
+ int genericMethod<T extends num>(T t) {}
+}
+
main() {}
testExtension1() {}
testExtension2() {}
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ab11e38
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+class Class1 {
+ Class1(this.field);
+ String toString() => 'Class1($field)';
+ int field;
+}
+
+class Class2 {
+ Class2(this.field);
+ String toString() => 'Class2($field)';
+ int field;
+}
+
+expect(expected, actual) {}
+
+extension Extension1 on Class1 {
+ int genericMethod<T extends num>(T t) {}
+ int method() {}
+}
+
+extension Extension2 on Class2 {
+ int genericMethod<T extends num>(T t) {}
+ int method() {}
+}
+
+main() {}
+testExtension1() {}
+testExtension2() {}
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect
index 3731a57..ad984f3 100644
--- a/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect
@@ -1,9 +1,16 @@
class Class {
int field;
}
-extension on ;
-Class (){}
-extension on ;
-Class (){}
+
+extension on Class {
+ int get property1 => property2;
+ void set property1(int value) => field = value;
+}
+
+extension on Class {
+ int get property2 => field;
+ void set property2(int value) => property1 = value;
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b4a0cb3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class Class {
+ int field;
+}
+
+expect(expected, actual) {}
+
+extension on Class {
+ int get property1 => property2;
+ void set property1(int value) => field = value;
+}
+
+extension on Class {
+ int get property2 => field;
+ void set property2(int value) => property1 = value;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect
index a8a7820..fda67e5 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect
@@ -1,7 +1,13 @@
class Class {}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ method(a) {}
+}
+
class GenericClass<T> {}
-extension GenericExtension<T> (){}
-on GenericClass<T> (){}
+
+extension GenericExtension<T> on GenericClass<T> {
+ method() {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cccd074
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class Class {}
+
+class GenericClass<T> {}
+
+extension Extension on Class {
+ method(a) {}
+}
+
+extension GenericExtension<T> on GenericClass<T> {
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect
index ce040db..2654863 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect
@@ -1,4 +1,11 @@
-extension Extension ;
-on String (){}
+extension Extension on String {
+ static method() {}
+ static get getter => null;
+ static set setter(_) {}
+ static get property => null;
+ static set property(_) {}
+ static var field;
+}
+
main() {}
errors() {}
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0abe64c
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+errors() {}
+
+extension Extension on String {
+ static get getter => null;
+ static get property => null;
+ static method() {}
+ static set property(_) {}
+ static set setter(_) {}
+ static var field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect
index fd2b304..43bf0c2 100644
--- a/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect
@@ -1,4 +1,5 @@
class Class<T> {}
-extension try<T> (){}
+extension on{}
+try<T> (){}
on Class<T> (){}
main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect
index 80db8ca..ec4321b 100644
--- a/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect
@@ -1,2 +1,2 @@
-extension C (){}
+extension C on{}
void main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect
index 3843d11..07df337 100644
--- a/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect
@@ -1,3 +1,8 @@
-extension C ;
-on int (){}
+extension C on int {
+ static int property2;
+ static void set property2(int x) {}
+ static void set property3(int x) {}
+ int get property3 => 1;
+}
+
void main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8b89684
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+extension C on int {
+ int get property3 => 1;
+ static int property2;
+ static void set property2(int x) {}
+ static void set property3(int x) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect
index 61466b7..d0a4d03 100644
--- a/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect
@@ -1,5 +1,11 @@
class C<T> {}
-extension ext<T> (){}
-on C<T> (){}
+extension ext<T> on C<T> {
+ int field;
+ final int property = 42;
+ void set property(int value) {}
+ final int property2 = 42;
+ static void set property2(int value) {}
+ method() {}
+}
main() {}
errors() {}
diff --git a/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect
index b013cb4..c52f04b 100644
--- a/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect
@@ -1,4 +1,7 @@
final list = ["a", "b", "c"].myMap((it) => it);
-extension A<T> (){}
-on List<T> (){}
+
+extension A<T> on List<T> {
+ List<R> myMap<R>(R Function(T) block) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd90a7a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+extension A<T> on List<T> {
+ List<R> myMap<R>(R Function(T) block) {}
+}
+
+final list = ["a", "b", "c"].myMap((it) => it);
+main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect
index cc9ad4c..349b61f 100644
--- a/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect
@@ -1,4 +1,10 @@
class Class {}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ void method1({bool b = false, String s = ', '}) => null;
+ void method2([bool b = false, String s = ', ']) => null;
+ void method3(int i, {bool b = false, String s = ', '}) {}
+ void method4(int i, [bool b = false, String s = ', ']) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..349b61f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Class {}
+
+extension Extension on Class {
+ void method1({bool b = false, String s = ', '}) => null;
+ void method2([bool b = false, String s = ', ']) => null;
+ void method3(int i, {bool b = false, String s = ', '}) {}
+ void method4(int i, [bool b = false, String s = ', ']) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect b/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
index 8131831..16896b4 100644
--- a/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
@@ -25,15 +25,15 @@
}
static method Extension1|[](lowered final self::C* #this, core::int* index) → self::C*
return let final self::C* #t1 = #this in block {
- let final self::C* #t2 = #t1 in #t2.{self::C::value} = #t2.{self::C::value}.{core::num::+}(index.{core::num::+}(1));
+ #t1.{self::C::value} = #t1.{self::C::value}.{core::num::+}(index.{core::num::+}(1));
} =>#t1;
static method Extension1|[]=(lowered final self::C* #this, core::int* index, self::C* other) → void
- return let final self::C* #t3 = #this in #t3.{self::C::value} = #t3.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
+ return #this.{self::C::value} = #this.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
static method Extension1|-(lowered final self::C* #this, core::int* val) → self::C*
return #this;
static method main() → dynamic {
self::C* c = new self::C::•();
- let final self::C* #t4 = c in let final core::int* #t5 = 42 in let final self::C* #t6 = self::Extension1|-(self::Extension1|[](#t4, #t5), 1) in let final void #t7 = self::Extension1|[]=(#t4, #t5, #t6) in #t6;
- let final self::C* #t8 = c in let final core::int* #t9 = 42 in self::Extension1|[]=(#t8, #t9, self::Extension1|-(self::Extension1|[](#t8, #t9), 1));
+ let final self::C* #t2 = c in let final core::int* #t3 = 42 in let final self::C* #t4 = self::Extension1|-(self::Extension1|[](#t2, #t3), 1) in let final void #t5 = self::Extension1|[]=(#t2, #t3, #t4) in #t4;
+ let final self::C* #t6 = c in let final core::int* #t7 = 42 in self::Extension1|[]=(#t6, #t7, self::Extension1|-(self::Extension1|[](#t6, #t7), 1));
self::Extension1|[]=(c, 42, self::Extension1|-(self::Extension1|[](c, 42), 1));
}
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
index 85bc50b..59b0317 100644
--- a/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
@@ -25,16 +25,16 @@
}
static method Extension1|[](lowered final self::C* #this, core::int* index) → self::C*
return let final self::C* #t1 = #this in block {
- let final self::C* #t2 = #t1 in #t2.{self::C::value} = #t2.{self::C::value}.{core::num::+}(index.{core::num::+}(1));
+ #t1.{self::C::value} = #t1.{self::C::value}.{core::num::+}(index.{core::num::+}(1));
} =>#t1;
static method Extension1|[]=(lowered final self::C* #this, core::int* index, self::C* other) → void
- return let final self::C* #t3 = #this in #t3.{self::C::value} = #t3.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
+ return #this.{self::C::value} = #this.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
static method Extension1|-(lowered final self::C* #this, core::int* val) → self::C*
return #this;
static method main() → dynamic {
self::C* c = new self::C::•();
- let final self::C* #t4 = c in let final core::int* #t5 = 42 in let final self::C* #t6 = self::Extension1|-(self::Extension1|[](#t4, #t5), 1) in let final void #t7 = self::Extension1|[]=(#t4, #t5, #t6) in #t6;
- let final self::C* #t8 = c in let final core::int* #t9 = 42 in self::Extension1|[]=(#t8, #t9, self::Extension1|-(self::Extension1|[](#t8, #t9), 1));
+ let final self::C* #t2 = c in let final core::int* #t3 = 42 in let final self::C* #t4 = self::Extension1|-(self::Extension1|[](#t2, #t3), 1) in let final void #t5 = self::Extension1|[]=(#t2, #t3, #t4) in #t4;
+ let final self::C* #t6 = c in let final core::int* #t7 = 42 in self::Extension1|[]=(#t6, #t7, self::Extension1|-(self::Extension1|[](#t6, #t7), 1));
self::Extension1|[]=(c, 42, self::Extension1|-(self::Extension1|[](c, 42), 1));
}
@@ -44,4 +44,4 @@
Evaluated: VariableGet @ org-dartlang-testcase:///issue39527.dart:19:19 -> IntConstant(42)
Evaluated: VariableGet @ org-dartlang-testcase:///issue39527.dart:22:17 -> IntConstant(42)
Evaluated: VariableGet @ org-dartlang-testcase:///issue39527.dart:22:17 -> IntConstant(42)
-Extra constant evaluation: evaluated: 56, effectively constant: 4
+Extra constant evaluation: evaluated: 52, effectively constant: 4
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect
index 7ec2575..586004b 100644
--- a/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect
@@ -1,6 +1,12 @@
class C {
int value = 0;
}
-extension Extension1 ;
-on C (){}
+
+extension Extension1 on C {
+ C operator [](int index) => this..value += index + 1;
+ void operator []=(int index, C other) =>
+ this.value += other.value + index + 1;
+ C operator -(int val) => this;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..56b4c36
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class C {
+ int value = 0;
+}
+
+extension Extension1 on C {
+ C operator -(int val) => this;
+ C operator [](int index) => this..value += index + 1;
+ void operator []=(int index, C other) =>
+ this.value += other.value + index + 1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect
index 9e92bb8..2b64dea 100644
--- a/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect
@@ -1,4 +1,7 @@
class C {}
-extension E ;
-on C (){}
+
+extension E on C {
+ void f(String b) {}
+}
+
void main() {}
diff --git a/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b64dea
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {}
+
+extension E on C {
+ void f(String b) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect
index a0ad8ac..ee456e8 100644
--- a/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect
@@ -1,4 +1,7 @@
import 'dart:async';
+
void main() {}
-extension Extension<T> (){}
-on Stream<T> (){}
+
+extension Extension<T> on Stream<T> {
+ StreamSubscription<T> call(Function onData) {}
+}
diff --git a/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a5b08bb
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'dart:async';
+
+extension Extension<T> on Stream<T> {
+ StreamSubscription<T> call(Function onData) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect
index bcdffa4..86e8aaa 100644
--- a/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect
@@ -1,5 +1,7 @@
-extension SafeAccess<T> (){}
-on Iterable<T> (){}
+extension SafeAccess<T> on Iterable<T> {
+ T get safeFirst {}
+}
+
main() {}
void test() {}
void errors() {}
diff --git a/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b4b03d34
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+extension SafeAccess<T> on Iterable<T> {
+ T get safeFirst {}
+}
+
+main() {}
+void errors() {}
+void test() {}
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect
index e32df9a..e806109 100644
--- a/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect
@@ -1,5 +1,9 @@
class A {}
+
class B {}
-extension on ;
-A (){}
+
+extension on A {
+ void foo(A a, B b) {}
+}
+
void main() {}
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e806109
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {}
+
+class B {}
+
+extension on A {
+ void foo(A a, B b) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/extensions/issue43218.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue43218.dart.textual_outline.expect
index 4eec6f8..c3323e8 100644
--- a/pkg/front_end/testcases/extensions/issue43218.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/issue43218.dart.textual_outline.expect
@@ -5,7 +5,10 @@
int get id => value;
void set id(int v) {}
}
-extension Ext ;
-on C (){}
+
+extension Ext on C {
+ int get id => this.value + 1;
+}
+
test() {}
main() {}
diff --git a/pkg/front_end/testcases/extensions/issue43218.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue43218.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c5f1e6
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue43218.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class C {
+ C() : value = 0 {}
+ init() {}
+ int get id => value;
+ int value;
+ void set id(int v) {}
+}
+
+extension Ext on C {
+ int get id => this.value + 1;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/extensions/language_issue1182.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/language_issue1182.dart.textual_outline.expect
index 2f9718a..5f989b2 100644
--- a/pkg/front_end/testcases/extensions/language_issue1182.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/language_issue1182.dart.textual_outline.expect
@@ -1,6 +1,9 @@
-extension Test<T> (){}
-on T (){}
+extension Test<T> on T {
+ T Function(T) get test => (a) => this;
+}
+
class Foo<S extends num> {
void test1(S x) {}
}
+
void main() {}
diff --git a/pkg/front_end/testcases/extensions/language_issue1182.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/language_issue1182.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9aaf1c7
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/language_issue1182.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Foo<S extends num> {
+ void test1(S x) {}
+}
+
+extension Test<T> on T {
+ T Function(T) get test => (a) => this;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect
index d11cf6d..83182ff 100644
--- a/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect
@@ -1,6 +1,9 @@
class Class {}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ void set setter(int value) {}
+}
+
var c = new Class();
var missingGetter = c.setter += 42;
main() {}
diff --git a/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..94e9a17
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Class {}
+
+extension Extension on Class {
+ void set setter(int value) {}
+}
+
+main() {}
+var c = new Class();
+var missingGetter = c.setter += 42;
diff --git a/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect
index c1528bd..8970b3e 100644
--- a/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect
@@ -1,4 +1,8 @@
class A<T> {}
-extension Extension<T> (){}
-on A<A<T>> (){}
+
+extension Extension<T> on A<A<T>> {
+ method1() {}
+ method2<A>(A a) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8970b3e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A<T> {}
+
+extension Extension<T> on A<A<T>> {
+ method1() {}
+ method2<A>(A a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect
index 54442ce..378b04c 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect
@@ -1,7 +1,13 @@
class Class {
int field;
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ int get property => field;
+ void set property(int value) {}
+ int method() => field;
+ testImplicitThis() {}
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dc73414
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Class {
+ int field;
+}
+
+expect(expected, actual) {}
+
+extension Extension on Class {
+ int get property => field;
+ int method() => field;
+ testImplicitThis() {}
+ void set property(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect
index 72efc6a..7b1f078 100644
--- a/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect
@@ -1,7 +1,14 @@
-extension<R, T> on ;
-R Function(T) {}
+extension<R, T> on R Function(T) {
+ Type get returnType => R;
+ Type get parameterType => T;
+}
+
class Class<T extends Class<T>> {}
+
class Subclass extends Class<Subclass> {}
-extension<T extends Class<T>> on ;
-dynamic Function<S extends T>(T, S) {}
+
+extension<T extends Class<T>> on dynamic Function<S extends T>(T, S) {
+ Type get parameterType => T;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d84ff38
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Class<T extends Class<T>> {}
+
+class Subclass extends Class<Subclass> {}
+
+extension<R, T> on R Function(T) {
+ Type get parameterType => T;
+ Type get returnType => R;
+}
+
+extension<T extends Class<T>> on dynamic Function<S extends T>(T, S) {
+ Type get parameterType => T;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect
index 9edafca..9aa7eba 100644
--- a/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect
@@ -1,7 +1,13 @@
-extension BestCom<T extends num> (){}
-on Iterable<T> (){}
-extension BestList<T> (){}
-on List<T> (){}
-extension BestSpec ;
-on List<num> (){}
+extension BestCom<T extends num> on Iterable<T> {
+ T best() => null;
+}
+
+extension BestList<T> on List<T> {
+ T best() => null;
+}
+
+extension BestSpec on List<num> {
+ num best() => null;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9aa7eba
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+extension BestCom<T extends num> on Iterable<T> {
+ T best() => null;
+}
+
+extension BestList<T> on List<T> {
+ T best() => null;
+}
+
+extension BestSpec on List<num> {
+ num best() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect
index a75ec57..d757af3 100644
--- a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect
@@ -1,8 +1,16 @@
class Struct {}
+
class StructA extends Struct {}
+
class StructB extends Struct {}
+
class NonStruct {}
-extension Extension<T extends Struct> (){}
-on T (){}
+
+extension Extension<T extends Struct> on T {
+ T method() => this;
+ T get property => this;
+ void set property(T value) {}
+}
+
main() {}
testNonStruct() {}
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16a0644
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class NonStruct {}
+
+class Struct {}
+
+class StructA extends Struct {}
+
+class StructB extends Struct {}
+
+extension Extension<T extends Struct> on T {
+ T get property => this;
+ T method() => this;
+ void set property(T value) {}
+}
+
+main() {}
+testNonStruct() {}
diff --git a/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect
index 3ed1892..908102a 100644
--- a/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect
@@ -9,8 +9,13 @@
bool operator ==(Object other) {}
String toString() => 'Complex($real,$imaginary)';
}
-extension Operators ;
-on Complex (){}
+
+extension Operators on Complex {
+ Complex operator +(Complex other) => add(other);
+ Complex operator -(Complex other) => sub(other);
+ Complex operator -() => negate();
+}
+
main() {}
implicit() {}
explicit() {}
diff --git a/pkg/front_end/testcases/extensions/operators.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/operators.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d77488d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/operators.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class Complex {
+ Complex add(Complex other) {}
+ Complex negate() {}
+ Complex sub(Complex other) {}
+ String toString() => 'Complex($real,$imaginary)';
+ bool operator ==(Object other) {}
+ const Complex(this.real, this.imaginary);
+ final double imaginary;
+ final double real;
+ int get hashCode => real.hashCode * 13 + imaginary.hashCode * 19;
+}
+
+expect(expected, actual) {}
+explicit() {}
+
+extension Operators on Complex {
+ Complex operator +(Complex other) => add(other);
+ Complex operator -() => negate();
+ Complex operator -(Complex other) => sub(other);
+}
+
+implicit() {}
+main() {}
+void errors(Complex c) {}
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect
index bd1c7e9..85d642c 100644
--- a/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect
@@ -6,6 +6,16 @@
static int getStaticField() => _staticField;
static void setStaticField(int value) {}
}
-extension A2 ;
-on A1 (){}
+
+extension A2 on A1 {
+ int get instanceProperty => getInstanceField();
+ void set instanceProperty(int value) {}
+ int operator +(int value) {}
+ int operator -(int value) {}
+ int operator -() {}
+ static int staticField = A1.getStaticField();
+ static int get staticProperty => A1.getStaticField();
+ static void set staticProperty(int value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1e10a1c
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+class A1 {
+ int _instanceField;
+ int getInstanceField() => _instanceField;
+ static int _staticField = 0;
+ static int getStaticField() => _staticField;
+ static void setStaticField(int value) {}
+ void setInstanceField(int value) {}
+}
+
+extension A2 on A1 {
+ int get instanceProperty => getInstanceField();
+ int operator +(int value) {}
+ int operator -() {}
+ int operator -(int value) {}
+ static int get staticProperty => A1.getStaticField();
+ static int staticField = A1.getStaticField();
+ static void set staticProperty(int value) {}
+ void set instanceProperty(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect
index cc9ad4c..af89663 100644
--- a/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect
@@ -1,4 +1,14 @@
class Class {}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ static method() {}
+ static genericMethod<T>(T t) {}
+ static get property => 42;
+ static set property(value) {}
+ static var field;
+ instanceMethod() {}
+ get instanceProperty => 42;
+ set instanceProperty(value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/static_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7a88d1
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Class {}
+
+extension Extension on Class {
+ get instanceProperty => 42;
+ instanceMethod() {}
+ set instanceProperty(value) {}
+ static genericMethod<T>(T t) {}
+ static get property => 42;
+ static method() {}
+ static set property(value) {}
+ static var field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect
index cc9ad4c..38dbcbf 100644
--- a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect
@@ -1,4 +1,9 @@
class Class {}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ instanceMethod() {}
+ get instanceProperty => 42;
+ set instanceProperty(value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..114f677
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Class {}
+
+extension Extension on Class {
+ get instanceProperty => 42;
+ instanceMethod() {}
+ set instanceProperty(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect
index 9c93cbd..45dbc23 100644
--- a/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect
@@ -1,5 +1,11 @@
class Class {}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ T id<T>(T t) => t;
+ T Function<T>(T) get getter => id;
+ method() {}
+ errors() {}
+}
+
main() {}
errors() {}
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ce0c980
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class Class {}
+
+errors() {}
+
+extension Extension on Class {
+ T Function<T>(T) get getter => id;
+ T id<T>(T t) => t;
+ errors() {}
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/type_variable_bound.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/type_variable_bound.dart.textual_outline.expect
index a9b3ce3..59d5ad1 100644
--- a/pkg/front_end/testcases/extensions/type_variable_bound.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/type_variable_bound.dart.textual_outline.expect
@@ -1,10 +1,16 @@
// @dart = 2.8
-extension Extension<T> (){}
-on T (){}
-extension BoundExtension<T extends Class> (){}
-on T (){}
+extension Extension<T> on T {
+ T method1() => this;
+}
+
+extension BoundExtension<T extends Class> on T {
+ T method2() => this;
+}
+
class Class {}
+
class SubClass extends Class {}
+
Class test1<T>(T t1) {}
test2<T extends Class>(T t2) {}
test3<T>(T t3) {}
diff --git a/pkg/front_end/testcases/extensions/type_variable_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/type_variable_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a08e473
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/type_variable_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.8
+Class test1<T>(T t1) {}
+
+class Class {}
+
+class SubClass extends Class {}
+
+extension BoundExtension<T extends Class> on T {
+ T method2() => this;
+}
+
+extension Extension<T> on T {
+ T method1() => this;
+}
+
+main() {}
+test2<T extends Class>(T t2) {}
+test3<T>(T t3) {}
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect
index 60b1f69..4f3bfdf 100644
--- a/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect
@@ -1,8 +1,14 @@
class A1<T> {}
-extension A2<T> (){}
-on A1<T> (){}
-extension A3<T extends A1<T>> (){}
-on A1<T> (){}
-extension A4<T> (){}
-on A1<T> (){}
+
+extension A2<T> on A1<T> {
+ A1<T> method1<S extends T>() {}
+ A1<T> method2<S extends A1<T>>(S o) {}
+}
+
+extension A3<T extends A1<T>> on A1<T> {}
+
+extension A4<T> on A1<T> {
+ method<T>() {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4f3bfdf
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A1<T> {}
+
+extension A2<T> on A1<T> {
+ A1<T> method1<S extends T>() {}
+ A1<T> method2<S extends A1<T>>(S o) {}
+}
+
+extension A3<T extends A1<T>> on A1<T> {}
+
+extension A4<T> on A1<T> {
+ method<T>() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect
index 8641f18..792016b 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect
@@ -3,15 +3,27 @@
Class1(this.field);
String toString() => 'Class1($field)';
}
+
class Class2 {
int field;
Class2(this.field);
String toString() => 'Class2($field)';
}
-extension on ;
-Class1 (){}
-extension on ;
-Class2 (){}
+
+extension on Class1 {
+ int method() {}
+ int genericMethod<T extends num>(T t) {}
+ int get property {}
+ set property(int value) {}
+}
+
+extension on Class2 {
+ int method() {}
+ int genericMethod<T extends num>(T t) {}
+ int get property {}
+ set property(int value) {}
+}
+
main() {}
testExtension1() {}
testExtension2() {}
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..66a7a5b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+class Class1 {
+ Class1(this.field);
+ String toString() => 'Class1($field)';
+ int field;
+}
+
+class Class2 {
+ Class2(this.field);
+ String toString() => 'Class2($field)';
+ int field;
+}
+
+expect(expected, actual) {}
+
+extension on Class1 {
+ int genericMethod<T extends num>(T t) {}
+ int get property {}
+ int method() {}
+ set property(int value) {}
+}
+
+extension on Class2 {
+ int genericMethod<T extends num>(T t) {}
+ int get property {}
+ int method() {}
+ set property(int value) {}
+}
+
+main() {}
+testExtension1() {}
+testExtension2() {}
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect
index e84610c..f12590a 100644
--- a/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect
@@ -1,7 +1,15 @@
class A1 {}
-extension A2 ;
-on A1 (){}
+
+extension A2 on A1 {
+ A1 method1() {}
+ A1 method2<T>(T o) {}
+}
+
class B1<T> {}
-extension B2<T> (){}
-on B1<T> (){}
+
+extension B2<T> on B1<T> {
+ B1<T> method1() {}
+ B1<T> method2<S>(S o) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/use_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f79fb58
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/use_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A1 {}
+
+class B1<T> {}
+
+extension A2 on A1 {
+ A1 method1() {}
+ A1 method2<T>(T o) {}
+}
+
+extension B2<T> on B1<T> {
+ B1<T> method1() {}
+ B1<T> method2<S>(S o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline.expect
index 47e2d86..4c98331 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline.expect
@@ -19,6 +19,7 @@
static num get property9 => 0;
static void set property9(String value) {}
}
+
abstract class B1 {
int get property1;
int get property2;
@@ -28,6 +29,7 @@
final String property6;
B1(this.property4, this.property5, this.property6);
}
+
abstract class B2 implements B1 {
void set property1(int i);
void set property2(String i);
@@ -36,6 +38,7 @@
void set property5(String i);
void set property6(int i);
}
+
abstract class C1 {
void set property1(int i);
void set property2(String i);
@@ -44,6 +47,7 @@
String property5;
int property6;
}
+
abstract class C2 implements C1 {
int get property1;
int get property2;
@@ -52,18 +56,48 @@
int get property5;
String get property6;
}
+
abstract class D1 {
int get property1;
int get property2;
String get property3;
}
+
abstract class D2 {
void set property1(int i);
void set property2(String i);
void set property3(int i);
}
+
abstract class D3 implements D1, D2 {}
+
abstract class D4 implements D3 {}
-extension Extension<T extends num, S extends T> (){}
-on int (){}
+
+extension Extension<T extends num, S extends T> on int {
+ int get property1 => 0;
+ void set property1(int i) {}
+ num get property2a => 0;
+ void set property2a(int i) {}
+ int get property2b => 0;
+ void set property2b(num i) {}
+ String get property3 => '';
+ void set property3(int i) {}
+ S get property4 => 0;
+ void set property4(S i) {}
+ S get property5a => 0;
+ void set property5a(T i) {}
+ T get property5b => 0;
+ void set property5b(S i) {}
+ String get property6 => '';
+ void set property6(S i) {}
+ static int get property7 => 0;
+ static void set property7(int value) {}
+ static int get property8a => 0;
+ static void set property8a(num value) {}
+ static num get property8b => 0;
+ static void set property8b(int value) {}
+ static num get property9 => 0;
+ static void set property9(String value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline_modelled.expect
index e2ee020..0d0827c 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline_modelled.expect
@@ -73,4 +73,31 @@
abstract class D4 implements D3 {}
+extension Extension<T extends num, S extends T> on int {
+ S get property4 => 0;
+ S get property5a => 0;
+ String get property3 => '';
+ String get property6 => '';
+ T get property5b => 0;
+ int get property1 => 0;
+ int get property2b => 0;
+ num get property2a => 0;
+ static int get property7 => 0;
+ static int get property8a => 0;
+ static num get property8b => 0;
+ static num get property9 => 0;
+ static void set property7(int value) {}
+ static void set property8a(num value) {}
+ static void set property8b(int value) {}
+ static void set property9(String value) {}
+ void set property1(int i) {}
+ void set property2a(int i) {}
+ void set property2b(num i) {}
+ void set property3(int i) {}
+ void set property4(S i) {}
+ void set property5a(T i) {}
+ void set property5b(S i) {}
+ void set property6(S i) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect
index c862500..4b76f91 100644
--- a/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect
@@ -1,5 +1,8 @@
class C {}
-extension E ;
-on C (){}
+
+extension E on C {
+ errors() {}
+}
+
errors() {}
main() {}
diff --git a/pkg/front_end/testcases/general/issue40242.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40242.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..91844c5
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40242.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class C {}
+
+errors() {}
+
+extension E on C {
+ errors() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/pure_index_expressions.dart b/pkg/front_end/testcases/general/pure_index_expressions.dart
new file mode 100644
index 0000000..975089a
--- /dev/null
+++ b/pkg/front_end/testcases/general/pure_index_expressions.dart
@@ -0,0 +1,215 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+extension Extension on int {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+}
+
+class Class {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+ Class operator +(Class cls) => cls;
+
+ void indexGetSetForEffect(Map<Class, Class> map) {
+ final Class self = this;
+ map[this] ??= this;
+ map[self] ??= self;
+
+ map[this] = this;
+ map[self] = self;
+
+ map[this];
+ map[self];
+
+ map[this] += this;
+ map[self] += self;
+ }
+
+ void indexGetSetForValue(Map<Class, Class> map) {
+ final Class self = this;
+ var v;
+ v = map[this] ??= this;
+ v = map[self] ??= self;
+
+ v = map[this] = this;
+ v = map[self] = self;
+
+ v = map[this];
+ v = map[self];
+
+ v = map[this] += this;
+ v = map[self] += self;
+ }
+
+ void implicitExtensionGetSetForEffect(int i) {
+ final Class self = this;
+ i[this] ??= this;
+ i[self] ??= self;
+
+ i[this] = this;
+ i[self] = self;
+
+ i[this];
+ i[self];
+
+ i[this] += this;
+ i[self] += self;
+ }
+
+ void implicitExtensionGetSetForValue(int i) {
+ final Class self = this;
+ var v;
+ v = i[this] ??= this;
+ v = i[self] ??= self;
+
+ v = i[this] = this;
+ v = i[self] = self;
+
+ v = i[this];
+ v = i[self];
+
+ v = i[this] += this;
+ v = i[self] += self;
+ }
+
+ void explicitExtensionGetSetForEffect(int i) {
+ final Class self = this;
+ Extension(i)[this] ??= this;
+ Extension(i)[self] ??= self;
+
+ Extension(i)[this] = this;
+ Extension(i)[self] = self;
+
+ Extension(i)[this];
+ Extension(i)[self];
+
+ Extension(i)[this] += this;
+ Extension(i)[self] += self;
+ }
+
+ void explicitExtensionGetSetForValue(int i) {
+ final Class self = this;
+ var v;
+ v = Extension(i)[this] ??= this;
+ v = Extension(i)[self] ??= self;
+
+ v = Extension(i)[this] = this;
+ v = Extension(i)[self] = self;
+
+ v = Extension(i)[this];
+ v = Extension(i)[self];
+
+ v = Extension(i)[this] += this;
+ v = Extension(i)[self] += self;
+ }
+}
+
+class Subclass extends Class {
+ void superIndexGetSetForEffect() {
+ final Class self = this;
+ super[this] ??= this;
+ super[self] ??= self;
+
+ super[this] = this;
+ super[self] = self;
+
+ super[this];
+ super[self];
+
+ super[this] += this;
+ super[self] += self;
+ }
+
+ void superIndexGetSetForValue() {
+ final Class self = this;
+ var v;
+ v = super[this] ??= this;
+ v = super[self] ??= self;
+
+ v = super[this] = this;
+ v = super[self] = self;
+
+ v = super[this];
+ v = super[self];
+
+ v = super[this] += this;
+ v = super[self] += self;
+ }
+}
+
+extension Extension2 on Class2 {
+ Class2 operator [](Class2 cls) => new Class2();
+ void operator []=(Class2 cls, Class2 value) {}
+}
+
+class Class2 {
+ Class2 operator +(Class2 cls) => cls;
+
+ void implicitExtensionGetSetForEffect() {
+ final Class2 self = this;
+ this[this] ??= this;
+ self[self] ??= self;
+
+ this[this] = this;
+ self[self] = self;
+
+ this[this];
+ self[self];
+
+ this[this] += this;
+ self[self] += self;
+ }
+
+ void implicitExtensionGetSetForValue() {
+ final Class2 self = this;
+ var v;
+ v = this[this] ??= this;
+ v = self[self] ??= self;
+
+ v = this[this] = this;
+ v = self[self] = self;
+
+ v = this[this];
+ v = self[self];
+
+ v = this[this] += this;
+ v = self[self] += self;
+ }
+
+ void explicitExtensionGetSetForEffect() {
+ final Class2 self = this;
+ Extension2(this)[this] ??= this;
+ Extension2(self)[self] ??= self;
+
+ Extension2(this)[this] = this;
+ Extension2(self)[self] = self;
+
+ Extension2(this)[this];
+ Extension2(self)[self];
+
+ Extension2(this)[this] += this;
+ Extension2(self)[self] += self;
+ }
+
+ void explicitExtensionGetSetForValue() {
+ final Class2 self = this;
+ var v;
+ v = Extension2(this)[this] ??= this;
+ v = Extension2(self)[self] ??= self;
+
+ v = Extension2(this)[this] = this;
+ v = Extension2(self)[self] = self;
+
+ v = Extension2(this)[this];
+ v = Extension2(self)[self];
+
+ v = Extension2(this)[this] += this;
+ v = Extension2(self)[self] += self;
+ }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/pure_index_expressions.dart.outline.expect b/pkg/front_end/testcases/general/pure_index_expressions.dart.outline.expect
new file mode 100644
index 0000000..df6fc30
--- /dev/null
+++ b/pkg/front_end/testcases/general/pure_index_expressions.dart.outline.expect
@@ -0,0 +1,86 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ ;
+ operator [](self::Class* cls) → self::Class*
+ ;
+ operator []=(self::Class* cls, self::Class* value) → void
+ ;
+ operator +(self::Class* cls) → self::Class*
+ ;
+ method indexGetSetForEffect(core::Map<self::Class*, self::Class*>* map) → void
+ ;
+ method indexGetSetForValue(core::Map<self::Class*, self::Class*>* map) → void
+ ;
+ method implicitExtensionGetSetForEffect(core::int* i) → void
+ ;
+ method implicitExtensionGetSetForValue(core::int* i) → void
+ ;
+ method explicitExtensionGetSetForEffect(core::int* i) → void
+ ;
+ method explicitExtensionGetSetForValue(core::int* i) → void
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class Subclass extends self::Class {
+ synthetic constructor •() → self::Subclass*
+ ;
+ method superIndexGetSetForEffect() → void
+ ;
+ method superIndexGetSetForValue() → void
+ ;
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2*
+ ;
+ operator +(self::Class2* cls) → self::Class2*
+ ;
+ method implicitExtensionGetSetForEffect() → void
+ ;
+ method implicitExtensionGetSetForValue() → void
+ ;
+ method explicitExtensionGetSetForEffect() → void
+ ;
+ method explicitExtensionGetSetForValue() → void
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+extension Extension on core::int* {
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+}
+extension Extension2 on self::Class2* {
+ operator [] = self::Extension2|[];
+ operator []= = self::Extension2|[]=;
+}
+static method Extension|[](lowered final core::int* #this, self::Class* cls) → self::Class*
+ ;
+static method Extension|[]=(lowered final core::int* #this, self::Class* cls, self::Class* value) → void
+ ;
+static method Extension2|[](lowered final self::Class2* #this, self::Class2* cls) → self::Class2*
+ ;
+static method Extension2|[]=(lowered final self::Class2* #this, self::Class2* cls, self::Class2* value) → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/pure_index_expressions.dart.strong.expect b/pkg/front_end/testcases/general/pure_index_expressions.dart.strong.expect
new file mode 100644
index 0000000..ed17f97
--- /dev/null
+++ b/pkg/front_end/testcases/general/pure_index_expressions.dart.strong.expect
@@ -0,0 +1,199 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ operator [](self::Class* cls) → self::Class*
+ return new self::Class::•();
+ operator []=(self::Class* cls, self::Class* value) → void {}
+ operator +(self::Class* cls) → self::Class*
+ return cls;
+ method indexGetSetForEffect(core::Map<self::Class*, self::Class*>* map) → void {
+ final self::Class* self = this;
+ let final core::Map<self::Class*, self::Class*>* #t1 = map in #t1.{core::Map::[]}(this).{self::Class::==}(null) ?{self::Class*} #t1.{core::Map::[]=}(this, this) : null;
+ let final core::Map<self::Class*, self::Class*>* #t2 = map in #t2.{core::Map::[]}(self).{self::Class::==}(null) ?{self::Class*} #t2.{core::Map::[]=}(self, self) : null;
+ map.{core::Map::[]=}(this, this);
+ map.{core::Map::[]=}(self, self);
+ map.{core::Map::[]}(this);
+ map.{core::Map::[]}(self);
+ let final core::Map<self::Class*, self::Class*>* #t3 = map in #t3.{core::Map::[]=}(this, #t3.{core::Map::[]}(this).{self::Class::+}(this));
+ let final core::Map<self::Class*, self::Class*>* #t4 = map in #t4.{core::Map::[]=}(self, #t4.{core::Map::[]}(self).{self::Class::+}(self));
+ }
+ method indexGetSetForValue(core::Map<self::Class*, self::Class*>* map) → void {
+ final self::Class* self = this;
+ dynamic v;
+ v = let final core::Map<self::Class*, self::Class*>* #t5 = map in let final self::Class* #t6 = #t5.{core::Map::[]}(this) in #t6.{self::Class::==}(null) ?{self::Class*} let final void #t7 = #t5.{core::Map::[]=}(this, this) in this : #t6;
+ v = let final core::Map<self::Class*, self::Class*>* #t8 = map in let final self::Class* #t9 = #t8.{core::Map::[]}(self) in #t9.{self::Class::==}(null) ?{self::Class*} let final void #t10 = #t8.{core::Map::[]=}(self, self) in self : #t9;
+ v = let final core::Map<self::Class*, self::Class*>* #t11 = map in let final void #t12 = #t11.{core::Map::[]=}(this, this) in this;
+ v = let final core::Map<self::Class*, self::Class*>* #t13 = map in let final void #t14 = #t13.{core::Map::[]=}(self, self) in self;
+ v = map.{core::Map::[]}(this);
+ v = map.{core::Map::[]}(self);
+ v = let final core::Map<self::Class*, self::Class*>* #t15 = map in let final self::Class* #t16 = #t15.{core::Map::[]}(this).{self::Class::+}(this) in let final void #t17 = #t15.{core::Map::[]=}(this, #t16) in #t16;
+ v = let final core::Map<self::Class*, self::Class*>* #t18 = map in let final self::Class* #t19 = #t18.{core::Map::[]}(self).{self::Class::+}(self) in let final void #t20 = #t18.{core::Map::[]=}(self, #t19) in #t19;
+ }
+ method implicitExtensionGetSetForEffect(core::int* i) → void {
+ final self::Class* self = this;
+ let final core::int* #t21 = i in self::Extension|[](#t21, this).{self::Class::==}(null) ?{self::Class*} self::Extension|[]=(#t21, this, this) : null;
+ let final core::int* #t22 = i in self::Extension|[](#t22, self).{self::Class::==}(null) ?{self::Class*} self::Extension|[]=(#t22, self, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int* #t23 = i in self::Extension|[]=(#t23, this, self::Extension|[](#t23, this).{self::Class::+}(this));
+ let final core::int* #t24 = i in self::Extension|[]=(#t24, self, self::Extension|[](#t24, self).{self::Class::+}(self));
+ }
+ method implicitExtensionGetSetForValue(core::int* i) → void {
+ final self::Class* self = this;
+ dynamic v;
+ v = let final core::int* #t25 = i in let final self::Class* #t26 = self::Extension|[](#t25, this) in #t26.{self::Class::==}(null) ?{self::Class*} let final void #t27 = self::Extension|[]=(#t25, this, this) in this : #t26;
+ v = let final core::int* #t28 = i in let final self::Class* #t29 = self::Extension|[](#t28, self) in #t29.{self::Class::==}(null) ?{self::Class*} let final void #t30 = self::Extension|[]=(#t28, self, self) in self : #t29;
+ v = let final core::int* #t31 = i in let final void #t32 = self::Extension|[]=(#t31, this, this) in this;
+ v = let final core::int* #t33 = i in let final void #t34 = self::Extension|[]=(#t33, self, self) in self;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int* #t35 = i in let final self::Class* #t36 = self::Extension|[](#t35, this).{self::Class::+}(this) in let final void #t37 = self::Extension|[]=(#t35, this, #t36) in #t36;
+ v = let final core::int* #t38 = i in let final self::Class* #t39 = self::Extension|[](#t38, self).{self::Class::+}(self) in let final void #t40 = self::Extension|[]=(#t38, self, #t39) in #t39;
+ }
+ method explicitExtensionGetSetForEffect(core::int* i) → void {
+ final self::Class* self = this;
+ let final core::int* #t41 = i in self::Extension|[](#t41, this).{self::Class::==}(null) ?{self::Class*} self::Extension|[]=(#t41, this, this) : null;
+ let final core::int* #t42 = i in self::Extension|[](#t42, self).{self::Class::==}(null) ?{self::Class*} self::Extension|[]=(#t42, self, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int* #t43 = i in self::Extension|[]=(#t43, this, self::Extension|[](#t43, this).{self::Class::+}(this));
+ let final core::int* #t44 = i in self::Extension|[]=(#t44, self, self::Extension|[](#t44, self).{self::Class::+}(self));
+ }
+ method explicitExtensionGetSetForValue(core::int* i) → void {
+ final self::Class* self = this;
+ dynamic v;
+ v = let final core::int* #t45 = i in let final self::Class* #t46 = self::Extension|[](#t45, this) in #t46.{self::Class::==}(null) ?{self::Class*} let final void #t47 = self::Extension|[]=(#t45, this, this) in this : #t46;
+ v = let final core::int* #t48 = i in let final self::Class* #t49 = self::Extension|[](#t48, self) in #t49.{self::Class::==}(null) ?{self::Class*} let final void #t50 = self::Extension|[]=(#t48, self, self) in self : #t49;
+ v = let final core::int* #t51 = i in let final void #t52 = self::Extension|[]=(#t51, this, this) in this;
+ v = let final core::int* #t53 = i in let final void #t54 = self::Extension|[]=(#t53, self, self) in self;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int* #t55 = i in let final self::Class* #t56 = self::Extension|[](#t55, this).{self::Class::+}(this) in let final void #t57 = self::Extension|[]=(#t55, this, #t56) in #t56;
+ v = let final core::int* #t58 = i in let final self::Class* #t59 = self::Extension|[](#t58, self).{self::Class::+}(self) in let final void #t60 = self::Extension|[]=(#t58, self, #t59) in #t59;
+ }
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class Subclass extends self::Class {
+ synthetic constructor •() → self::Subclass*
+ : super self::Class::•()
+ ;
+ method superIndexGetSetForEffect() → void {
+ final self::Class* self = this;
+ super.{self::Class::[]}(this).{self::Class::==}(null) ?{self::Class*} super.{self::Class::[]=}(this, this) : null;
+ super.{self::Class::[]}(self).{self::Class::==}(null) ?{self::Class*} super.{self::Class::[]=}(self, self) : null;
+ super.{self::Class::[]=}(this, this);
+ super.{self::Class::[]=}(self, self);
+ super.{self::Class::[]}(this);
+ super.{self::Class::[]}(self);
+ super.{self::Class::[]=}(this, super.{self::Class::[]}(this).{self::Class::+}(this));
+ super.{self::Class::[]=}(self, super.{self::Class::[]}(self).{self::Class::+}(self));
+ }
+ method superIndexGetSetForValue() → void {
+ final self::Class* self = this;
+ dynamic v;
+ v = let final self::Class* #t61 = super.{self::Class::[]}(this) in #t61.{self::Class::==}(null) ?{self::Class*} let final void #t62 = super.{self::Class::[]=}(this, this) in this : #t61;
+ v = let final self::Class* #t63 = super.{self::Class::[]}(self) in #t63.{self::Class::==}(null) ?{self::Class*} let final void #t64 = super.{self::Class::[]=}(self, self) in self : #t63;
+ v = let final void #t65 = super.{self::Class::[]=}(this, this) in this;
+ v = let final void #t66 = super.{self::Class::[]=}(self, self) in self;
+ v = super.{self::Class::[]}(this);
+ v = super.{self::Class::[]}(self);
+ v = let final self::Class* #t67 = super.{self::Class::[]}(this).{self::Class::+}(this) in let final void #t68 = super.{self::Class::[]=}(this, #t67) in #t67;
+ v = let final self::Class* #t69 = super.{self::Class::[]}(self).{self::Class::+}(self) in let final void #t70 = super.{self::Class::[]=}(self, #t69) in #t69;
+ }
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2*
+ : super core::Object::•()
+ ;
+ operator +(self::Class2* cls) → self::Class2*
+ return cls;
+ method implicitExtensionGetSetForEffect() → void {
+ final self::Class2* self = this;
+ self::Extension2|[](this, this).{self::Class2::==}(null) ?{self::Class2*} self::Extension2|[]=(this, this, this) : null;
+ self::Extension2|[](self, self).{self::Class2::==}(null) ?{self::Class2*} self::Extension2|[]=(self, self, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ self::Extension2|[]=(self, self, self::Extension2|[](self, self).{self::Class2::+}(self));
+ }
+ method implicitExtensionGetSetForValue() → void {
+ final self::Class2* self = this;
+ dynamic v;
+ v = let final self::Class2* #t71 = self::Extension2|[](this, this) in #t71.{self::Class2::==}(null) ?{self::Class2*} let final void #t72 = self::Extension2|[]=(this, this, this) in this : #t71;
+ v = let final self::Class2* #t73 = self::Extension2|[](self, self) in #t73.{self::Class2::==}(null) ?{self::Class2*} let final void #t74 = self::Extension2|[]=(self, self, self) in self : #t73;
+ v = let final void #t75 = self::Extension2|[]=(this, this, this) in this;
+ v = let final void #t76 = self::Extension2|[]=(self, self, self) in self;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2* #t77 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t78 = self::Extension2|[]=(this, this, #t77) in #t77;
+ v = let final self::Class2* #t79 = self::Extension2|[](self, self).{self::Class2::+}(self) in let final void #t80 = self::Extension2|[]=(self, self, #t79) in #t79;
+ }
+ method explicitExtensionGetSetForEffect() → void {
+ final self::Class2* self = this;
+ self::Extension2|[](this, this).{self::Class2::==}(null) ?{self::Class2*} self::Extension2|[]=(this, this, this) : null;
+ self::Extension2|[](self, self).{self::Class2::==}(null) ?{self::Class2*} self::Extension2|[]=(self, self, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ self::Extension2|[]=(self, self, self::Extension2|[](self, self).{self::Class2::+}(self));
+ }
+ method explicitExtensionGetSetForValue() → void {
+ final self::Class2* self = this;
+ dynamic v;
+ v = let final self::Class2* #t81 = self::Extension2|[](this, this) in #t81.{self::Class2::==}(null) ?{self::Class2*} let final void #t82 = self::Extension2|[]=(this, this, this) in this : #t81;
+ v = let final self::Class2* #t83 = self::Extension2|[](self, self) in #t83.{self::Class2::==}(null) ?{self::Class2*} let final void #t84 = self::Extension2|[]=(self, self, self) in self : #t83;
+ v = let final void #t85 = self::Extension2|[]=(this, this, this) in this;
+ v = let final void #t86 = self::Extension2|[]=(self, self, self) in self;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2* #t87 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t88 = self::Extension2|[]=(this, this, #t87) in #t87;
+ v = let final self::Class2* #t89 = self::Extension2|[](self, self).{self::Class2::+}(self) in let final void #t90 = self::Extension2|[]=(self, self, #t89) in #t89;
+ }
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+extension Extension on core::int* {
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+}
+extension Extension2 on self::Class2* {
+ operator [] = self::Extension2|[];
+ operator []= = self::Extension2|[]=;
+}
+static method Extension|[](lowered final core::int* #this, self::Class* cls) → self::Class*
+ return new self::Class::•();
+static method Extension|[]=(lowered final core::int* #this, self::Class* cls, self::Class* value) → void {}
+static method Extension2|[](lowered final self::Class2* #this, self::Class2* cls) → self::Class2*
+ return new self::Class2::•();
+static method Extension2|[]=(lowered final self::Class2* #this, self::Class2* cls, self::Class2* value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/pure_index_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/general/pure_index_expressions.dart.strong.transformed.expect
new file mode 100644
index 0000000..ed17f97
--- /dev/null
+++ b/pkg/front_end/testcases/general/pure_index_expressions.dart.strong.transformed.expect
@@ -0,0 +1,199 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ operator [](self::Class* cls) → self::Class*
+ return new self::Class::•();
+ operator []=(self::Class* cls, self::Class* value) → void {}
+ operator +(self::Class* cls) → self::Class*
+ return cls;
+ method indexGetSetForEffect(core::Map<self::Class*, self::Class*>* map) → void {
+ final self::Class* self = this;
+ let final core::Map<self::Class*, self::Class*>* #t1 = map in #t1.{core::Map::[]}(this).{self::Class::==}(null) ?{self::Class*} #t1.{core::Map::[]=}(this, this) : null;
+ let final core::Map<self::Class*, self::Class*>* #t2 = map in #t2.{core::Map::[]}(self).{self::Class::==}(null) ?{self::Class*} #t2.{core::Map::[]=}(self, self) : null;
+ map.{core::Map::[]=}(this, this);
+ map.{core::Map::[]=}(self, self);
+ map.{core::Map::[]}(this);
+ map.{core::Map::[]}(self);
+ let final core::Map<self::Class*, self::Class*>* #t3 = map in #t3.{core::Map::[]=}(this, #t3.{core::Map::[]}(this).{self::Class::+}(this));
+ let final core::Map<self::Class*, self::Class*>* #t4 = map in #t4.{core::Map::[]=}(self, #t4.{core::Map::[]}(self).{self::Class::+}(self));
+ }
+ method indexGetSetForValue(core::Map<self::Class*, self::Class*>* map) → void {
+ final self::Class* self = this;
+ dynamic v;
+ v = let final core::Map<self::Class*, self::Class*>* #t5 = map in let final self::Class* #t6 = #t5.{core::Map::[]}(this) in #t6.{self::Class::==}(null) ?{self::Class*} let final void #t7 = #t5.{core::Map::[]=}(this, this) in this : #t6;
+ v = let final core::Map<self::Class*, self::Class*>* #t8 = map in let final self::Class* #t9 = #t8.{core::Map::[]}(self) in #t9.{self::Class::==}(null) ?{self::Class*} let final void #t10 = #t8.{core::Map::[]=}(self, self) in self : #t9;
+ v = let final core::Map<self::Class*, self::Class*>* #t11 = map in let final void #t12 = #t11.{core::Map::[]=}(this, this) in this;
+ v = let final core::Map<self::Class*, self::Class*>* #t13 = map in let final void #t14 = #t13.{core::Map::[]=}(self, self) in self;
+ v = map.{core::Map::[]}(this);
+ v = map.{core::Map::[]}(self);
+ v = let final core::Map<self::Class*, self::Class*>* #t15 = map in let final self::Class* #t16 = #t15.{core::Map::[]}(this).{self::Class::+}(this) in let final void #t17 = #t15.{core::Map::[]=}(this, #t16) in #t16;
+ v = let final core::Map<self::Class*, self::Class*>* #t18 = map in let final self::Class* #t19 = #t18.{core::Map::[]}(self).{self::Class::+}(self) in let final void #t20 = #t18.{core::Map::[]=}(self, #t19) in #t19;
+ }
+ method implicitExtensionGetSetForEffect(core::int* i) → void {
+ final self::Class* self = this;
+ let final core::int* #t21 = i in self::Extension|[](#t21, this).{self::Class::==}(null) ?{self::Class*} self::Extension|[]=(#t21, this, this) : null;
+ let final core::int* #t22 = i in self::Extension|[](#t22, self).{self::Class::==}(null) ?{self::Class*} self::Extension|[]=(#t22, self, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int* #t23 = i in self::Extension|[]=(#t23, this, self::Extension|[](#t23, this).{self::Class::+}(this));
+ let final core::int* #t24 = i in self::Extension|[]=(#t24, self, self::Extension|[](#t24, self).{self::Class::+}(self));
+ }
+ method implicitExtensionGetSetForValue(core::int* i) → void {
+ final self::Class* self = this;
+ dynamic v;
+ v = let final core::int* #t25 = i in let final self::Class* #t26 = self::Extension|[](#t25, this) in #t26.{self::Class::==}(null) ?{self::Class*} let final void #t27 = self::Extension|[]=(#t25, this, this) in this : #t26;
+ v = let final core::int* #t28 = i in let final self::Class* #t29 = self::Extension|[](#t28, self) in #t29.{self::Class::==}(null) ?{self::Class*} let final void #t30 = self::Extension|[]=(#t28, self, self) in self : #t29;
+ v = let final core::int* #t31 = i in let final void #t32 = self::Extension|[]=(#t31, this, this) in this;
+ v = let final core::int* #t33 = i in let final void #t34 = self::Extension|[]=(#t33, self, self) in self;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int* #t35 = i in let final self::Class* #t36 = self::Extension|[](#t35, this).{self::Class::+}(this) in let final void #t37 = self::Extension|[]=(#t35, this, #t36) in #t36;
+ v = let final core::int* #t38 = i in let final self::Class* #t39 = self::Extension|[](#t38, self).{self::Class::+}(self) in let final void #t40 = self::Extension|[]=(#t38, self, #t39) in #t39;
+ }
+ method explicitExtensionGetSetForEffect(core::int* i) → void {
+ final self::Class* self = this;
+ let final core::int* #t41 = i in self::Extension|[](#t41, this).{self::Class::==}(null) ?{self::Class*} self::Extension|[]=(#t41, this, this) : null;
+ let final core::int* #t42 = i in self::Extension|[](#t42, self).{self::Class::==}(null) ?{self::Class*} self::Extension|[]=(#t42, self, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int* #t43 = i in self::Extension|[]=(#t43, this, self::Extension|[](#t43, this).{self::Class::+}(this));
+ let final core::int* #t44 = i in self::Extension|[]=(#t44, self, self::Extension|[](#t44, self).{self::Class::+}(self));
+ }
+ method explicitExtensionGetSetForValue(core::int* i) → void {
+ final self::Class* self = this;
+ dynamic v;
+ v = let final core::int* #t45 = i in let final self::Class* #t46 = self::Extension|[](#t45, this) in #t46.{self::Class::==}(null) ?{self::Class*} let final void #t47 = self::Extension|[]=(#t45, this, this) in this : #t46;
+ v = let final core::int* #t48 = i in let final self::Class* #t49 = self::Extension|[](#t48, self) in #t49.{self::Class::==}(null) ?{self::Class*} let final void #t50 = self::Extension|[]=(#t48, self, self) in self : #t49;
+ v = let final core::int* #t51 = i in let final void #t52 = self::Extension|[]=(#t51, this, this) in this;
+ v = let final core::int* #t53 = i in let final void #t54 = self::Extension|[]=(#t53, self, self) in self;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int* #t55 = i in let final self::Class* #t56 = self::Extension|[](#t55, this).{self::Class::+}(this) in let final void #t57 = self::Extension|[]=(#t55, this, #t56) in #t56;
+ v = let final core::int* #t58 = i in let final self::Class* #t59 = self::Extension|[](#t58, self).{self::Class::+}(self) in let final void #t60 = self::Extension|[]=(#t58, self, #t59) in #t59;
+ }
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class Subclass extends self::Class {
+ synthetic constructor •() → self::Subclass*
+ : super self::Class::•()
+ ;
+ method superIndexGetSetForEffect() → void {
+ final self::Class* self = this;
+ super.{self::Class::[]}(this).{self::Class::==}(null) ?{self::Class*} super.{self::Class::[]=}(this, this) : null;
+ super.{self::Class::[]}(self).{self::Class::==}(null) ?{self::Class*} super.{self::Class::[]=}(self, self) : null;
+ super.{self::Class::[]=}(this, this);
+ super.{self::Class::[]=}(self, self);
+ super.{self::Class::[]}(this);
+ super.{self::Class::[]}(self);
+ super.{self::Class::[]=}(this, super.{self::Class::[]}(this).{self::Class::+}(this));
+ super.{self::Class::[]=}(self, super.{self::Class::[]}(self).{self::Class::+}(self));
+ }
+ method superIndexGetSetForValue() → void {
+ final self::Class* self = this;
+ dynamic v;
+ v = let final self::Class* #t61 = super.{self::Class::[]}(this) in #t61.{self::Class::==}(null) ?{self::Class*} let final void #t62 = super.{self::Class::[]=}(this, this) in this : #t61;
+ v = let final self::Class* #t63 = super.{self::Class::[]}(self) in #t63.{self::Class::==}(null) ?{self::Class*} let final void #t64 = super.{self::Class::[]=}(self, self) in self : #t63;
+ v = let final void #t65 = super.{self::Class::[]=}(this, this) in this;
+ v = let final void #t66 = super.{self::Class::[]=}(self, self) in self;
+ v = super.{self::Class::[]}(this);
+ v = super.{self::Class::[]}(self);
+ v = let final self::Class* #t67 = super.{self::Class::[]}(this).{self::Class::+}(this) in let final void #t68 = super.{self::Class::[]=}(this, #t67) in #t67;
+ v = let final self::Class* #t69 = super.{self::Class::[]}(self).{self::Class::+}(self) in let final void #t70 = super.{self::Class::[]=}(self, #t69) in #t69;
+ }
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2*
+ : super core::Object::•()
+ ;
+ operator +(self::Class2* cls) → self::Class2*
+ return cls;
+ method implicitExtensionGetSetForEffect() → void {
+ final self::Class2* self = this;
+ self::Extension2|[](this, this).{self::Class2::==}(null) ?{self::Class2*} self::Extension2|[]=(this, this, this) : null;
+ self::Extension2|[](self, self).{self::Class2::==}(null) ?{self::Class2*} self::Extension2|[]=(self, self, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ self::Extension2|[]=(self, self, self::Extension2|[](self, self).{self::Class2::+}(self));
+ }
+ method implicitExtensionGetSetForValue() → void {
+ final self::Class2* self = this;
+ dynamic v;
+ v = let final self::Class2* #t71 = self::Extension2|[](this, this) in #t71.{self::Class2::==}(null) ?{self::Class2*} let final void #t72 = self::Extension2|[]=(this, this, this) in this : #t71;
+ v = let final self::Class2* #t73 = self::Extension2|[](self, self) in #t73.{self::Class2::==}(null) ?{self::Class2*} let final void #t74 = self::Extension2|[]=(self, self, self) in self : #t73;
+ v = let final void #t75 = self::Extension2|[]=(this, this, this) in this;
+ v = let final void #t76 = self::Extension2|[]=(self, self, self) in self;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2* #t77 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t78 = self::Extension2|[]=(this, this, #t77) in #t77;
+ v = let final self::Class2* #t79 = self::Extension2|[](self, self).{self::Class2::+}(self) in let final void #t80 = self::Extension2|[]=(self, self, #t79) in #t79;
+ }
+ method explicitExtensionGetSetForEffect() → void {
+ final self::Class2* self = this;
+ self::Extension2|[](this, this).{self::Class2::==}(null) ?{self::Class2*} self::Extension2|[]=(this, this, this) : null;
+ self::Extension2|[](self, self).{self::Class2::==}(null) ?{self::Class2*} self::Extension2|[]=(self, self, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ self::Extension2|[]=(self, self, self::Extension2|[](self, self).{self::Class2::+}(self));
+ }
+ method explicitExtensionGetSetForValue() → void {
+ final self::Class2* self = this;
+ dynamic v;
+ v = let final self::Class2* #t81 = self::Extension2|[](this, this) in #t81.{self::Class2::==}(null) ?{self::Class2*} let final void #t82 = self::Extension2|[]=(this, this, this) in this : #t81;
+ v = let final self::Class2* #t83 = self::Extension2|[](self, self) in #t83.{self::Class2::==}(null) ?{self::Class2*} let final void #t84 = self::Extension2|[]=(self, self, self) in self : #t83;
+ v = let final void #t85 = self::Extension2|[]=(this, this, this) in this;
+ v = let final void #t86 = self::Extension2|[]=(self, self, self) in self;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2* #t87 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t88 = self::Extension2|[]=(this, this, #t87) in #t87;
+ v = let final self::Class2* #t89 = self::Extension2|[](self, self).{self::Class2::+}(self) in let final void #t90 = self::Extension2|[]=(self, self, #t89) in #t89;
+ }
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+extension Extension on core::int* {
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+}
+extension Extension2 on self::Class2* {
+ operator [] = self::Extension2|[];
+ operator []= = self::Extension2|[]=;
+}
+static method Extension|[](lowered final core::int* #this, self::Class* cls) → self::Class*
+ return new self::Class::•();
+static method Extension|[]=(lowered final core::int* #this, self::Class* cls, self::Class* value) → void {}
+static method Extension2|[](lowered final self::Class2* #this, self::Class2* cls) → self::Class2*
+ return new self::Class2::•();
+static method Extension2|[]=(lowered final self::Class2* #this, self::Class2* cls, self::Class2* value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/pure_index_expressions.dart.textual_outline.expect b/pkg/front_end/testcases/general/pure_index_expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..a529cd5
--- /dev/null
+++ b/pkg/front_end/testcases/general/pure_index_expressions.dart.textual_outline.expect
@@ -0,0 +1,37 @@
+// @dart = 2.9
+extension Extension on int {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+}
+
+class Class {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+ Class operator +(Class cls) => cls;
+ void indexGetSetForEffect(Map<Class, Class> map) {}
+ void indexGetSetForValue(Map<Class, Class> map) {}
+ void implicitExtensionGetSetForEffect(int i) {}
+ void implicitExtensionGetSetForValue(int i) {}
+ void explicitExtensionGetSetForEffect(int i) {}
+ void explicitExtensionGetSetForValue(int i) {}
+}
+
+class Subclass extends Class {
+ void superIndexGetSetForEffect() {}
+ void superIndexGetSetForValue() {}
+}
+
+extension Extension2 on Class2 {
+ Class2 operator [](Class2 cls) => new Class2();
+ void operator []=(Class2 cls, Class2 value) {}
+}
+
+class Class2 {
+ Class2 operator +(Class2 cls) => cls;
+ void implicitExtensionGetSetForEffect() {}
+ void implicitExtensionGetSetForValue() {}
+ void explicitExtensionGetSetForEffect() {}
+ void explicitExtensionGetSetForValue() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/pure_index_expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/pure_index_expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0fb925
--- /dev/null
+++ b/pkg/front_end/testcases/general/pure_index_expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,37 @@
+// @dart = 2.9
+class Class {
+ Class operator +(Class cls) => cls;
+ Class operator [](Class cls) => new Class();
+ void explicitExtensionGetSetForEffect(int i) {}
+ void explicitExtensionGetSetForValue(int i) {}
+ void implicitExtensionGetSetForEffect(int i) {}
+ void implicitExtensionGetSetForValue(int i) {}
+ void indexGetSetForEffect(Map<Class, Class> map) {}
+ void indexGetSetForValue(Map<Class, Class> map) {}
+ void operator []=(Class cls, Class value) {}
+}
+
+class Class2 {
+ Class2 operator +(Class2 cls) => cls;
+ void explicitExtensionGetSetForEffect() {}
+ void explicitExtensionGetSetForValue() {}
+ void implicitExtensionGetSetForEffect() {}
+ void implicitExtensionGetSetForValue() {}
+}
+
+class Subclass extends Class {
+ void superIndexGetSetForEffect() {}
+ void superIndexGetSetForValue() {}
+}
+
+extension Extension on int {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+}
+
+extension Extension2 on Class2 {
+ Class2 operator [](Class2 cls) => new Class2();
+ void operator []=(Class2 cls, Class2 value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect
index 8e696a0..35d1d71 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect
@@ -1,3 +1,24 @@
-extension Foo<U> (){}
-on List (){}
+extension Foo<U> on List {
+ static U foo1() {}
+ static List<U> foo1Prime() {}
+ static void foo2(U x) {}
+ static void foo2Prime(List<U> x) {}
+ static void foo3() {}
+ static U Function() foo8() {}
+ static List<U> Function() foo8Prime() {}
+ static void Function(U) foo9() {}
+ static void Function(List<U>) foo9Prime() {}
+ static void foo10(U Function()) {}
+ static void foo10Prime(List<U> Function()) {}
+ static void foo11(void Function(U)) {}
+ static void foo12(void Function(U) b) {}
+ static void foo12Prime(void Function(List<U>) b) {}
+ static void foo13(void Function(U b)) {}
+ static void foo13Prime(void Function(List<U> b)) {}
+ static U foo14 = null;
+ static List<U> foo14Prime = null;
+ static U Function(U) foo15 = null;
+ static List<U> Function(List<U>) foo15Prime = null;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72cd4cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+extension Foo<U> on List {
+ static List<U> Function() foo8Prime() {}
+ static List<U> Function(List<U>) foo15Prime = null;
+ static List<U> foo14Prime = null;
+ static List<U> foo1Prime() {}
+ static U Function() foo8() {}
+ static U Function(U) foo15 = null;
+ static U foo1() {}
+ static U foo14 = null;
+ static void Function(List<U>) foo9Prime() {}
+ static void Function(U) foo9() {}
+ static void foo10(U Function()) {}
+ static void foo10Prime(List<U> Function()) {}
+ static void foo11(void Function(U)) {}
+ static void foo12(void Function(U) b) {}
+ static void foo12Prime(void Function(List<U>) b) {}
+ static void foo13(void Function(U b)) {}
+ static void foo13Prime(void Function(List<U> b)) {}
+ static void foo2(U x) {}
+ static void foo2Prime(List<U> x) {}
+ static void foo3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect
index bb04737..06dc10a 100644
--- a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect
@@ -1,8 +1,15 @@
class A<X extends int> {}
+
class B {
A<num> fieldOfA;
static A<num> staticFieldOfA;
}
-extension E<X extends A<num>> (){}
-on A (){}
+
+extension E<X extends A<num>> on A {
+ static A<num> fieldOfE;
+ A<num> fooOfE() => null;
+ void barOfE(A<num> a) {}
+ void bazOfE<Y extends A<num>>() {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4fd7430
--- /dev/null
+++ b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A<X extends int> {}
+
+class B {
+ A<num> fieldOfA;
+ static A<num> staticFieldOfA;
+}
+
+extension E<X extends A<num>> on A {
+ A<num> fooOfE() => null;
+ static A<num> fieldOfE;
+ void barOfE(A<num> a) {}
+ void bazOfE<Y extends A<num>>() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_annotations.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_annotations.dart.textual_outline.expect
index e03605b..e124df6 100644
--- a/pkg/front_end/testcases/late_lowering/late_annotations.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_annotations.dart.textual_outline.expect
@@ -56,6 +56,15 @@
static late ;
final int finalStaticFieldWithInitializer = 0;
}
-extension Extension ;
-on A (){}
+extension Extension on A {
+ @Annotation()
+ static late int ;
+ extensionStaticField;
+ @Annotation()
+ static late ;
+ final int finalExtensionStaticField;
+ @Annotation()
+ static late ;
+ final int finalExtensionStaticFieldWithInitializer = 0;
+}
main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect
index 3c8b258..40fa799 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect
@@ -16,7 +16,12 @@
Class(this.field);
instanceMethod(T value) {}
}
-extension Extension<T> (){}
-on Class<T> (){}
+extension Extension<T> on Class<T> {
+ static late int ;
+ lateExtensionField1 = 87;
+ static late int ;
+ lateExtensionField2 = 42;
+ static staticMethod() {}
+}
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect
index a79477b..45d52d8 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect
@@ -12,8 +12,13 @@
T lateGenericInstanceField;
instanceMethod(T value) {}
}
-extension Extension<T> (){}
-on Class<T> (){}
+extension Extension<T> on Class<T> {
+ static late int ;
+ lateExtensionField1;
+ static late int ;
+ lateExtensionField2;
+ static staticMethod() {}
+}
main() {}
expect(expected, actual) {}
throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect
index eb122a4..08e1682 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect
@@ -34,7 +34,16 @@
Class(this.field);
instanceMethod() {}
}
-extension Extension<T> (){}
-on Class<T> (){}
+extension Extension<T> on Class<T> {
+ static int? lateExtensionField1Init;
+ static int initLateExtensionField1(int value) {}
+ static late ;
+ final int lateExtensionField1 = initLateExtensionField1(87);
+ static int? lateExtensionField2Init;
+ static int initLateExtensionField2(int value) {}
+ static late ;
+ final int lateExtensionField2 = initLateExtensionField2(42);
+ static staticMethod() {}
+}
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect
index e1be8d4..7a7f054 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect
@@ -10,8 +10,13 @@
final int lateInstanceField;
instanceMethod() {}
}
-extension Extension ;
-on Class (){}
+extension Extension on Class {
+ static late ;
+ final int lateExtensionField1;
+ static late ;
+ final int lateExtensionField2;
+ static staticMethod() {}
+}
main() {}
expect(expected, actual) {}
throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect
index 3a9e54e..14bd840 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect
@@ -24,7 +24,16 @@
Class(this.field);
instanceMethod() {}
}
-extension Extension<T> (){}
-on Class<T> (){}
+extension Extension<T> on Class<T> {
+ static int? lateExtensionField1Init;
+ static int? initLateExtensionField1(int value) {}
+ static late ;
+ final int? lateExtensionField1 = initLateExtensionField1(87);
+ static int? lateExtensionField2Init;
+ static int? initLateExtensionField2(int value) {}
+ static late ;
+ final int? lateExtensionField2 = initLateExtensionField2(42);
+ static staticMethod() {}
+}
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect
index d82d349..8837f31 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect
@@ -12,8 +12,13 @@
final T? lateGenericInstanceField;
instanceMethod(T value) {}
}
-extension Extension<T> (){}
-on Class<T> (){}
+extension Extension<T> on Class<T> {
+ static late ;
+ final int? lateExtensionField1;
+ static late ;
+ final int? lateExtensionField2;
+ static staticMethod() {}
+}
main() {}
expect(expected, actual) {}
throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect
index 7804754..83b91b4 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect
@@ -21,7 +21,16 @@
Class(this.field);
instanceMethod(T? value) {}
}
-extension Extension<T> (){}
-on Class<T> (){}
+extension Extension<T> on Class<T> {
+ static int? lateExtensionField1Init() => 87;
+ static late int;
+ operator? (){}
+ lateExtensionField1 = lateExtensionField1Init();
+ static int? lateExtensionField2Init() => 42;
+ static late int;
+ operator? (){}
+ lateExtensionField2 = lateExtensionField2Init();
+ static staticMethod() {}
+}
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect
index aab13f1..d0cb971 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect
@@ -14,8 +14,15 @@
T? lateGenericInstanceField;
instanceMethod(T? value) {}
}
-extension Extension<T> (){}
-on Class<T> (){}
+extension Extension<T> on Class<T> {
+ static late int;
+ operator? (){}
+ lateExtensionField1;
+ static late int;
+ operator? (){}
+ lateExtensionField2;
+ static staticMethod() {}
+}
main() {}
expect(expected, actual) {}
throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/nnbd/abstract_field_errors.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/abstract_field_errors.dart.textual_outline.expect
index 69a99ab..a2e1e46 100644
--- a/pkg/front_end/testcases/nnbd/abstract_field_errors.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/abstract_field_errors.dart.textual_outline.expect
@@ -26,6 +26,10 @@
external abstract final int externalFinalInstanceField;
external abstract covariant num externalCovariantInstanceField;
}
-extension Extension ;
-on A (){}
+extension Extension on A {
+ abstract int extensionInstanceField;
+ abstract final int finalExtensionInstanceField;
+ abstract static int extensionStaticField = 0;
+ abstract static final int finalExtensionStaticField = 0;
+}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/extension_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/extension_bounds.dart.textual_outline.expect
index ad8ddc8..d7c8546 100644
--- a/pkg/front_end/testcases/nnbd/extension_bounds.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/extension_bounds.dart.textual_outline.expect
@@ -1,11 +1,41 @@
-extension Extension1<T extends Object> (){}
-on T (){}
-extension Extension2<T extends String> (){}
-on T (){}
-extension Extension3<T extends dynamic> (){}
-on T (){}
-extension Extension4<T> (){}
-on T (){}
-extension Extension5<T extends Object?> (){}
-on T (){}
+extension Extension1<T extends Object> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+extension Extension2<T extends String> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+extension Extension3<T extends dynamic> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+extension Extension4<T> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+extension Extension5<T extends Object?> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/extension_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/extension_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7c8546
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/extension_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,41 @@
+extension Extension1<T extends Object> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+extension Extension2<T extends String> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+extension Extension3<T extends dynamic> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+extension Extension4<T> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+extension Extension5<T extends Object?> on T {
+ method1<S extends Object>() {}
+ method2<S extends String>() {}
+ method3<S extends dynamic>() {}
+ method4<S>() {}
+ method5<S extends Object?>() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.textual_outline.expect
index 8b38ea1..b573756 100644
--- a/pkg/front_end/testcases/nnbd/extension_never.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/extension_never.dart.textual_outline.expect
@@ -1,5 +1,7 @@
-extension Extension ;
-on Never (){}
+extension Extension on Never {
+ extensionMethod() {}
+}
+
implicitAccess(Never never) {}
explicitAccess(Never never) {}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4edd53e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/extension_never.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+explicitAccess(Never never) {}
+
+extension Extension on Never {
+ extensionMethod() {}
+}
+
+implicitAccess(Never never) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.textual_outline.expect
index 0434002..7f86fba 100644
--- a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.textual_outline.expect
@@ -1,9 +1,15 @@
-extension Extension<T> (){}
-on T (){}
-extension BoundExtension<T extends Class> (){}
-on T (){}
+extension Extension<T> on T {
+ T method1() => this;
+}
+
+extension BoundExtension<T extends Class> on T {
+ T method2() => this;
+}
+
class Class {}
+
class SubClass extends Class {}
+
Class test1<T>(T t1) {}
test2<T extends Class>(T t2) {}
test3<T>(T t3) {}
diff --git a/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d20dc15
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/extension_type_variable_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+Class test1<T>(T t1) {}
+
+class Class {}
+
+class SubClass extends Class {}
+
+extension BoundExtension<T extends Class> on T {
+ T method2() => this;
+}
+
+extension Extension<T> on T {
+ T method1() => this;
+}
+
+main() {}
+test2<T extends Class>(T t2) {}
+test3<T>(T t3) {}
diff --git a/pkg/front_end/testcases/nnbd/external_field_errors.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/external_field_errors.dart.textual_outline.expect
index cafad59..ac7f418 100644
--- a/pkg/front_end/testcases/nnbd/external_field_errors.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/external_field_errors.dart.textual_outline.expect
@@ -1,6 +1,7 @@
external int topLevelField = 0;
external final int finalTopLevelField = 0;
external const int constField = 0;
+
abstract class A {
external int fieldWithInitializer = 0;
external int initializedField1;
@@ -9,10 +10,17 @@
external static int staticField = 0;
external static final int finalStaticField = 0;
}
+
mixin B {
external static int staticField = 0;
external static final int finalStaticField = 0;
}
-extension Extension ;
-on A (){}
+
+extension Extension on A {
+ external int extensionInstanceField = 0;
+ external final int finalExtensionInstanceField = 0;
+ external static int extensionStaticField = 0;
+ external static final int finalExtensionStaticField = 0;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/external_field_errors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/external_field_errors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..322cf16
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/external_field_errors.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+abstract class A {
+ A(this.initializedField1) : this.initializedField2 = 0;
+ external int fieldWithInitializer = 0;
+ external int initializedField1;
+ external int initializedField2;
+ external static final int finalStaticField = 0;
+ external static int staticField = 0;
+}
+
+extension Extension on A {
+ external final int finalExtensionInstanceField = 0;
+ external int extensionInstanceField = 0;
+ external static final int finalExtensionStaticField = 0;
+ external static int extensionStaticField = 0;
+}
+
+external const int constField = 0;
+external final int finalTopLevelField = 0;
+external int topLevelField = 0;
+main() {}
+mixin B {
+ external static final int finalStaticField = 0;
+ external static int staticField = 0;
+}
diff --git a/pkg/front_end/testcases/nnbd/external_fields.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/external_fields.dart.textual_outline.expect
index d337a98..e1bc41f 100644
--- a/pkg/front_end/testcases/nnbd/external_fields.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/external_fields.dart.textual_outline.expect
@@ -1,12 +1,14 @@
class Annotation {
const Annotation();
}
+
@Annotation()
external int topLevelField;
@Annotation()
external final int finalTopLevelField;
external var untypedTopLevelField;
external final untypedFinalTopLevelField;
+
class A {
@Annotation()
external int instanceField;
@@ -24,6 +26,7 @@
external static var untypedStaticField;
external static final untypedFinalStaticField;
}
+
mixin B {
@Annotation()
external int instanceField;
@@ -41,8 +44,22 @@
external static var untypedStaticField;
external static final untypedFinalStaticField;
}
-extension Extension ;
-on A (){}
+
+extension Extension on A {
+ @Annotation()
+ external int extensionInstanceField;
+ @Annotation()
+ external final int finalExtensionInstanceField;
+ @Annotation()
+ external static int extensionStaticField;
+ @Annotation()
+ external static final int finalExtensionStaticField;
+ external var untypedExtensionInstanceField;
+ external final untypedFinalExtensionInstanceField;
+ external static var untypedExtensionStaticField;
+ external static final untypedFinalExtensionStaticField;
+}
+
class C implements A {
external var instanceField;
external final finalInstanceField;
@@ -51,4 +68,5 @@
external final untypedFinalInstanceField;
external var untypedCovariantInstanceField;
}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/external_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/external_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c5e3169
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/external_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,70 @@
+class A {
+ @Annotation()
+ external covariant num covariantInstanceField;
+ external covariant var untypedCovariantInstanceField;
+ @Annotation()
+ external final int finalInstanceField;
+ external final untypedFinalInstanceField;
+ @Annotation()
+ external int instanceField;
+ @Annotation()
+ external static final int finalStaticField;
+ external static final untypedFinalStaticField;
+ @Annotation()
+ external static int staticField;
+ external static var untypedStaticField;
+ external var untypedInstanceField;
+}
+
+class Annotation {
+ const Annotation();
+}
+
+class C implements A {
+ external final finalInstanceField;
+ external final untypedFinalInstanceField;
+ external var covariantInstanceField;
+ external var instanceField;
+ external var untypedCovariantInstanceField;
+ external var untypedInstanceField;
+}
+
+extension Extension on A {
+ @Annotation()
+ external final int finalExtensionInstanceField;
+ external final untypedFinalExtensionInstanceField;
+ @Annotation()
+ external int extensionInstanceField;
+ @Annotation()
+ external static final int finalExtensionStaticField;
+ external static final untypedFinalExtensionStaticField;
+ @Annotation()
+ external static int extensionStaticField;
+ external static var untypedExtensionStaticField;
+ external var untypedExtensionInstanceField;
+}
+
+@Annotation()
+external final int finalTopLevelField;
+external final untypedFinalTopLevelField;
+@Annotation()
+external int topLevelField;
+external var untypedTopLevelField;
+main() {}
+mixin B {
+ @Annotation()
+ external covariant num covariantInstanceField;
+ external covariant var untypedCovariantInstanceField;
+ @Annotation()
+ external final int finalInstanceField;
+ external final untypedFinalInstanceField;
+ @Annotation()
+ external int instanceField;
+ @Annotation()
+ external static final int finalStaticField;
+ external static final untypedFinalStaticField;
+ @Annotation()
+ external static int staticField;
+ external static var untypedStaticField;
+ external var untypedInstanceField;
+}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline.expect
index 806128e..8fae4ef 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline.expect
@@ -4,6 +4,7 @@
void set property2(num value) {}
num get property3 => 0;
void set property3(int value) {}
+
abstract class A {
int get property1;
void set property1(int i);
@@ -21,6 +22,7 @@
static num get property9 => 0;
static void set property9(int value) {}
}
+
abstract class B1 {
int get property1;
int get property2;
@@ -30,6 +32,7 @@
final num property6;
B1(this.property4, this.property5, this.property6);
}
+
abstract class B2 implements B1 {
void set property1(int i);
void set property2(num i);
@@ -38,6 +41,7 @@
void set property5(num i);
void set property6(int i);
}
+
abstract class C1 {
void set property1(int i);
void set property2(num i);
@@ -46,6 +50,7 @@
num property5 = 0;
int property6 = 0;
}
+
abstract class C2 implements C1 {
int get property1;
int get property2;
@@ -54,18 +59,42 @@
int get property5;
num get property6;
}
+
abstract class D1 {
int get property1;
int get property2;
num get property3;
}
+
abstract class D2 {
void set property1(int i);
void set property2(num i);
void set property3(int i);
}
+
abstract class D3 implements D1, D2 {}
+
abstract class D4 implements D3 {}
-extension Extension<T, S extends T> (){}
-on int (){}
+
+extension Extension<T, S extends T> on int {
+ int get property1 => 0;
+ void set property1(int i) {}
+ int get property2 => 0;
+ void set property2(num i) {}
+ num get property3 => 0;
+ void set property3(int i) {}
+ S get property4 => 0;
+ void set property4(S i) {}
+ S get property5 => 0;
+ void set property5(T i) {}
+ T get property6 => 0;
+ void set property6(S i) {}
+ static int get property7 => 0;
+ static void set property7(int value) {}
+ static int get property8 => 0;
+ static void set property8(num value) {}
+ static num get property9 => 0;
+ static void set property9(int value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline_modelled.expect
index feb0a3a..75210d1 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline_modelled.expect
@@ -69,6 +69,27 @@
abstract class D4 implements D3 {}
+extension Extension<T, S extends T> on int {
+ S get property4 => 0;
+ S get property5 => 0;
+ T get property6 => 0;
+ int get property1 => 0;
+ int get property2 => 0;
+ num get property3 => 0;
+ static int get property7 => 0;
+ static int get property8 => 0;
+ static num get property9 => 0;
+ static void set property7(int value) {}
+ static void set property8(num value) {}
+ static void set property9(int value) {}
+ void set property1(int i) {}
+ void set property2(num i) {}
+ void set property3(int i) {}
+ void set property4(S i) {}
+ void set property5(T i) {}
+ void set property6(S i) {}
+}
+
int get property1 => 0;
int get property2 => 0;
main() {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline.expect
index 1bfebe7..b5c6ecb 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline.expect
@@ -4,6 +4,7 @@
void set property2(int? value) {}
int? get property3 => 0;
void set property3(int value) {}
+
abstract class A {
int get property1;
void set property1(int i);
@@ -22,6 +23,7 @@
static int? get property9 => 0;
static void set property9(int value) {}
}
+
abstract class B1 {
int get property1;
int get property2;
@@ -31,6 +33,7 @@
final int? property6;
B1(this.property4, this.property5, this.property6);
}
+
abstract class B2 implements B1 {
void set property1(int i);
void set property2(int? i);
@@ -39,6 +42,7 @@
void set property5(int? i);
void set property6(int i);
}
+
abstract class C1 {
void set property1(int i);
void set property2(int? i);
@@ -48,6 +52,7 @@
int property6;
C1(this.property4, this.property5, this.property6);
}
+
abstract class C2 implements C1 {
int get property1;
int get property2;
@@ -56,18 +61,44 @@
int get property5;
int? get property6;
}
+
abstract class D1 {
int get property1;
int get property2;
int? get property3;
}
+
abstract class D2 {
void set property1(int i);
void set property2(int? i);
void set property3(int i);
}
+
abstract class D3 implements D1, D2 {}
+
abstract class D4 implements D3 {}
-extension Extension<T extends num> (){}
-on int (){}
+
+extension Extension<T extends num> on int {
+ int get property1 => 0;
+ void set property1(int i) {}
+ int get property2 => 0;
+ void set property2(int? i) {}
+ int? get property3 => 0;
+ void set property3(int i) {}
+ T get property4a => 0;
+ void set property4a(T i) {}
+ T? get property4b => 0;
+ void set property4b(T? i) {}
+ T get property5 => 0;
+ void set property5(T? i) {}
+ T? get property6 => 0;
+ void set property6(T i) {}
+ static int get property7 => 0;
+ static void set property7(int value) {}
+ static int get property8 => 0;
+ static void set property8(int? value) {}
+ static int? get property9 => 0;
+ static void set property9(int value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline_modelled.expect
index 30cbfa9..9aaca1d 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline_modelled.expect
@@ -71,6 +71,29 @@
abstract class D4 implements D3 {}
+extension Extension<T extends num> on int {
+ T? get property4b => 0;
+ T? get property6 => 0;
+ T get property4a => 0;
+ T get property5 => 0;
+ int? get property3 => 0;
+ int get property1 => 0;
+ int get property2 => 0;
+ static int? get property9 => 0;
+ static int get property7 => 0;
+ static int get property8 => 0;
+ static void set property7(int value) {}
+ static void set property8(int? value) {}
+ static void set property9(int value) {}
+ void set property1(int i) {}
+ void set property2(int? i) {}
+ void set property3(int i) {}
+ void set property4a(T i) {}
+ void set property4b(T? i) {}
+ void set property5(T? i) {}
+ void set property6(T i) {}
+}
+
int? get property3 => 0;
int get property1 => 0;
int get property2 => 0;
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect
index c41c8b4..6e6c210 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect
@@ -1,24 +1,34 @@
T hest1<T>() => throw "hest";
test1() {}
+
class A2 {
String? foo;
}
+
test2(A2 a) {}
test3() {}
test4() {}
+
class A5 {
void operator []=(int index, String? value) {}
String? operator [](int index) => null;
}
+
class B5 extends A5 {
test5() {}
}
-extension E6 ;
-on double (){}
+
+extension E6 on double {
+ void operator []=(int index, String? value) {}
+ String? operator [](int index) => null;
+}
+
test6() {}
+
class A7 {
String foo = "foo";
String? bar;
}
+
test7(A7? a) {}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1621b7e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,32 @@
+T hest1<T>() => throw "hest";
+
+class A2 {
+ String? foo;
+}
+
+class A5 {
+ String? operator [](int index) => null;
+ void operator []=(int index, String? value) {}
+}
+
+class A7 {
+ String? bar;
+ String foo = "foo";
+}
+
+class B5 extends A5 {
+ test5() {}
+}
+
+extension E6 on double {
+ String? operator [](int index) => null;
+ void operator []=(int index, String? value) {}
+}
+
+main() {}
+test1() {}
+test2(A2 a) {}
+test3() {}
+test4() {}
+test6() {}
+test7(A7? a) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect
index 6fca9a1..3e3ff63 100644
--- a/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect
@@ -1,15 +1,20 @@
class A {
foo() => 23;
}
-extension B ;
-on A;
-? { foo() => 42; bar() => 87; }
-extension C ;
-on A (){}
-extension D ;
-on int ;
-Function(){}
-? { int call() => 76; }
+
+extension B on A? {
+ foo() => 42;
+ bar() => 87;
+}
+
+extension C on A {
+ bar() => 123;
+}
+
+extension D on int Function()? {
+ int call() => 76;
+}
+
main() {}
testA(A? a) {}
testFunction(int Function()? f) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..545b414
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+class A {
+ foo() => 23;
+}
+
+expect(expected, actual) {}
+
+extension B on A? {
+ bar() => 87;
+ foo() => 42;
+}
+
+extension C on A {
+ bar() => 123;
+}
+
+extension D on int Function()? {
+ int call() => 76;
+}
+
+main() {}
+testA(A? a) {}
+testFunction(int Function()? f) {}
diff --git a/pkg/front_end/testcases/nnbd/issue43211.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue43211.dart.textual_outline.expect
index f38556f..f3d6cdd 100644
--- a/pkg/front_end/testcases/nnbd/issue43211.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue43211.dart.textual_outline.expect
@@ -1,17 +1,24 @@
class A<X extends A<X>?> {}
+
class D<X extends num> {}
-extension Extension1<X extends A<X>?> (){}
-on A<X> (){}
-extension ext2<X extends A<Null>?> (){}
-on A<X> (){}
+
+extension Extension1<X extends A<X>?> on A<X> {
+ void method1<Y extends A<Y>?>(A<Y> a, A<A<Null>>? b) {}
+ void method2<Y extends String>(D<Y> a, D<String>? b) {}
+}
+
+extension ext2<X extends A<Null>?> on A<X> {}
+
class B<X extends A<Null>?> implements A<X> {
void method1<Y extends A<Null>?>(A<Y> a, A<A<Null>>? b) {}
void method2<Y extends String>(D<Y> a, D<String>? b) {}
}
+
class C {
factory C.redirect(A<A<Null>>? a) = C.internal;
factory C.fact(A<A<Null>>? a) {}
C.internal(_) {}
}
+
test() {}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue43211.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue43211.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..36a6a66
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue43211.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class A<X extends A<X>?> {}
+
+class B<X extends A<Null>?> implements A<X> {
+ void method1<Y extends A<Null>?>(A<Y> a, A<A<Null>>? b) {}
+ void method2<Y extends String>(D<Y> a, D<String>? b) {}
+}
+
+class C {
+ C.internal(_) {}
+ factory C.fact(A<A<Null>>? a) {}
+ factory C.redirect(A<A<Null>>? a) = C.internal;
+}
+
+class D<X extends num> {}
+
+extension Extension1<X extends A<X>?> on A<X> {
+ void method1<Y extends A<Y>?>(A<Y> a, A<A<Null>>? b) {}
+ void method2<Y extends String>(D<Y> a, D<String>? b) {}
+}
+
+extension ext2<X extends A<Null>?> on A<X> {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.textual_outline.expect
index 989f770..c4cdc58 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.textual_outline.expect
@@ -3,9 +3,16 @@
A bar;
A(this.bar);
}
+
test<T extends A?>(A? a, T t, dynamic d, int x) {}
+
class B {}
-extension Extension ;
-on B (){}
+
+extension Extension on B {
+ int? get fooExtension => null;
+ void set fooExtension(int? value) {}
+ B get barExtension => new B();
+}
+
testExtension<T extends B?>(B? b, T t, int x) {}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue43278.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue43278.dart.textual_outline_modelled.expect
index ffcd116..b16d6f7 100644
--- a/pkg/front_end/testcases/nnbd/issue43278.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd/issue43278.dart.textual_outline_modelled.expect
@@ -1,9 +1,17 @@
-bar<T extends A?>(A? a, T t, dynamic d, int x) {}
-
class A {
A(this.bar);
A bar;
int? foo;
}
+class B {}
+
+extension Extension on B {
+ B get barExtension => new B();
+ int? get fooExtension => null;
+ void set fooExtension(int? value) {}
+}
+
main() {}
+test<T extends A?>(A? a, T t, dynamic d, int x) {}
+testExtension<T extends B?>(B? b, T t, int x) {}
diff --git a/pkg/front_end/testcases/nnbd/issue43591.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue43591.dart.textual_outline.expect
index eb34b94..2341156 100644
--- a/pkg/front_end/testcases/nnbd/issue43591.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue43591.dart.textual_outline.expect
@@ -1,5 +1,7 @@
-extension E<T> (){}
-on T (){}
+extension E<T> on T {
+ T Function(T) get f => (T t) => t;
+}
+
method1<S>(S s) {}
method2<S extends dynamic>(S s) {}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue43591.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue43591.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c47013a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue43591.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+extension E<T> on T {
+ T Function(T) get f => (T t) => t;
+}
+
+main() {}
+method1<S>(S s) {}
+method2<S extends dynamic>(S s) {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/language_issue1182.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/language_issue1182.dart.textual_outline.expect
index 2f9718a..5f989b2 100644
--- a/pkg/front_end/testcases/nnbd/language_issue1182.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/language_issue1182.dart.textual_outline.expect
@@ -1,6 +1,9 @@
-extension Test<T> (){}
-on T (){}
+extension Test<T> on T {
+ T Function(T) get test => (a) => this;
+}
+
class Foo<S extends num> {
void test1(S x) {}
}
+
void main() {}
diff --git a/pkg/front_end/testcases/nnbd/language_issue1182.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/language_issue1182.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9aaf1c7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/language_issue1182.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Foo<S extends num> {
+ void test1(S x) {}
+}
+
+extension Test<T> on T {
+ T Function(T) get test => (a) => this;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect
index d664bd6..98dd013 100644
--- a/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect
@@ -20,8 +20,9 @@
X fieldOfN;
Y fieldOfN2;
}
-extension P ;
-on Foo (){}
+extension P on Foo {
+ static int staticFieldOfE;
+}
int? nullableTopLevelField;
late
int lateTopLevelField;
@@ -65,6 +66,10 @@
late
Y fieldOfM9;
}
-extension Q ;
-on Foo (){}
+extension Q on Foo {
+ static int? staticFieldOfQ;
+ static late int ;
+ lateStaticFieldOfQ;
+ static int staticFieldOfQInitialized = 42;
+}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect
index 78062c2..abb5f99 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect
@@ -1,6 +1,9 @@
class Class {
Class method() => this;
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ Class extensionMethod() => this;
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..abb5f99
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Class {
+ Class method() => this;
+}
+
+extension Extension on Class {
+ Class extensionMethod() => this;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect
index 438dfcd..13b04f9 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect
@@ -4,19 +4,42 @@
Class1 get property1 => new Class1();
Class2 get property2 => new Class2();
}
-extension Extension1 ;
-on Class1 (){}
+
+extension Extension1 on Class1 {
+ Class1? get nullable1 => property1;
+ void set nullable1(Class1? value) {}
+ Class1 nonNullable1Method() => nonNullable1;
+ Class1? operator [](Class1? key) => nullable1;
+ void operator []=(Class1? key, Class1? value) {}
+ Class1? operator +(int value) => nullable1;
+ Class1? operator -() => nullable1;
+ Class1 get nonNullable1 => property1;
+ Class2 get nonNullable2 => property2;
+}
+
class Class2 {
Class2 get property => this;
void set property(Class2 value) {}
}
-extension Extension2 ;
-on Class2 (){}
+
+extension Extension2 on Class2 {
+ Class2 nonNullable2Method() => nonNullable2;
+ Class2 operator [](Class2? key) => property;
+ void operator []=(Class2? key, Class2? value) => property;
+ Class2 operator +(int value) => property;
+ Class2 operator -() => property;
+ Class2 get nonNullable2 => property;
+ void set nonNullable2(Class2 value) {}
+}
+
class Class3 {
Class2? get property => null;
}
-extension Extension3 ;
-on Class3 (){}
+
+extension Extension3 on Class3 {
+ Class2? operator [](Class3? key) => property;
+}
+
main() {}
void propertyAccess(Class1? n1) {}
void indexAccess(Class1? n1, Class2? n2, Class3? n3) {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..79f7c01
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline_modelled.expect
@@ -0,0 +1,48 @@
+class Class1 {
+ Class1? get property => null;
+ Class1 get property1 => new Class1();
+ Class2 get property2 => new Class2();
+ void set property(Class1? value) {}
+}
+
+class Class2 {
+ Class2 get property => this;
+ void set property(Class2 value) {}
+}
+
+class Class3 {
+ Class2? get property => null;
+}
+
+extension Extension1 on Class1 {
+ Class1? get nullable1 => property1;
+ Class1? operator +(int value) => nullable1;
+ Class1? operator -() => nullable1;
+ Class1? operator [](Class1? key) => nullable1;
+ Class1 get nonNullable1 => property1;
+ Class1 nonNullable1Method() => nonNullable1;
+ Class2 get nonNullable2 => property2;
+ void operator []=(Class1? key, Class1? value) {}
+ void set nullable1(Class1? value) {}
+}
+
+extension Extension2 on Class2 {
+ Class2 get nonNullable2 => property;
+ Class2 nonNullable2Method() => nonNullable2;
+ Class2 operator +(int value) => property;
+ Class2 operator -() => property;
+ Class2 operator [](Class2? key) => property;
+ void operator []=(Class2? key, Class2? value) => property;
+ void set nonNullable2(Class2 value) {}
+}
+
+extension Extension3 on Class3 {
+ Class2? operator [](Class3? key) => property;
+}
+
+main() {}
+void ifNull(Class1? n1) {}
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {}
+void operatorAccess(Class1? n1, Class2? n2) {}
+void propertyAccess(Class1? n1) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect
index 438dfcd..13b04f9 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect
@@ -4,19 +4,42 @@
Class1 get property1 => new Class1();
Class2 get property2 => new Class2();
}
-extension Extension1 ;
-on Class1 (){}
+
+extension Extension1 on Class1 {
+ Class1? get nullable1 => property1;
+ void set nullable1(Class1? value) {}
+ Class1 nonNullable1Method() => nonNullable1;
+ Class1? operator [](Class1? key) => nullable1;
+ void operator []=(Class1? key, Class1? value) {}
+ Class1? operator +(int value) => nullable1;
+ Class1? operator -() => nullable1;
+ Class1 get nonNullable1 => property1;
+ Class2 get nonNullable2 => property2;
+}
+
class Class2 {
Class2 get property => this;
void set property(Class2 value) {}
}
-extension Extension2 ;
-on Class2 (){}
+
+extension Extension2 on Class2 {
+ Class2 nonNullable2Method() => nonNullable2;
+ Class2 operator [](Class2? key) => property;
+ void operator []=(Class2? key, Class2? value) => property;
+ Class2 operator +(int value) => property;
+ Class2 operator -() => property;
+ Class2 get nonNullable2 => property;
+ void set nonNullable2(Class2 value) {}
+}
+
class Class3 {
Class2? get property => null;
}
-extension Extension3 ;
-on Class3 (){}
+
+extension Extension3 on Class3 {
+ Class2? operator [](Class3? key) => property;
+}
+
main() {}
void propertyAccess(Class1? n1) {}
void indexAccess(Class1? n1, Class2? n2, Class3? n3) {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..79f7c01
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline_modelled.expect
@@ -0,0 +1,48 @@
+class Class1 {
+ Class1? get property => null;
+ Class1 get property1 => new Class1();
+ Class2 get property2 => new Class2();
+ void set property(Class1? value) {}
+}
+
+class Class2 {
+ Class2 get property => this;
+ void set property(Class2 value) {}
+}
+
+class Class3 {
+ Class2? get property => null;
+}
+
+extension Extension1 on Class1 {
+ Class1? get nullable1 => property1;
+ Class1? operator +(int value) => nullable1;
+ Class1? operator -() => nullable1;
+ Class1? operator [](Class1? key) => nullable1;
+ Class1 get nonNullable1 => property1;
+ Class1 nonNullable1Method() => nonNullable1;
+ Class2 get nonNullable2 => property2;
+ void operator []=(Class1? key, Class1? value) {}
+ void set nullable1(Class1? value) {}
+}
+
+extension Extension2 on Class2 {
+ Class2 get nonNullable2 => property;
+ Class2 nonNullable2Method() => nonNullable2;
+ Class2 operator +(int value) => property;
+ Class2 operator -() => property;
+ Class2 operator [](Class2? key) => property;
+ void operator []=(Class2? key, Class2? value) => property;
+ void set nonNullable2(Class2 value) {}
+}
+
+extension Extension3 on Class3 {
+ Class2? operator [](Class3? key) => property;
+}
+
+main() {}
+void ifNull(Class1? n1) {}
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {}
+void operatorAccess(Class1? n1, Class2? n2) {}
+void propertyAccess(Class1? n1) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect
index e3e40af..2be2b70 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect
@@ -3,9 +3,14 @@
int operator [](int index) => index;
void operator []=(int index, int value) {}
}
+
class Class2 {
int field = 42;
}
-extension Extension ;
-on Class2 (){}
+
+extension Extension on Class2 {
+ int operator [](int index) => field;
+ void operator []=(int index, int value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2be2b70
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class Class1 {
+ Class2? get field => null;
+ int operator [](int index) => index;
+ void operator []=(int index, int value) {}
+}
+
+class Class2 {
+ int field = 42;
+}
+
+extension Extension on Class2 {
+ int operator [](int index) => field;
+ void operator []=(int index, int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.textual_outline.expect
index 8bd081e..3eef1e7 100644
--- a/pkg/front_end/testcases/nnbd/nullable_extension.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.textual_outline.expect
@@ -1,8 +1,10 @@
class A {
String text = "";
}
-extension on ;
-A;
-? { String get text => "Lily was here"; }
+
+extension on A? {
+ String get text => "Lily was here";
+}
+
void main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_extension.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_extension.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ff2587a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_extension.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A {
+ String text = "";
+}
+
+expect(expected, actual) {}
+
+extension on A? {
+ String get text => "Lily was here";
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.textual_outline.expect
index f75f2e0..ff978cb 100644
--- a/pkg/front_end/testcases/nnbd/nullable_setter.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.textual_outline.expect
@@ -3,8 +3,11 @@
void set setter(String v) {}
void operator []=(int index, String value) {}
}
-extension on ;
-C;
-? { void set setter(String v) { this?.m = v; } void operator []=(int index, String value) { this?.m = '$index$value'; } }
+
+extension on C? {
+ void set setter(String v) {}
+ void operator []=(int index, String value) {}
+}
+
main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7a84dd6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class C {
+ String m = "";
+ void operator []=(int index, String value) {}
+ void set setter(String v) {}
+}
+
+expect(expected, actual) {}
+
+extension on C? {
+ void operator []=(int index, String value) {}
+ void set setter(String v) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect
index cbd0809..6f73b5c 100644
--- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect
@@ -6,8 +6,20 @@
Function get functionGetter => () {};
void Function() get functionTypeGetter => () {};
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ int operator +(int value) => 0;
+ int operator -() => 0;
+ int operator [](int index) => 0;
+ void operator []=(int index, int value) {}
+ int call() => 0;
+ int get extensionProperty => 0;
+ void set extensionProperty(int value) {}
+ int extensionMethod() => 0;
+ Function get extensionFunctionGetter => () {};
+ void Function() get extensionFunctionTypeGetter => () {};
+}
+
Function? get nullableFunction => () {};
void Function()? get nullableFunctionType => () {};
int? get nullableInt => 0;
@@ -47,6 +59,7 @@
var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
-var topLevelExtensionFunctionTypeGetter = nullableClass.extensionFunctionTypeGetter();
+var topLevelExtensionFunctionTypeGetter =
+ nullableClass.extensionFunctionTypeGetter();
test() {}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe7c996
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,66 @@
+Class? get nullableClass => new Class();
+Function? get nullableFunction => () {};
+Map<dynamic, dynamic>? get nullableMap => {};
+
+class Class {
+ Function functionField = () {};
+ Function get functionGetter => () {};
+ int method() => 0;
+ int property = 0;
+ void Function() functionTypeField = () {};
+ void Function() get functionTypeGetter => () {};
+}
+
+extension Extension on Class {
+ Function get extensionFunctionGetter => () {};
+ int call() => 0;
+ int extensionMethod() => 0;
+ int get extensionProperty => 0;
+ int operator +(int value) => 0;
+ int operator -() => 0;
+ int operator [](int index) => 0;
+ void Function() get extensionFunctionTypeGetter => () {};
+ void operator []=(int index, int value) {}
+ void set extensionProperty(int value) {}
+}
+
+int? get nullableInt => 0;
+main() {}
+test() {}
+var topLevelBinary = nullableInt + 0;
+var topLevelExtensionBinary = nullableClass + 0;
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+var topLevelExtensionFunctionTypeGetter =
+ nullableClass.extensionFunctionTypeGetter();
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+var topLevelExtensionIndexGet = nullableClass[0];
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+var topLevelExtensionUnary = -nullableClass;
+var topLevelFunctionExplicitCall = nullableFunction.call();
+var topLevelFunctionField = nullableClass.functionField();
+var topLevelFunctionGetter = nullableClass.functionGetter();
+var topLevelFunctionImplicitCall = nullableFunction();
+var topLevelFunctionTearOff = nullableFunction.call;
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+var topLevelIndexGet = nullableMap[0];
+var topLevelIndexGetSet = nullableMap[0] += 1;
+var topLevelIndexSet = nullableMap[0] = 1;
+var topLevelMethodInvocation = nullableClass.method();
+var topLevelMethodTearOff = nullableClass.method;
+var topLevelPropertyGet = nullableClass.property;
+var topLevelPropertyGetSet = nullableClass.property += 1;
+var topLevelPropertySet = nullableClass.property = 1;
+var topLevelUnary = -nullableInt;
+void Function()? get nullableFunctionType => () {};
diff --git a/pkg/front_end/testcases/nnbd/pure_index_expressions.dart b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart
new file mode 100644
index 0000000..9b143d6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+bool b = true;
+
+abstract class Map<K, V> {
+ V operator [](K index);
+ void operator []=(K index, V value);
+}
+
+extension Extension on int {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+}
+
+class Class {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+ Class operator +(Class cls) => cls;
+
+ void indexGetSetForEffect(Map<Class, Class> map) {
+ late final Class self;
+ if (b) self = this;
+ map[this] ??= this;
+ map[self] ??= self;
+
+ map[this] = this;
+ map[self] = self;
+
+ map[this];
+ map[self];
+
+ map[this] += this;
+ map[self] += self;
+ }
+
+ void indexGetSetForValue(Map<Class, Class> map) {
+ late final Class self;
+ if (b) self = this;
+ var v;
+ v = map[this] ??= this;
+ v = map[self] ??= self;
+
+ v = map[this] = this;
+ v = map[self] = self;
+
+ v = map[this];
+ v = map[self];
+
+ v = map[this] += this;
+ v = map[self] += self;
+ }
+
+ void implicitExtensionGetSetForEffect(int i) {
+ late final Class self;
+ if (b) self = this;
+ i[this] ??= this;
+ i[self] ??= self;
+
+ i[this] = this;
+ i[self] = self;
+
+ i[this];
+ i[self];
+
+ i[this] += this;
+ i[self] += self;
+ }
+
+ void implicitExtensionGetSetForValue(int i) {
+ late final Class self;
+ if (b) self = this;
+ var v;
+ v = i[this] ??= this;
+ v = i[self] ??= self;
+
+ v = i[this] = this;
+ v = i[self] = self;
+
+ v = i[this];
+ v = i[self];
+
+ v = i[this] += this;
+ v = i[self] += self;
+ }
+
+ void explicitExtensionGetSetForEffect(int i) {
+ late final Class self;
+ if (b) self = this;
+ Extension(i)[this] ??= this;
+ Extension(i)[self] ??= self;
+
+ Extension(i)[this] = this;
+ Extension(i)[self] = self;
+
+ Extension(i)[this];
+ Extension(i)[self];
+
+ Extension(i)[this] += this;
+ Extension(i)[self] += self;
+ }
+
+ void explicitExtensionGetSetForValue(int i) {
+ late final Class self;
+ if (b) self = this;
+ var v;
+ v = Extension(i)[this] ??= this;
+ v = Extension(i)[self] ??= self;
+
+ v = Extension(i)[this] = this;
+ v = Extension(i)[self] = self;
+
+ v = Extension(i)[this];
+ v = Extension(i)[self];
+
+ v = Extension(i)[this] += this;
+ v = Extension(i)[self] += self;
+ }
+}
+
+class Subclass extends Class {
+ void superIndexGetSetForEffect() {
+ late final Class self;
+ if (b) self = this;
+ super[this] ??= this;
+ super[self] ??= self;
+
+ super[this] = this;
+ super[self] = self;
+
+ super[this];
+ super[self];
+
+ super[this] += this;
+ super[self] += self;
+ }
+
+ void superIndexGetSetForValue() {
+ late final Class self;
+ if (b) self = this;
+ var v;
+ v = super[this] ??= this;
+ v = super[self] ??= self;
+
+ v = super[this] = this;
+ v = super[self] = self;
+
+ v = super[this];
+ v = super[self];
+
+ v = super[this] += this;
+ v = super[self] += self;
+ }
+}
+
+extension Extension2 on Class2 {
+ Class2 operator [](Class2 cls) => new Class2();
+ void operator []=(Class2 cls, Class2 value) {}
+}
+
+class Class2 {
+ Class2 operator +(Class2 cls) => cls;
+
+ void implicitExtensionGetSetForEffect() {
+ late final Class2 self;
+ if (b) self = this;
+ this[this] ??= this;
+ self[self] ??= self;
+
+ this[this] = this;
+ self[self] = self;
+
+ this[this];
+ self[self];
+
+ this[this] += this;
+ self[self] += self;
+ }
+
+ void implicitExtensionGetSetForValue() {
+ late final Class2 self;
+ if (b) self = this;
+ var v;
+ v = this[this] ??= this;
+ v = self[self] ??= self;
+
+ v = this[this] = this;
+ v = self[self] = self;
+
+ v = this[this];
+ v = self[self];
+
+ v = this[this] += this;
+ v = self[self] += self;
+ }
+
+ void explicitExtensionGetSetForEffect() {
+ late final Class2 self;
+ if (b) self = this;
+ Extension2(this)[this] ??= this;
+ Extension2(self)[self] ??= self;
+
+ Extension2(this)[this] = this;
+ Extension2(self)[self] = self;
+
+ Extension2(this)[this];
+ Extension2(self)[self];
+
+ Extension2(this)[this] += this;
+ Extension2(self)[self] += self;
+ }
+
+ void explicitExtensionGetSetForValue() {
+ late final Class2 self;
+ if (b) self = this;
+ var v;
+ v = Extension2(this)[this] ??= this;
+ v = Extension2(self)[self] ??= self;
+
+ v = Extension2(this)[this] = this;
+ v = Extension2(self)[self] = self;
+
+ v = Extension2(this)[this];
+ v = Extension2(self)[self];
+
+ v = Extension2(this)[this] += this;
+ v = Extension2(self)[self] += self;
+ }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.outline.expect b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.outline.expect
new file mode 100644
index 0000000..f44d475
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.outline.expect
@@ -0,0 +1,73 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class Map<K extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::Map<self::Map::K%, self::Map::V%>
+ ;
+ abstract operator [](generic-covariant-impl self::Map::K% index) → self::Map::V%;
+ abstract operator []=(generic-covariant-impl self::Map::K% index, generic-covariant-impl self::Map::V% value) → void;
+}
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ ;
+ operator [](self::Class cls) → self::Class
+ ;
+ operator []=(self::Class cls, self::Class value) → void
+ ;
+ operator +(self::Class cls) → self::Class
+ ;
+ method indexGetSetForEffect(self::Map<self::Class, self::Class> map) → void
+ ;
+ method indexGetSetForValue(self::Map<self::Class, self::Class> map) → void
+ ;
+ method implicitExtensionGetSetForEffect(core::int i) → void
+ ;
+ method implicitExtensionGetSetForValue(core::int i) → void
+ ;
+ method explicitExtensionGetSetForEffect(core::int i) → void
+ ;
+ method explicitExtensionGetSetForValue(core::int i) → void
+ ;
+}
+class Subclass extends self::Class {
+ synthetic constructor •() → self::Subclass
+ ;
+ method superIndexGetSetForEffect() → void
+ ;
+ method superIndexGetSetForValue() → void
+ ;
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2
+ ;
+ operator +(self::Class2 cls) → self::Class2
+ ;
+ method implicitExtensionGetSetForEffect() → void
+ ;
+ method implicitExtensionGetSetForValue() → void
+ ;
+ method explicitExtensionGetSetForEffect() → void
+ ;
+ method explicitExtensionGetSetForValue() → void
+ ;
+}
+extension Extension on core::int {
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+}
+extension Extension2 on self::Class2 {
+ operator [] = self::Extension2|[];
+ operator []= = self::Extension2|[]=;
+}
+static field core::bool b;
+static method Extension|[](lowered final core::int #this, self::Class cls) → self::Class
+ ;
+static method Extension|[]=(lowered final core::int #this, self::Class cls, self::Class value) → void
+ ;
+static method Extension2|[](lowered final self::Class2 #this, self::Class2 cls) → self::Class2
+ ;
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2 cls, self::Class2 value) → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.strong.expect b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.strong.expect
new file mode 100644
index 0000000..84d1907
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.strong.expect
@@ -0,0 +1,334 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:25:8: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// map[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:26:8: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// map[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:42:12: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = map[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:43:12: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = map[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:58:6: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// i[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:59:6: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// i[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:75:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = i[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:76:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = i[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:91:17: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension(i)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:92:17: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension(i)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:108:21: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension(i)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:109:21: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension(i)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:126:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// super[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:127:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// super[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:143:14: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = super[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:144:14: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = super[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:168:9: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// this[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:169:9: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// self[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:185:13: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = this[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:186:13: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = self[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:201:21: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension2(this)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:202:21: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension2(self)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:218:25: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension2(this)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:219:25: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension2(self)[self] ??= self;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Map<K extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::Map<self::Map::K%, self::Map::V%>
+ : super core::Object::•()
+ ;
+ abstract operator [](generic-covariant-impl self::Map::K% index) → self::Map::V%;
+ abstract operator []=(generic-covariant-impl self::Map::K% index, generic-covariant-impl self::Map::V% value) → void;
+}
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ operator [](self::Class cls) → self::Class
+ return new self::Class::•();
+ operator []=(self::Class cls, self::Class value) → void {}
+ operator +(self::Class cls) → self::Class
+ return cls;
+ method indexGetSetForEffect(self::Map<self::Class, self::Class> map) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final self::Map<self::Class, self::Class> #t1 = map in #t1.{self::Map::[]}(this).{core::Object::==}(null) ?{self::Class} #t1.{self::Map::[]=}(this, this) : null;
+ let final self::Map<self::Class, self::Class> #t2 = map in let final self::Class #t3 = self in #t2.{self::Map::[]}(#t3).{core::Object::==}(null) ?{self::Class} #t2.{self::Map::[]=}(#t3, self) : null;
+ map.{self::Map::[]=}(this, this);
+ map.{self::Map::[]=}(self, self);
+ map.{self::Map::[]}(this);
+ map.{self::Map::[]}(self);
+ let final self::Map<self::Class, self::Class> #t4 = map in #t4.{self::Map::[]=}(this, #t4.{self::Map::[]}(this).{self::Class::+}(this));
+ let final self::Map<self::Class, self::Class> #t5 = map in let final self::Class #t6 = self in #t5.{self::Map::[]=}(#t6, #t5.{self::Map::[]}(#t6).{self::Class::+}(self));
+ }
+ method indexGetSetForValue(self::Map<self::Class, self::Class> map) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Map<self::Class, self::Class> #t7 = map in let final self::Class #t8 = #t7.{self::Map::[]}(this) in #t8.{core::Object::==}(null) ?{self::Class} let final void #t9 = #t7.{self::Map::[]=}(this, this) in this : #t8;
+ v = let final self::Map<self::Class, self::Class> #t10 = map in let final self::Class #t11 = self in let final self::Class #t12 = #t10.{self::Map::[]}(#t11) in #t12.{core::Object::==}(null) ?{self::Class} let final self::Class #t13 = self in let final void #t14 = #t10.{self::Map::[]=}(#t11, #t13) in #t13 : #t12;
+ v = let final self::Map<self::Class, self::Class> #t15 = map in let final void #t16 = #t15.{self::Map::[]=}(this, this) in this;
+ v = let final self::Map<self::Class, self::Class> #t17 = map in let final self::Class #t18 = self in let final self::Class #t19 = self in let final void #t20 = #t17.{self::Map::[]=}(#t18, #t19) in #t19;
+ v = map.{self::Map::[]}(this);
+ v = map.{self::Map::[]}(self);
+ v = let final self::Map<self::Class, self::Class> #t21 = map in let final self::Class #t22 = #t21.{self::Map::[]}(this).{self::Class::+}(this) in let final void #t23 = #t21.{self::Map::[]=}(this, #t22) in #t22;
+ v = let final self::Map<self::Class, self::Class> #t24 = map in let final self::Class #t25 = self in let final self::Class #t26 = #t24.{self::Map::[]}(#t25).{self::Class::+}(self) in let final void #t27 = #t24.{self::Map::[]=}(#t25, #t26) in #t26;
+ }
+ method implicitExtensionGetSetForEffect(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final core::int #t28 = i in self::Extension|[](#t28, this).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t28, this, this) : null;
+ let final core::int #t29 = i in let final self::Class #t30 = self in self::Extension|[](#t29, #t30).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t29, #t30, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int #t31 = i in self::Extension|[]=(#t31, this, self::Extension|[](#t31, this).{self::Class::+}(this));
+ let final core::int #t32 = i in let final self::Class #t33 = self in self::Extension|[]=(#t32, #t33, self::Extension|[](#t32, #t33).{self::Class::+}(self));
+ }
+ method implicitExtensionGetSetForValue(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final core::int #t34 = i in let final self::Class #t35 = self::Extension|[](#t34, this) in #t35.{core::Object::==}(null) ?{self::Class} let final void #t36 = self::Extension|[]=(#t34, this, this) in this : #t35;
+ v = let final core::int #t37 = i in let final self::Class #t38 = self in let final self::Class #t39 = self::Extension|[](#t37, #t38) in #t39.{core::Object::==}(null) ?{self::Class} let final self::Class #t40 = self in let final void #t41 = self::Extension|[]=(#t37, #t38, #t40) in #t40 : #t39;
+ v = let final core::int #t42 = i in let final void #t43 = self::Extension|[]=(#t42, this, this) in this;
+ v = let final core::int #t44 = i in let final self::Class #t45 = self in let final self::Class #t46 = self in let final void #t47 = self::Extension|[]=(#t44, #t45, #t46) in #t46;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int #t48 = i in let final self::Class #t49 = self::Extension|[](#t48, this).{self::Class::+}(this) in let final void #t50 = self::Extension|[]=(#t48, this, #t49) in #t49;
+ v = let final core::int #t51 = i in let final self::Class #t52 = self in let final self::Class #t53 = self::Extension|[](#t51, #t52).{self::Class::+}(self) in let final void #t54 = self::Extension|[]=(#t51, #t52, #t53) in #t53;
+ }
+ method explicitExtensionGetSetForEffect(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final core::int #t55 = i in self::Extension|[](#t55, this).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t55, this, this) : null;
+ let final core::int #t56 = i in let final self::Class #t57 = self in self::Extension|[](#t56, #t57).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t56, #t57, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int #t58 = i in self::Extension|[]=(#t58, this, self::Extension|[](#t58, this).{self::Class::+}(this));
+ let final core::int #t59 = i in let final self::Class #t60 = self in self::Extension|[]=(#t59, #t60, self::Extension|[](#t59, #t60).{self::Class::+}(self));
+ }
+ method explicitExtensionGetSetForValue(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final core::int #t61 = i in let final self::Class #t62 = self::Extension|[](#t61, this) in #t62.{core::Object::==}(null) ?{self::Class} let final void #t63 = self::Extension|[]=(#t61, this, this) in this : #t62;
+ v = let final core::int #t64 = i in let final self::Class #t65 = self in let final self::Class #t66 = self::Extension|[](#t64, #t65) in #t66.{core::Object::==}(null) ?{self::Class} let final self::Class #t67 = self in let final void #t68 = self::Extension|[]=(#t64, #t65, #t67) in #t67 : #t66;
+ v = let final core::int #t69 = i in let final void #t70 = self::Extension|[]=(#t69, this, this) in this;
+ v = let final core::int #t71 = i in let final self::Class #t72 = self in let final void #t73 = self::Extension|[]=(#t71, self, #t72) in #t72;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int #t74 = i in let final self::Class #t75 = self::Extension|[](#t74, this).{self::Class::+}(this) in let final void #t76 = self::Extension|[]=(#t74, this, #t75) in #t75;
+ v = let final core::int #t77 = i in let final self::Class #t78 = self in let final self::Class #t79 = self::Extension|[](#t77, #t78).{self::Class::+}(self) in let final void #t80 = self::Extension|[]=(#t77, #t78, #t79) in #t79;
+ }
+}
+class Subclass extends self::Class {
+ synthetic constructor •() → self::Subclass
+ : super self::Class::•()
+ ;
+ method superIndexGetSetForEffect() → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ super.{self::Class::[]}(this).{core::Object::==}(null) ?{self::Class} super.{self::Class::[]=}(this, this) : null;
+ let final self::Class #t81 = self in super.{self::Class::[]}(#t81).{core::Object::==}(null) ?{self::Class} super.{self::Class::[]=}(#t81, self) : null;
+ super.{self::Class::[]=}(this, this);
+ super.{self::Class::[]=}(self, self);
+ super.{self::Class::[]}(this);
+ super.{self::Class::[]}(self);
+ super.{self::Class::[]=}(this, super.{self::Class::[]}(this).{self::Class::+}(this));
+ let final self::Class #t82 = self in super.{self::Class::[]=}(#t82, super.{self::Class::[]}(#t82).{self::Class::+}(self));
+ }
+ method superIndexGetSetForValue() → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class #t83 = super.{self::Class::[]}(this) in #t83.{core::Object::==}(null) ?{self::Class} let final void #t84 = super.{self::Class::[]=}(this, this) in this : #t83;
+ v = let final self::Class #t85 = self in let final self::Class #t86 = super.{self::Class::[]}(#t85) in #t86.{core::Object::==}(null) ?{self::Class} let final self::Class #t87 = self in let final void #t88 = super.{self::Class::[]=}(#t85, #t87) in #t87 : #t86;
+ v = let final void #t89 = super.{self::Class::[]=}(this, this) in this;
+ v = let final self::Class #t90 = self in let final self::Class #t91 = self in let final void #t92 = super.{self::Class::[]=}(#t90, #t91) in #t91;
+ v = super.{self::Class::[]}(this);
+ v = super.{self::Class::[]}(self);
+ v = let final self::Class #t93 = super.{self::Class::[]}(this).{self::Class::+}(this) in let final void #t94 = super.{self::Class::[]=}(this, #t93) in #t93;
+ v = let final self::Class #t95 = self in let final self::Class #t96 = super.{self::Class::[]}(#t95).{self::Class::+}(self) in let final void #t97 = super.{self::Class::[]=}(#t95, #t96) in #t96;
+ }
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2
+ : super core::Object::•()
+ ;
+ operator +(self::Class2 cls) → self::Class2
+ return cls;
+ method implicitExtensionGetSetForEffect() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ self::Extension2|[](this, this).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(this, this, this) : null;
+ let final self::Class2 #t98 = self in let final self::Class2 #t99 = self in self::Extension2|[](#t98, #t99).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(#t98, #t99, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ let final self::Class2 #t100 = self in let final self::Class2 #t101 = self in self::Extension2|[]=(#t100, #t101, self::Extension2|[](#t100, #t101).{self::Class2::+}(self));
+ }
+ method implicitExtensionGetSetForValue() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class2 #t102 = self::Extension2|[](this, this) in #t102.{core::Object::==}(null) ?{self::Class2} let final void #t103 = self::Extension2|[]=(this, this, this) in this : #t102;
+ v = let final self::Class2 #t104 = self in let final self::Class2 #t105 = self in let final self::Class2 #t106 = self::Extension2|[](#t104, #t105) in #t106.{core::Object::==}(null) ?{self::Class2} let final self::Class2 #t107 = self in let final void #t108 = self::Extension2|[]=(#t104, #t105, #t107) in #t107 : #t106;
+ v = let final void #t109 = self::Extension2|[]=(this, this, this) in this;
+ v = let final self::Class2 #t110 = self in let final self::Class2 #t111 = self in let final self::Class2 #t112 = self in let final void #t113 = self::Extension2|[]=(#t110, #t111, #t112) in #t112;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2 #t114 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t115 = self::Extension2|[]=(this, this, #t114) in #t114;
+ v = let final self::Class2 #t116 = self in let final self::Class2 #t117 = self in let final self::Class2 #t118 = self::Extension2|[](#t116, #t117).{self::Class2::+}(self) in let final void #t119 = self::Extension2|[]=(#t116, #t117, #t118) in #t118;
+ }
+ method explicitExtensionGetSetForEffect() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ self::Extension2|[](this, this).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(this, this, this) : null;
+ let final self::Class2 #t120 = self in let final self::Class2 #t121 = self in self::Extension2|[](#t120, #t121).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(#t120, #t121, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ let final self::Class2 #t122 = self in let final self::Class2 #t123 = self in self::Extension2|[]=(#t122, #t123, self::Extension2|[](#t122, #t123).{self::Class2::+}(self));
+ }
+ method explicitExtensionGetSetForValue() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class2 #t124 = self::Extension2|[](this, this) in #t124.{core::Object::==}(null) ?{self::Class2} let final void #t125 = self::Extension2|[]=(this, this, this) in this : #t124;
+ v = let final self::Class2 #t126 = self in let final self::Class2 #t127 = self in let final self::Class2 #t128 = self::Extension2|[](#t126, #t127) in #t128.{core::Object::==}(null) ?{self::Class2} let final self::Class2 #t129 = self in let final void #t130 = self::Extension2|[]=(#t126, #t127, #t129) in #t129 : #t128;
+ v = let final void #t131 = self::Extension2|[]=(this, this, this) in this;
+ v = let final self::Class2 #t132 = self in let final self::Class2 #t133 = self in let final void #t134 = self::Extension2|[]=(#t132, self, #t133) in #t133;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2 #t135 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t136 = self::Extension2|[]=(this, this, #t135) in #t135;
+ v = let final self::Class2 #t137 = self in let final self::Class2 #t138 = self in let final self::Class2 #t139 = self::Extension2|[](#t137, #t138).{self::Class2::+}(self) in let final void #t140 = self::Extension2|[]=(#t137, #t138, #t139) in #t139;
+ }
+}
+extension Extension on core::int {
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+}
+extension Extension2 on self::Class2 {
+ operator [] = self::Extension2|[];
+ operator []= = self::Extension2|[]=;
+}
+static field core::bool b = true;
+static method Extension|[](lowered final core::int #this, self::Class cls) → self::Class
+ return new self::Class::•();
+static method Extension|[]=(lowered final core::int #this, self::Class cls, self::Class value) → void {}
+static method Extension2|[](lowered final self::Class2 #this, self::Class2 cls) → self::Class2
+ return new self::Class2::•();
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2 cls, self::Class2 value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.strong.transformed.expect
new file mode 100644
index 0000000..84d1907
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.strong.transformed.expect
@@ -0,0 +1,334 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:25:8: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// map[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:26:8: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// map[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:42:12: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = map[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:43:12: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = map[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:58:6: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// i[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:59:6: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// i[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:75:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = i[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:76:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = i[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:91:17: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension(i)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:92:17: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension(i)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:108:21: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension(i)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:109:21: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension(i)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:126:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// super[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:127:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// super[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:143:14: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = super[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:144:14: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = super[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:168:9: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// this[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:169:9: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// self[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:185:13: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = this[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:186:13: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = self[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:201:21: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension2(this)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:202:21: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension2(self)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:218:25: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension2(this)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:219:25: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension2(self)[self] ??= self;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Map<K extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::Map<self::Map::K%, self::Map::V%>
+ : super core::Object::•()
+ ;
+ abstract operator [](generic-covariant-impl self::Map::K% index) → self::Map::V%;
+ abstract operator []=(generic-covariant-impl self::Map::K% index, generic-covariant-impl self::Map::V% value) → void;
+}
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ operator [](self::Class cls) → self::Class
+ return new self::Class::•();
+ operator []=(self::Class cls, self::Class value) → void {}
+ operator +(self::Class cls) → self::Class
+ return cls;
+ method indexGetSetForEffect(self::Map<self::Class, self::Class> map) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final self::Map<self::Class, self::Class> #t1 = map in #t1.{self::Map::[]}(this).{core::Object::==}(null) ?{self::Class} #t1.{self::Map::[]=}(this, this) : null;
+ let final self::Map<self::Class, self::Class> #t2 = map in let final self::Class #t3 = self in #t2.{self::Map::[]}(#t3).{core::Object::==}(null) ?{self::Class} #t2.{self::Map::[]=}(#t3, self) : null;
+ map.{self::Map::[]=}(this, this);
+ map.{self::Map::[]=}(self, self);
+ map.{self::Map::[]}(this);
+ map.{self::Map::[]}(self);
+ let final self::Map<self::Class, self::Class> #t4 = map in #t4.{self::Map::[]=}(this, #t4.{self::Map::[]}(this).{self::Class::+}(this));
+ let final self::Map<self::Class, self::Class> #t5 = map in let final self::Class #t6 = self in #t5.{self::Map::[]=}(#t6, #t5.{self::Map::[]}(#t6).{self::Class::+}(self));
+ }
+ method indexGetSetForValue(self::Map<self::Class, self::Class> map) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Map<self::Class, self::Class> #t7 = map in let final self::Class #t8 = #t7.{self::Map::[]}(this) in #t8.{core::Object::==}(null) ?{self::Class} let final void #t9 = #t7.{self::Map::[]=}(this, this) in this : #t8;
+ v = let final self::Map<self::Class, self::Class> #t10 = map in let final self::Class #t11 = self in let final self::Class #t12 = #t10.{self::Map::[]}(#t11) in #t12.{core::Object::==}(null) ?{self::Class} let final self::Class #t13 = self in let final void #t14 = #t10.{self::Map::[]=}(#t11, #t13) in #t13 : #t12;
+ v = let final self::Map<self::Class, self::Class> #t15 = map in let final void #t16 = #t15.{self::Map::[]=}(this, this) in this;
+ v = let final self::Map<self::Class, self::Class> #t17 = map in let final self::Class #t18 = self in let final self::Class #t19 = self in let final void #t20 = #t17.{self::Map::[]=}(#t18, #t19) in #t19;
+ v = map.{self::Map::[]}(this);
+ v = map.{self::Map::[]}(self);
+ v = let final self::Map<self::Class, self::Class> #t21 = map in let final self::Class #t22 = #t21.{self::Map::[]}(this).{self::Class::+}(this) in let final void #t23 = #t21.{self::Map::[]=}(this, #t22) in #t22;
+ v = let final self::Map<self::Class, self::Class> #t24 = map in let final self::Class #t25 = self in let final self::Class #t26 = #t24.{self::Map::[]}(#t25).{self::Class::+}(self) in let final void #t27 = #t24.{self::Map::[]=}(#t25, #t26) in #t26;
+ }
+ method implicitExtensionGetSetForEffect(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final core::int #t28 = i in self::Extension|[](#t28, this).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t28, this, this) : null;
+ let final core::int #t29 = i in let final self::Class #t30 = self in self::Extension|[](#t29, #t30).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t29, #t30, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int #t31 = i in self::Extension|[]=(#t31, this, self::Extension|[](#t31, this).{self::Class::+}(this));
+ let final core::int #t32 = i in let final self::Class #t33 = self in self::Extension|[]=(#t32, #t33, self::Extension|[](#t32, #t33).{self::Class::+}(self));
+ }
+ method implicitExtensionGetSetForValue(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final core::int #t34 = i in let final self::Class #t35 = self::Extension|[](#t34, this) in #t35.{core::Object::==}(null) ?{self::Class} let final void #t36 = self::Extension|[]=(#t34, this, this) in this : #t35;
+ v = let final core::int #t37 = i in let final self::Class #t38 = self in let final self::Class #t39 = self::Extension|[](#t37, #t38) in #t39.{core::Object::==}(null) ?{self::Class} let final self::Class #t40 = self in let final void #t41 = self::Extension|[]=(#t37, #t38, #t40) in #t40 : #t39;
+ v = let final core::int #t42 = i in let final void #t43 = self::Extension|[]=(#t42, this, this) in this;
+ v = let final core::int #t44 = i in let final self::Class #t45 = self in let final self::Class #t46 = self in let final void #t47 = self::Extension|[]=(#t44, #t45, #t46) in #t46;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int #t48 = i in let final self::Class #t49 = self::Extension|[](#t48, this).{self::Class::+}(this) in let final void #t50 = self::Extension|[]=(#t48, this, #t49) in #t49;
+ v = let final core::int #t51 = i in let final self::Class #t52 = self in let final self::Class #t53 = self::Extension|[](#t51, #t52).{self::Class::+}(self) in let final void #t54 = self::Extension|[]=(#t51, #t52, #t53) in #t53;
+ }
+ method explicitExtensionGetSetForEffect(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final core::int #t55 = i in self::Extension|[](#t55, this).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t55, this, this) : null;
+ let final core::int #t56 = i in let final self::Class #t57 = self in self::Extension|[](#t56, #t57).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t56, #t57, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int #t58 = i in self::Extension|[]=(#t58, this, self::Extension|[](#t58, this).{self::Class::+}(this));
+ let final core::int #t59 = i in let final self::Class #t60 = self in self::Extension|[]=(#t59, #t60, self::Extension|[](#t59, #t60).{self::Class::+}(self));
+ }
+ method explicitExtensionGetSetForValue(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final core::int #t61 = i in let final self::Class #t62 = self::Extension|[](#t61, this) in #t62.{core::Object::==}(null) ?{self::Class} let final void #t63 = self::Extension|[]=(#t61, this, this) in this : #t62;
+ v = let final core::int #t64 = i in let final self::Class #t65 = self in let final self::Class #t66 = self::Extension|[](#t64, #t65) in #t66.{core::Object::==}(null) ?{self::Class} let final self::Class #t67 = self in let final void #t68 = self::Extension|[]=(#t64, #t65, #t67) in #t67 : #t66;
+ v = let final core::int #t69 = i in let final void #t70 = self::Extension|[]=(#t69, this, this) in this;
+ v = let final core::int #t71 = i in let final self::Class #t72 = self in let final void #t73 = self::Extension|[]=(#t71, self, #t72) in #t72;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int #t74 = i in let final self::Class #t75 = self::Extension|[](#t74, this).{self::Class::+}(this) in let final void #t76 = self::Extension|[]=(#t74, this, #t75) in #t75;
+ v = let final core::int #t77 = i in let final self::Class #t78 = self in let final self::Class #t79 = self::Extension|[](#t77, #t78).{self::Class::+}(self) in let final void #t80 = self::Extension|[]=(#t77, #t78, #t79) in #t79;
+ }
+}
+class Subclass extends self::Class {
+ synthetic constructor •() → self::Subclass
+ : super self::Class::•()
+ ;
+ method superIndexGetSetForEffect() → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ super.{self::Class::[]}(this).{core::Object::==}(null) ?{self::Class} super.{self::Class::[]=}(this, this) : null;
+ let final self::Class #t81 = self in super.{self::Class::[]}(#t81).{core::Object::==}(null) ?{self::Class} super.{self::Class::[]=}(#t81, self) : null;
+ super.{self::Class::[]=}(this, this);
+ super.{self::Class::[]=}(self, self);
+ super.{self::Class::[]}(this);
+ super.{self::Class::[]}(self);
+ super.{self::Class::[]=}(this, super.{self::Class::[]}(this).{self::Class::+}(this));
+ let final self::Class #t82 = self in super.{self::Class::[]=}(#t82, super.{self::Class::[]}(#t82).{self::Class::+}(self));
+ }
+ method superIndexGetSetForValue() → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class #t83 = super.{self::Class::[]}(this) in #t83.{core::Object::==}(null) ?{self::Class} let final void #t84 = super.{self::Class::[]=}(this, this) in this : #t83;
+ v = let final self::Class #t85 = self in let final self::Class #t86 = super.{self::Class::[]}(#t85) in #t86.{core::Object::==}(null) ?{self::Class} let final self::Class #t87 = self in let final void #t88 = super.{self::Class::[]=}(#t85, #t87) in #t87 : #t86;
+ v = let final void #t89 = super.{self::Class::[]=}(this, this) in this;
+ v = let final self::Class #t90 = self in let final self::Class #t91 = self in let final void #t92 = super.{self::Class::[]=}(#t90, #t91) in #t91;
+ v = super.{self::Class::[]}(this);
+ v = super.{self::Class::[]}(self);
+ v = let final self::Class #t93 = super.{self::Class::[]}(this).{self::Class::+}(this) in let final void #t94 = super.{self::Class::[]=}(this, #t93) in #t93;
+ v = let final self::Class #t95 = self in let final self::Class #t96 = super.{self::Class::[]}(#t95).{self::Class::+}(self) in let final void #t97 = super.{self::Class::[]=}(#t95, #t96) in #t96;
+ }
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2
+ : super core::Object::•()
+ ;
+ operator +(self::Class2 cls) → self::Class2
+ return cls;
+ method implicitExtensionGetSetForEffect() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ self::Extension2|[](this, this).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(this, this, this) : null;
+ let final self::Class2 #t98 = self in let final self::Class2 #t99 = self in self::Extension2|[](#t98, #t99).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(#t98, #t99, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ let final self::Class2 #t100 = self in let final self::Class2 #t101 = self in self::Extension2|[]=(#t100, #t101, self::Extension2|[](#t100, #t101).{self::Class2::+}(self));
+ }
+ method implicitExtensionGetSetForValue() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class2 #t102 = self::Extension2|[](this, this) in #t102.{core::Object::==}(null) ?{self::Class2} let final void #t103 = self::Extension2|[]=(this, this, this) in this : #t102;
+ v = let final self::Class2 #t104 = self in let final self::Class2 #t105 = self in let final self::Class2 #t106 = self::Extension2|[](#t104, #t105) in #t106.{core::Object::==}(null) ?{self::Class2} let final self::Class2 #t107 = self in let final void #t108 = self::Extension2|[]=(#t104, #t105, #t107) in #t107 : #t106;
+ v = let final void #t109 = self::Extension2|[]=(this, this, this) in this;
+ v = let final self::Class2 #t110 = self in let final self::Class2 #t111 = self in let final self::Class2 #t112 = self in let final void #t113 = self::Extension2|[]=(#t110, #t111, #t112) in #t112;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2 #t114 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t115 = self::Extension2|[]=(this, this, #t114) in #t114;
+ v = let final self::Class2 #t116 = self in let final self::Class2 #t117 = self in let final self::Class2 #t118 = self::Extension2|[](#t116, #t117).{self::Class2::+}(self) in let final void #t119 = self::Extension2|[]=(#t116, #t117, #t118) in #t118;
+ }
+ method explicitExtensionGetSetForEffect() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ self::Extension2|[](this, this).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(this, this, this) : null;
+ let final self::Class2 #t120 = self in let final self::Class2 #t121 = self in self::Extension2|[](#t120, #t121).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(#t120, #t121, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ let final self::Class2 #t122 = self in let final self::Class2 #t123 = self in self::Extension2|[]=(#t122, #t123, self::Extension2|[](#t122, #t123).{self::Class2::+}(self));
+ }
+ method explicitExtensionGetSetForValue() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class2 #t124 = self::Extension2|[](this, this) in #t124.{core::Object::==}(null) ?{self::Class2} let final void #t125 = self::Extension2|[]=(this, this, this) in this : #t124;
+ v = let final self::Class2 #t126 = self in let final self::Class2 #t127 = self in let final self::Class2 #t128 = self::Extension2|[](#t126, #t127) in #t128.{core::Object::==}(null) ?{self::Class2} let final self::Class2 #t129 = self in let final void #t130 = self::Extension2|[]=(#t126, #t127, #t129) in #t129 : #t128;
+ v = let final void #t131 = self::Extension2|[]=(this, this, this) in this;
+ v = let final self::Class2 #t132 = self in let final self::Class2 #t133 = self in let final void #t134 = self::Extension2|[]=(#t132, self, #t133) in #t133;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2 #t135 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t136 = self::Extension2|[]=(this, this, #t135) in #t135;
+ v = let final self::Class2 #t137 = self in let final self::Class2 #t138 = self in let final self::Class2 #t139 = self::Extension2|[](#t137, #t138).{self::Class2::+}(self) in let final void #t140 = self::Extension2|[]=(#t137, #t138, #t139) in #t139;
+ }
+}
+extension Extension on core::int {
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+}
+extension Extension2 on self::Class2 {
+ operator [] = self::Extension2|[];
+ operator []= = self::Extension2|[]=;
+}
+static field core::bool b = true;
+static method Extension|[](lowered final core::int #this, self::Class cls) → self::Class
+ return new self::Class::•();
+static method Extension|[]=(lowered final core::int #this, self::Class cls, self::Class value) → void {}
+static method Extension2|[](lowered final self::Class2 #this, self::Class2 cls) → self::Class2
+ return new self::Class2::•();
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2 cls, self::Class2 value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..beb5b6c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.textual_outline.expect
@@ -0,0 +1,43 @@
+bool b = true;
+
+abstract class Map<K, V> {
+ V operator [](K index);
+ void operator []=(K index, V value);
+}
+
+extension Extension on int {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+}
+
+class Class {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+ Class operator +(Class cls) => cls;
+ void indexGetSetForEffect(Map<Class, Class> map) {}
+ void indexGetSetForValue(Map<Class, Class> map) {}
+ void implicitExtensionGetSetForEffect(int i) {}
+ void implicitExtensionGetSetForValue(int i) {}
+ void explicitExtensionGetSetForEffect(int i) {}
+ void explicitExtensionGetSetForValue(int i) {}
+}
+
+class Subclass extends Class {
+ void superIndexGetSetForEffect() {}
+ void superIndexGetSetForValue() {}
+}
+
+extension Extension2 on Class2 {
+ Class2 operator [](Class2 cls) => new Class2();
+ void operator []=(Class2 cls, Class2 value) {}
+}
+
+class Class2 {
+ Class2 operator +(Class2 cls) => cls;
+ void implicitExtensionGetSetForEffect() {}
+ void implicitExtensionGetSetForValue() {}
+ void explicitExtensionGetSetForEffect() {}
+ void explicitExtensionGetSetForValue() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5088689
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,43 @@
+abstract class Map<K, V> {
+ V operator [](K index);
+ void operator []=(K index, V value);
+}
+
+bool b = true;
+
+class Class {
+ Class operator +(Class cls) => cls;
+ Class operator [](Class cls) => new Class();
+ void explicitExtensionGetSetForEffect(int i) {}
+ void explicitExtensionGetSetForValue(int i) {}
+ void implicitExtensionGetSetForEffect(int i) {}
+ void implicitExtensionGetSetForValue(int i) {}
+ void indexGetSetForEffect(Map<Class, Class> map) {}
+ void indexGetSetForValue(Map<Class, Class> map) {}
+ void operator []=(Class cls, Class value) {}
+}
+
+class Class2 {
+ Class2 operator +(Class2 cls) => cls;
+ void explicitExtensionGetSetForEffect() {}
+ void explicitExtensionGetSetForValue() {}
+ void implicitExtensionGetSetForEffect() {}
+ void implicitExtensionGetSetForValue() {}
+}
+
+class Subclass extends Class {
+ void superIndexGetSetForEffect() {}
+ void superIndexGetSetForValue() {}
+}
+
+extension Extension on int {
+ Class operator [](Class cls) => new Class();
+ void operator []=(Class cls, Class value) {}
+}
+
+extension Extension2 on Class2 {
+ Class2 operator [](Class2 cls) => new Class2();
+ void operator []=(Class2 cls, Class2 value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.weak.expect b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.weak.expect
new file mode 100644
index 0000000..84d1907
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.weak.expect
@@ -0,0 +1,334 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:25:8: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// map[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:26:8: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// map[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:42:12: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = map[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:43:12: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = map[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:58:6: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// i[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:59:6: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// i[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:75:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = i[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:76:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = i[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:91:17: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension(i)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:92:17: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension(i)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:108:21: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension(i)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:109:21: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension(i)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:126:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// super[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:127:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// super[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:143:14: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = super[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:144:14: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = super[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:168:9: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// this[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:169:9: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// self[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:185:13: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = this[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:186:13: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = self[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:201:21: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension2(this)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:202:21: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension2(self)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:218:25: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension2(this)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:219:25: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension2(self)[self] ??= self;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Map<K extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::Map<self::Map::K%, self::Map::V%>
+ : super core::Object::•()
+ ;
+ abstract operator [](generic-covariant-impl self::Map::K% index) → self::Map::V%;
+ abstract operator []=(generic-covariant-impl self::Map::K% index, generic-covariant-impl self::Map::V% value) → void;
+}
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ operator [](self::Class cls) → self::Class
+ return new self::Class::•();
+ operator []=(self::Class cls, self::Class value) → void {}
+ operator +(self::Class cls) → self::Class
+ return cls;
+ method indexGetSetForEffect(self::Map<self::Class, self::Class> map) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final self::Map<self::Class, self::Class> #t1 = map in #t1.{self::Map::[]}(this).{core::Object::==}(null) ?{self::Class} #t1.{self::Map::[]=}(this, this) : null;
+ let final self::Map<self::Class, self::Class> #t2 = map in let final self::Class #t3 = self in #t2.{self::Map::[]}(#t3).{core::Object::==}(null) ?{self::Class} #t2.{self::Map::[]=}(#t3, self) : null;
+ map.{self::Map::[]=}(this, this);
+ map.{self::Map::[]=}(self, self);
+ map.{self::Map::[]}(this);
+ map.{self::Map::[]}(self);
+ let final self::Map<self::Class, self::Class> #t4 = map in #t4.{self::Map::[]=}(this, #t4.{self::Map::[]}(this).{self::Class::+}(this));
+ let final self::Map<self::Class, self::Class> #t5 = map in let final self::Class #t6 = self in #t5.{self::Map::[]=}(#t6, #t5.{self::Map::[]}(#t6).{self::Class::+}(self));
+ }
+ method indexGetSetForValue(self::Map<self::Class, self::Class> map) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Map<self::Class, self::Class> #t7 = map in let final self::Class #t8 = #t7.{self::Map::[]}(this) in #t8.{core::Object::==}(null) ?{self::Class} let final void #t9 = #t7.{self::Map::[]=}(this, this) in this : #t8;
+ v = let final self::Map<self::Class, self::Class> #t10 = map in let final self::Class #t11 = self in let final self::Class #t12 = #t10.{self::Map::[]}(#t11) in #t12.{core::Object::==}(null) ?{self::Class} let final self::Class #t13 = self in let final void #t14 = #t10.{self::Map::[]=}(#t11, #t13) in #t13 : #t12;
+ v = let final self::Map<self::Class, self::Class> #t15 = map in let final void #t16 = #t15.{self::Map::[]=}(this, this) in this;
+ v = let final self::Map<self::Class, self::Class> #t17 = map in let final self::Class #t18 = self in let final self::Class #t19 = self in let final void #t20 = #t17.{self::Map::[]=}(#t18, #t19) in #t19;
+ v = map.{self::Map::[]}(this);
+ v = map.{self::Map::[]}(self);
+ v = let final self::Map<self::Class, self::Class> #t21 = map in let final self::Class #t22 = #t21.{self::Map::[]}(this).{self::Class::+}(this) in let final void #t23 = #t21.{self::Map::[]=}(this, #t22) in #t22;
+ v = let final self::Map<self::Class, self::Class> #t24 = map in let final self::Class #t25 = self in let final self::Class #t26 = #t24.{self::Map::[]}(#t25).{self::Class::+}(self) in let final void #t27 = #t24.{self::Map::[]=}(#t25, #t26) in #t26;
+ }
+ method implicitExtensionGetSetForEffect(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final core::int #t28 = i in self::Extension|[](#t28, this).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t28, this, this) : null;
+ let final core::int #t29 = i in let final self::Class #t30 = self in self::Extension|[](#t29, #t30).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t29, #t30, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int #t31 = i in self::Extension|[]=(#t31, this, self::Extension|[](#t31, this).{self::Class::+}(this));
+ let final core::int #t32 = i in let final self::Class #t33 = self in self::Extension|[]=(#t32, #t33, self::Extension|[](#t32, #t33).{self::Class::+}(self));
+ }
+ method implicitExtensionGetSetForValue(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final core::int #t34 = i in let final self::Class #t35 = self::Extension|[](#t34, this) in #t35.{core::Object::==}(null) ?{self::Class} let final void #t36 = self::Extension|[]=(#t34, this, this) in this : #t35;
+ v = let final core::int #t37 = i in let final self::Class #t38 = self in let final self::Class #t39 = self::Extension|[](#t37, #t38) in #t39.{core::Object::==}(null) ?{self::Class} let final self::Class #t40 = self in let final void #t41 = self::Extension|[]=(#t37, #t38, #t40) in #t40 : #t39;
+ v = let final core::int #t42 = i in let final void #t43 = self::Extension|[]=(#t42, this, this) in this;
+ v = let final core::int #t44 = i in let final self::Class #t45 = self in let final self::Class #t46 = self in let final void #t47 = self::Extension|[]=(#t44, #t45, #t46) in #t46;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int #t48 = i in let final self::Class #t49 = self::Extension|[](#t48, this).{self::Class::+}(this) in let final void #t50 = self::Extension|[]=(#t48, this, #t49) in #t49;
+ v = let final core::int #t51 = i in let final self::Class #t52 = self in let final self::Class #t53 = self::Extension|[](#t51, #t52).{self::Class::+}(self) in let final void #t54 = self::Extension|[]=(#t51, #t52, #t53) in #t53;
+ }
+ method explicitExtensionGetSetForEffect(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final core::int #t55 = i in self::Extension|[](#t55, this).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t55, this, this) : null;
+ let final core::int #t56 = i in let final self::Class #t57 = self in self::Extension|[](#t56, #t57).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t56, #t57, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int #t58 = i in self::Extension|[]=(#t58, this, self::Extension|[](#t58, this).{self::Class::+}(this));
+ let final core::int #t59 = i in let final self::Class #t60 = self in self::Extension|[]=(#t59, #t60, self::Extension|[](#t59, #t60).{self::Class::+}(self));
+ }
+ method explicitExtensionGetSetForValue(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final core::int #t61 = i in let final self::Class #t62 = self::Extension|[](#t61, this) in #t62.{core::Object::==}(null) ?{self::Class} let final void #t63 = self::Extension|[]=(#t61, this, this) in this : #t62;
+ v = let final core::int #t64 = i in let final self::Class #t65 = self in let final self::Class #t66 = self::Extension|[](#t64, #t65) in #t66.{core::Object::==}(null) ?{self::Class} let final self::Class #t67 = self in let final void #t68 = self::Extension|[]=(#t64, #t65, #t67) in #t67 : #t66;
+ v = let final core::int #t69 = i in let final void #t70 = self::Extension|[]=(#t69, this, this) in this;
+ v = let final core::int #t71 = i in let final self::Class #t72 = self in let final void #t73 = self::Extension|[]=(#t71, self, #t72) in #t72;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int #t74 = i in let final self::Class #t75 = self::Extension|[](#t74, this).{self::Class::+}(this) in let final void #t76 = self::Extension|[]=(#t74, this, #t75) in #t75;
+ v = let final core::int #t77 = i in let final self::Class #t78 = self in let final self::Class #t79 = self::Extension|[](#t77, #t78).{self::Class::+}(self) in let final void #t80 = self::Extension|[]=(#t77, #t78, #t79) in #t79;
+ }
+}
+class Subclass extends self::Class {
+ synthetic constructor •() → self::Subclass
+ : super self::Class::•()
+ ;
+ method superIndexGetSetForEffect() → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ super.{self::Class::[]}(this).{core::Object::==}(null) ?{self::Class} super.{self::Class::[]=}(this, this) : null;
+ let final self::Class #t81 = self in super.{self::Class::[]}(#t81).{core::Object::==}(null) ?{self::Class} super.{self::Class::[]=}(#t81, self) : null;
+ super.{self::Class::[]=}(this, this);
+ super.{self::Class::[]=}(self, self);
+ super.{self::Class::[]}(this);
+ super.{self::Class::[]}(self);
+ super.{self::Class::[]=}(this, super.{self::Class::[]}(this).{self::Class::+}(this));
+ let final self::Class #t82 = self in super.{self::Class::[]=}(#t82, super.{self::Class::[]}(#t82).{self::Class::+}(self));
+ }
+ method superIndexGetSetForValue() → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class #t83 = super.{self::Class::[]}(this) in #t83.{core::Object::==}(null) ?{self::Class} let final void #t84 = super.{self::Class::[]=}(this, this) in this : #t83;
+ v = let final self::Class #t85 = self in let final self::Class #t86 = super.{self::Class::[]}(#t85) in #t86.{core::Object::==}(null) ?{self::Class} let final self::Class #t87 = self in let final void #t88 = super.{self::Class::[]=}(#t85, #t87) in #t87 : #t86;
+ v = let final void #t89 = super.{self::Class::[]=}(this, this) in this;
+ v = let final self::Class #t90 = self in let final self::Class #t91 = self in let final void #t92 = super.{self::Class::[]=}(#t90, #t91) in #t91;
+ v = super.{self::Class::[]}(this);
+ v = super.{self::Class::[]}(self);
+ v = let final self::Class #t93 = super.{self::Class::[]}(this).{self::Class::+}(this) in let final void #t94 = super.{self::Class::[]=}(this, #t93) in #t93;
+ v = let final self::Class #t95 = self in let final self::Class #t96 = super.{self::Class::[]}(#t95).{self::Class::+}(self) in let final void #t97 = super.{self::Class::[]=}(#t95, #t96) in #t96;
+ }
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2
+ : super core::Object::•()
+ ;
+ operator +(self::Class2 cls) → self::Class2
+ return cls;
+ method implicitExtensionGetSetForEffect() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ self::Extension2|[](this, this).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(this, this, this) : null;
+ let final self::Class2 #t98 = self in let final self::Class2 #t99 = self in self::Extension2|[](#t98, #t99).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(#t98, #t99, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ let final self::Class2 #t100 = self in let final self::Class2 #t101 = self in self::Extension2|[]=(#t100, #t101, self::Extension2|[](#t100, #t101).{self::Class2::+}(self));
+ }
+ method implicitExtensionGetSetForValue() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class2 #t102 = self::Extension2|[](this, this) in #t102.{core::Object::==}(null) ?{self::Class2} let final void #t103 = self::Extension2|[]=(this, this, this) in this : #t102;
+ v = let final self::Class2 #t104 = self in let final self::Class2 #t105 = self in let final self::Class2 #t106 = self::Extension2|[](#t104, #t105) in #t106.{core::Object::==}(null) ?{self::Class2} let final self::Class2 #t107 = self in let final void #t108 = self::Extension2|[]=(#t104, #t105, #t107) in #t107 : #t106;
+ v = let final void #t109 = self::Extension2|[]=(this, this, this) in this;
+ v = let final self::Class2 #t110 = self in let final self::Class2 #t111 = self in let final self::Class2 #t112 = self in let final void #t113 = self::Extension2|[]=(#t110, #t111, #t112) in #t112;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2 #t114 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t115 = self::Extension2|[]=(this, this, #t114) in #t114;
+ v = let final self::Class2 #t116 = self in let final self::Class2 #t117 = self in let final self::Class2 #t118 = self::Extension2|[](#t116, #t117).{self::Class2::+}(self) in let final void #t119 = self::Extension2|[]=(#t116, #t117, #t118) in #t118;
+ }
+ method explicitExtensionGetSetForEffect() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ self::Extension2|[](this, this).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(this, this, this) : null;
+ let final self::Class2 #t120 = self in let final self::Class2 #t121 = self in self::Extension2|[](#t120, #t121).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(#t120, #t121, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ let final self::Class2 #t122 = self in let final self::Class2 #t123 = self in self::Extension2|[]=(#t122, #t123, self::Extension2|[](#t122, #t123).{self::Class2::+}(self));
+ }
+ method explicitExtensionGetSetForValue() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class2 #t124 = self::Extension2|[](this, this) in #t124.{core::Object::==}(null) ?{self::Class2} let final void #t125 = self::Extension2|[]=(this, this, this) in this : #t124;
+ v = let final self::Class2 #t126 = self in let final self::Class2 #t127 = self in let final self::Class2 #t128 = self::Extension2|[](#t126, #t127) in #t128.{core::Object::==}(null) ?{self::Class2} let final self::Class2 #t129 = self in let final void #t130 = self::Extension2|[]=(#t126, #t127, #t129) in #t129 : #t128;
+ v = let final void #t131 = self::Extension2|[]=(this, this, this) in this;
+ v = let final self::Class2 #t132 = self in let final self::Class2 #t133 = self in let final void #t134 = self::Extension2|[]=(#t132, self, #t133) in #t133;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2 #t135 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t136 = self::Extension2|[]=(this, this, #t135) in #t135;
+ v = let final self::Class2 #t137 = self in let final self::Class2 #t138 = self in let final self::Class2 #t139 = self::Extension2|[](#t137, #t138).{self::Class2::+}(self) in let final void #t140 = self::Extension2|[]=(#t137, #t138, #t139) in #t139;
+ }
+}
+extension Extension on core::int {
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+}
+extension Extension2 on self::Class2 {
+ operator [] = self::Extension2|[];
+ operator []= = self::Extension2|[]=;
+}
+static field core::bool b = true;
+static method Extension|[](lowered final core::int #this, self::Class cls) → self::Class
+ return new self::Class::•();
+static method Extension|[]=(lowered final core::int #this, self::Class cls, self::Class value) → void {}
+static method Extension2|[](lowered final self::Class2 #this, self::Class2 cls) → self::Class2
+ return new self::Class2::•();
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2 cls, self::Class2 value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.weak.transformed.expect
new file mode 100644
index 0000000..84d1907
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/pure_index_expressions.dart.weak.transformed.expect
@@ -0,0 +1,334 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:25:8: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// map[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:26:8: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// map[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:42:12: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = map[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:43:12: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = map[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:58:6: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// i[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:59:6: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// i[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:75:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = i[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:76:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = i[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:91:17: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension(i)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:92:17: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension(i)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:108:21: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension(i)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:109:21: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension(i)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:126:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// super[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:127:10: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// super[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:143:14: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = super[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:144:14: Warning: Operand of null-aware operation '??=' has type 'Class' which excludes null.
+// - 'Class' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = super[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:168:9: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// this[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:169:9: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// self[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:185:13: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = this[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:186:13: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = self[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:201:21: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension2(this)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:202:21: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// Extension2(self)[self] ??= self;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:218:25: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension2(this)[this] ??= this;
+// ^
+//
+// pkg/front_end/testcases/nnbd/pure_index_expressions.dart:219:25: Warning: Operand of null-aware operation '??=' has type 'Class2' which excludes null.
+// - 'Class2' is from 'pkg/front_end/testcases/nnbd/pure_index_expressions.dart'.
+// v = Extension2(self)[self] ??= self;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Map<K extends core::Object? = dynamic, V extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::Map<self::Map::K%, self::Map::V%>
+ : super core::Object::•()
+ ;
+ abstract operator [](generic-covariant-impl self::Map::K% index) → self::Map::V%;
+ abstract operator []=(generic-covariant-impl self::Map::K% index, generic-covariant-impl self::Map::V% value) → void;
+}
+class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ operator [](self::Class cls) → self::Class
+ return new self::Class::•();
+ operator []=(self::Class cls, self::Class value) → void {}
+ operator +(self::Class cls) → self::Class
+ return cls;
+ method indexGetSetForEffect(self::Map<self::Class, self::Class> map) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final self::Map<self::Class, self::Class> #t1 = map in #t1.{self::Map::[]}(this).{core::Object::==}(null) ?{self::Class} #t1.{self::Map::[]=}(this, this) : null;
+ let final self::Map<self::Class, self::Class> #t2 = map in let final self::Class #t3 = self in #t2.{self::Map::[]}(#t3).{core::Object::==}(null) ?{self::Class} #t2.{self::Map::[]=}(#t3, self) : null;
+ map.{self::Map::[]=}(this, this);
+ map.{self::Map::[]=}(self, self);
+ map.{self::Map::[]}(this);
+ map.{self::Map::[]}(self);
+ let final self::Map<self::Class, self::Class> #t4 = map in #t4.{self::Map::[]=}(this, #t4.{self::Map::[]}(this).{self::Class::+}(this));
+ let final self::Map<self::Class, self::Class> #t5 = map in let final self::Class #t6 = self in #t5.{self::Map::[]=}(#t6, #t5.{self::Map::[]}(#t6).{self::Class::+}(self));
+ }
+ method indexGetSetForValue(self::Map<self::Class, self::Class> map) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Map<self::Class, self::Class> #t7 = map in let final self::Class #t8 = #t7.{self::Map::[]}(this) in #t8.{core::Object::==}(null) ?{self::Class} let final void #t9 = #t7.{self::Map::[]=}(this, this) in this : #t8;
+ v = let final self::Map<self::Class, self::Class> #t10 = map in let final self::Class #t11 = self in let final self::Class #t12 = #t10.{self::Map::[]}(#t11) in #t12.{core::Object::==}(null) ?{self::Class} let final self::Class #t13 = self in let final void #t14 = #t10.{self::Map::[]=}(#t11, #t13) in #t13 : #t12;
+ v = let final self::Map<self::Class, self::Class> #t15 = map in let final void #t16 = #t15.{self::Map::[]=}(this, this) in this;
+ v = let final self::Map<self::Class, self::Class> #t17 = map in let final self::Class #t18 = self in let final self::Class #t19 = self in let final void #t20 = #t17.{self::Map::[]=}(#t18, #t19) in #t19;
+ v = map.{self::Map::[]}(this);
+ v = map.{self::Map::[]}(self);
+ v = let final self::Map<self::Class, self::Class> #t21 = map in let final self::Class #t22 = #t21.{self::Map::[]}(this).{self::Class::+}(this) in let final void #t23 = #t21.{self::Map::[]=}(this, #t22) in #t22;
+ v = let final self::Map<self::Class, self::Class> #t24 = map in let final self::Class #t25 = self in let final self::Class #t26 = #t24.{self::Map::[]}(#t25).{self::Class::+}(self) in let final void #t27 = #t24.{self::Map::[]=}(#t25, #t26) in #t26;
+ }
+ method implicitExtensionGetSetForEffect(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final core::int #t28 = i in self::Extension|[](#t28, this).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t28, this, this) : null;
+ let final core::int #t29 = i in let final self::Class #t30 = self in self::Extension|[](#t29, #t30).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t29, #t30, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int #t31 = i in self::Extension|[]=(#t31, this, self::Extension|[](#t31, this).{self::Class::+}(this));
+ let final core::int #t32 = i in let final self::Class #t33 = self in self::Extension|[]=(#t32, #t33, self::Extension|[](#t32, #t33).{self::Class::+}(self));
+ }
+ method implicitExtensionGetSetForValue(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final core::int #t34 = i in let final self::Class #t35 = self::Extension|[](#t34, this) in #t35.{core::Object::==}(null) ?{self::Class} let final void #t36 = self::Extension|[]=(#t34, this, this) in this : #t35;
+ v = let final core::int #t37 = i in let final self::Class #t38 = self in let final self::Class #t39 = self::Extension|[](#t37, #t38) in #t39.{core::Object::==}(null) ?{self::Class} let final self::Class #t40 = self in let final void #t41 = self::Extension|[]=(#t37, #t38, #t40) in #t40 : #t39;
+ v = let final core::int #t42 = i in let final void #t43 = self::Extension|[]=(#t42, this, this) in this;
+ v = let final core::int #t44 = i in let final self::Class #t45 = self in let final self::Class #t46 = self in let final void #t47 = self::Extension|[]=(#t44, #t45, #t46) in #t46;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int #t48 = i in let final self::Class #t49 = self::Extension|[](#t48, this).{self::Class::+}(this) in let final void #t50 = self::Extension|[]=(#t48, this, #t49) in #t49;
+ v = let final core::int #t51 = i in let final self::Class #t52 = self in let final self::Class #t53 = self::Extension|[](#t51, #t52).{self::Class::+}(self) in let final void #t54 = self::Extension|[]=(#t51, #t52, #t53) in #t53;
+ }
+ method explicitExtensionGetSetForEffect(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ let final core::int #t55 = i in self::Extension|[](#t55, this).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t55, this, this) : null;
+ let final core::int #t56 = i in let final self::Class #t57 = self in self::Extension|[](#t56, #t57).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t56, #t57, self) : null;
+ self::Extension|[]=(i, this, this);
+ self::Extension|[]=(i, self, self);
+ self::Extension|[](i, this);
+ self::Extension|[](i, self);
+ let final core::int #t58 = i in self::Extension|[]=(#t58, this, self::Extension|[](#t58, this).{self::Class::+}(this));
+ let final core::int #t59 = i in let final self::Class #t60 = self in self::Extension|[]=(#t59, #t60, self::Extension|[](#t59, #t60).{self::Class::+}(self));
+ }
+ method explicitExtensionGetSetForValue(core::int i) → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final core::int #t61 = i in let final self::Class #t62 = self::Extension|[](#t61, this) in #t62.{core::Object::==}(null) ?{self::Class} let final void #t63 = self::Extension|[]=(#t61, this, this) in this : #t62;
+ v = let final core::int #t64 = i in let final self::Class #t65 = self in let final self::Class #t66 = self::Extension|[](#t64, #t65) in #t66.{core::Object::==}(null) ?{self::Class} let final self::Class #t67 = self in let final void #t68 = self::Extension|[]=(#t64, #t65, #t67) in #t67 : #t66;
+ v = let final core::int #t69 = i in let final void #t70 = self::Extension|[]=(#t69, this, this) in this;
+ v = let final core::int #t71 = i in let final self::Class #t72 = self in let final void #t73 = self::Extension|[]=(#t71, self, #t72) in #t72;
+ v = self::Extension|[](i, this);
+ v = self::Extension|[](i, self);
+ v = let final core::int #t74 = i in let final self::Class #t75 = self::Extension|[](#t74, this).{self::Class::+}(this) in let final void #t76 = self::Extension|[]=(#t74, this, #t75) in #t75;
+ v = let final core::int #t77 = i in let final self::Class #t78 = self in let final self::Class #t79 = self::Extension|[](#t77, #t78).{self::Class::+}(self) in let final void #t80 = self::Extension|[]=(#t77, #t78, #t79) in #t79;
+ }
+}
+class Subclass extends self::Class {
+ synthetic constructor •() → self::Subclass
+ : super self::Class::•()
+ ;
+ method superIndexGetSetForEffect() → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ super.{self::Class::[]}(this).{core::Object::==}(null) ?{self::Class} super.{self::Class::[]=}(this, this) : null;
+ let final self::Class #t81 = self in super.{self::Class::[]}(#t81).{core::Object::==}(null) ?{self::Class} super.{self::Class::[]=}(#t81, self) : null;
+ super.{self::Class::[]=}(this, this);
+ super.{self::Class::[]=}(self, self);
+ super.{self::Class::[]}(this);
+ super.{self::Class::[]}(self);
+ super.{self::Class::[]=}(this, super.{self::Class::[]}(this).{self::Class::+}(this));
+ let final self::Class #t82 = self in super.{self::Class::[]=}(#t82, super.{self::Class::[]}(#t82).{self::Class::+}(self));
+ }
+ method superIndexGetSetForValue() → void {
+ late final self::Class self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class #t83 = super.{self::Class::[]}(this) in #t83.{core::Object::==}(null) ?{self::Class} let final void #t84 = super.{self::Class::[]=}(this, this) in this : #t83;
+ v = let final self::Class #t85 = self in let final self::Class #t86 = super.{self::Class::[]}(#t85) in #t86.{core::Object::==}(null) ?{self::Class} let final self::Class #t87 = self in let final void #t88 = super.{self::Class::[]=}(#t85, #t87) in #t87 : #t86;
+ v = let final void #t89 = super.{self::Class::[]=}(this, this) in this;
+ v = let final self::Class #t90 = self in let final self::Class #t91 = self in let final void #t92 = super.{self::Class::[]=}(#t90, #t91) in #t91;
+ v = super.{self::Class::[]}(this);
+ v = super.{self::Class::[]}(self);
+ v = let final self::Class #t93 = super.{self::Class::[]}(this).{self::Class::+}(this) in let final void #t94 = super.{self::Class::[]=}(this, #t93) in #t93;
+ v = let final self::Class #t95 = self in let final self::Class #t96 = super.{self::Class::[]}(#t95).{self::Class::+}(self) in let final void #t97 = super.{self::Class::[]=}(#t95, #t96) in #t96;
+ }
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2
+ : super core::Object::•()
+ ;
+ operator +(self::Class2 cls) → self::Class2
+ return cls;
+ method implicitExtensionGetSetForEffect() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ self::Extension2|[](this, this).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(this, this, this) : null;
+ let final self::Class2 #t98 = self in let final self::Class2 #t99 = self in self::Extension2|[](#t98, #t99).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(#t98, #t99, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ let final self::Class2 #t100 = self in let final self::Class2 #t101 = self in self::Extension2|[]=(#t100, #t101, self::Extension2|[](#t100, #t101).{self::Class2::+}(self));
+ }
+ method implicitExtensionGetSetForValue() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class2 #t102 = self::Extension2|[](this, this) in #t102.{core::Object::==}(null) ?{self::Class2} let final void #t103 = self::Extension2|[]=(this, this, this) in this : #t102;
+ v = let final self::Class2 #t104 = self in let final self::Class2 #t105 = self in let final self::Class2 #t106 = self::Extension2|[](#t104, #t105) in #t106.{core::Object::==}(null) ?{self::Class2} let final self::Class2 #t107 = self in let final void #t108 = self::Extension2|[]=(#t104, #t105, #t107) in #t107 : #t106;
+ v = let final void #t109 = self::Extension2|[]=(this, this, this) in this;
+ v = let final self::Class2 #t110 = self in let final self::Class2 #t111 = self in let final self::Class2 #t112 = self in let final void #t113 = self::Extension2|[]=(#t110, #t111, #t112) in #t112;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2 #t114 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t115 = self::Extension2|[]=(this, this, #t114) in #t114;
+ v = let final self::Class2 #t116 = self in let final self::Class2 #t117 = self in let final self::Class2 #t118 = self::Extension2|[](#t116, #t117).{self::Class2::+}(self) in let final void #t119 = self::Extension2|[]=(#t116, #t117, #t118) in #t118;
+ }
+ method explicitExtensionGetSetForEffect() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ self::Extension2|[](this, this).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(this, this, this) : null;
+ let final self::Class2 #t120 = self in let final self::Class2 #t121 = self in self::Extension2|[](#t120, #t121).{core::Object::==}(null) ?{self::Class2} self::Extension2|[]=(#t120, #t121, self) : null;
+ self::Extension2|[]=(this, this, this);
+ self::Extension2|[]=(self, self, self);
+ self::Extension2|[](this, this);
+ self::Extension2|[](self, self);
+ self::Extension2|[]=(this, this, self::Extension2|[](this, this).{self::Class2::+}(this));
+ let final self::Class2 #t122 = self in let final self::Class2 #t123 = self in self::Extension2|[]=(#t122, #t123, self::Extension2|[](#t122, #t123).{self::Class2::+}(self));
+ }
+ method explicitExtensionGetSetForValue() → void {
+ late final self::Class2 self;
+ if(self::b)
+ self = this;
+ dynamic v;
+ v = let final self::Class2 #t124 = self::Extension2|[](this, this) in #t124.{core::Object::==}(null) ?{self::Class2} let final void #t125 = self::Extension2|[]=(this, this, this) in this : #t124;
+ v = let final self::Class2 #t126 = self in let final self::Class2 #t127 = self in let final self::Class2 #t128 = self::Extension2|[](#t126, #t127) in #t128.{core::Object::==}(null) ?{self::Class2} let final self::Class2 #t129 = self in let final void #t130 = self::Extension2|[]=(#t126, #t127, #t129) in #t129 : #t128;
+ v = let final void #t131 = self::Extension2|[]=(this, this, this) in this;
+ v = let final self::Class2 #t132 = self in let final self::Class2 #t133 = self in let final void #t134 = self::Extension2|[]=(#t132, self, #t133) in #t133;
+ v = self::Extension2|[](this, this);
+ v = self::Extension2|[](self, self);
+ v = let final self::Class2 #t135 = self::Extension2|[](this, this).{self::Class2::+}(this) in let final void #t136 = self::Extension2|[]=(this, this, #t135) in #t135;
+ v = let final self::Class2 #t137 = self in let final self::Class2 #t138 = self in let final self::Class2 #t139 = self::Extension2|[](#t137, #t138).{self::Class2::+}(self) in let final void #t140 = self::Extension2|[]=(#t137, #t138, #t139) in #t139;
+ }
+}
+extension Extension on core::int {
+ operator [] = self::Extension|[];
+ operator []= = self::Extension|[]=;
+}
+extension Extension2 on self::Class2 {
+ operator [] = self::Extension2|[];
+ operator []= = self::Extension2|[]=;
+}
+static field core::bool b = true;
+static method Extension|[](lowered final core::int #this, self::Class cls) → self::Class
+ return new self::Class::•();
+static method Extension|[]=(lowered final core::int #this, self::Class cls, self::Class value) → void {}
+static method Extension2|[](lowered final self::Class2 #this, self::Class2 cls) → self::Class2
+ return new self::Class2::•();
+static method Extension2|[]=(lowered final self::Class2 #this, self::Class2 cls, self::Class2 value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect
index d51e2b9..e5febc5 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect
@@ -1,11 +1,17 @@
-extension E ;
-on String (){}
-class A {
- String operator[](int index) => "foo";
- void operator[]=(int index, String value) {}
+extension E on String {
+ int get foo => 42;
+ void operator []=(int index, int value) {}
+ int operator [](int index) => 42;
}
+
+class A {
+ String operator [](int index) => "foo";
+ void operator []=(int index, String value) {}
+}
+
class B extends A {
void test() {}
}
+
warning(String s, List<String> l, Map<String, int> m) {}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..77eca74
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class A {
+ String operator [](int index) => "foo";
+ void operator []=(int index, String value) {}
+}
+
+class B extends A {
+ void test() {}
+}
+
+extension E on String {
+ int get foo => 42;
+ int operator [](int index) => 42;
+ void operator []=(int index, int value) {}
+}
+
+main() {}
+warning(String s, List<String> l, Map<String, int> m) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.textual_outline.expect
index 33f6302..14d2d75 100644
--- a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.textual_outline.expect
@@ -2,8 +2,17 @@
class Class {
Class _field;
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ Class get field => _field;
+ void set field(Class value) {}
+ Class method() => field;
+ Class operator [](Class key) => field;
+ void operator []=(Class key, Class value) {}
+ Class operator +(int value) => field;
+ Class operator -() => field;
+}
+
main() {}
void propertyAccess(Class c) {}
void indexAccess(Class c) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..027cbbc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_explicit_extension.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class Class {
+ Class _field;
+}
+
+extension Extension on Class {
+ Class get field => _field;
+ Class method() => field;
+ Class operator +(int value) => field;
+ Class operator -() => field;
+ Class operator [](Class key) => field;
+ void operator []=(Class key, Class value) {}
+ void set field(Class value) {}
+}
+
+main() {}
+void ifNull(Class c) {}
+void indexAccess(Class c) {}
+void operatorAccess(Class c) {}
+void propertyAccess(Class c) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.textual_outline.expect
index 33f6302..14d2d75 100644
--- a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.textual_outline.expect
@@ -2,8 +2,17 @@
class Class {
Class _field;
}
-extension Extension ;
-on Class (){}
+
+extension Extension on Class {
+ Class get field => _field;
+ void set field(Class value) {}
+ Class method() => field;
+ Class operator [](Class key) => field;
+ void operator []=(Class key, Class value) {}
+ Class operator +(int value) => field;
+ Class operator -() => field;
+}
+
main() {}
void propertyAccess(Class c) {}
void indexAccess(Class c) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..027cbbc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/no_null_shorting_extension.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class Class {
+ Class _field;
+}
+
+extension Extension on Class {
+ Class get field => _field;
+ Class method() => field;
+ Class operator +(int value) => field;
+ Class operator -() => field;
+ Class operator [](Class key) => field;
+ void operator []=(Class key, Class value) {}
+ void set field(Class value) {}
+}
+
+main() {}
+void ifNull(Class c) {}
+void indexAccess(Class c) {}
+void operatorAccess(Class c) {}
+void propertyAccess(Class c) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.textual_outline.expect
index 72a0f5b..db630d4 100644
--- a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.textual_outline.expect
@@ -1,6 +1,8 @@
import 'nullable_extension_on_opt_out_lib.dart';
-extension on ;
-A;
-? { String get text => "Lily was here"; }
+
+extension on A? {
+ String get text => "Lily was here";
+}
+
void main() {}
expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5294531
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/nullable_extension_on_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'nullable_extension_on_opt_out_lib.dart';
+
+expect(expected, actual) {}
+
+extension on A? {
+ String get text => "Lily was here";
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline.expect
index 50ce9f2..7298d03 100644
--- a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline.expect
@@ -1,45 +1,60 @@
// @dart = 2.8
import 'unsound_checks_lib.dart';
+
isNullOptOut1(int i) => i == null;
isNotNullOptOut1(int i) => i != null;
isNullOptOut2(int i) => null == i;
isNotNullOptOut2(int i) => null != i;
ifNullOptOut(int i) => i ?? 42;
+
class OptOutClass1 {}
-extension OptOutExtension ;
-on OptOutClass1 (){}
+
+extension OptOutExtension on OptOutClass1 {
+ int operator [](int index) => index;
+ void operator []=(int index, int value) {}
+}
+
extensionIfNullOptOut1(int i) => OptOutExtension(new OptOutClass1())[i] ??= 42;
extensionIfNullOptOut1ForEffect(int i) {}
extensionIfNullOptOut2(int i) => new OptOutClass1()[i] ??= 42;
extensionIfNullOptOut2ForEffect(int i) {}
+
class OptOutClass2 {
int operator [](int index) => index;
void operator []=(int index, int value) {}
}
+
ifNullIndexSetOptOut(int i) => new OptOutClass2()[i] ??= 42;
ifNullIndexSetOptOutForEffect(int i) {}
+
class OptOutClass3 {
int field;
OptOutClass3(this.field);
}
+
ifNullPropertySetOptOut(int i) => new OptOutClass3(i).field ??= 42;
ifNullPropertySetOptOutForEffect(int i) {}
ifNullSetOptOut(int i) => i ??= 42;
ifNullSetOptOutForEffect(int i) {}
+
class OptOutSuperClass4 {
int operator [](int index) => index;
void operator []=(int index, int value) {}
}
+
class OptOutClass4 extends OptOutSuperClass4 {
method(int i) => super[i] ??= 42;
methodForEffect(int i) {}
}
+
ifNullSuperIndexSetOptOut(int i) => new OptOutClass4().method(i);
ifNullSuperIndexSetOptOutForEffect(int i) {}
+
class OptOutClass5 {
int field;
OptOutClass5(this.field);
}
+
nullAwareIfNullSetOptOut(int i) {}
nullAwareIfNullSetOptOutForEffect(int i) {}
isTestOptOut(int i) => i is int;
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f86f53b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,60 @@
+// @dart = 2.8
+import 'unsound_checks_lib.dart';
+
+class OptOutClass1 {}
+
+class OptOutClass2 {
+ int operator [](int index) => index;
+ void operator []=(int index, int value) {}
+}
+
+class OptOutClass3 {
+ OptOutClass3(this.field);
+ int field;
+}
+
+class OptOutClass4 extends OptOutSuperClass4 {
+ method(int i) => super[i] ??= 42;
+ methodForEffect(int i) {}
+}
+
+class OptOutClass5 {
+ OptOutClass5(this.field);
+ int field;
+}
+
+class OptOutSuperClass4 {
+ int operator [](int index) => index;
+ void operator []=(int index, int value) {}
+}
+
+expect(expected, actual) {}
+
+extension OptOutExtension on OptOutClass1 {
+ int operator [](int index) => index;
+ void operator []=(int index, int value) {}
+}
+
+extensionIfNullOptOut1(int i) => OptOutExtension(new OptOutClass1())[i] ??= 42;
+extensionIfNullOptOut1ForEffect(int i) {}
+extensionIfNullOptOut2(int i) => new OptOutClass1()[i] ??= 42;
+extensionIfNullOptOut2ForEffect(int i) {}
+ifNullIndexSetOptOut(int i) => new OptOutClass2()[i] ??= 42;
+ifNullIndexSetOptOutForEffect(int i) {}
+ifNullOptOut(int i) => i ?? 42;
+ifNullPropertySetOptOut(int i) => new OptOutClass3(i).field ??= 42;
+ifNullPropertySetOptOutForEffect(int i) {}
+ifNullSetOptOut(int i) => i ??= 42;
+ifNullSetOptOutForEffect(int i) {}
+ifNullSuperIndexSetOptOut(int i) => new OptOutClass4().method(i);
+ifNullSuperIndexSetOptOutForEffect(int i) {}
+isNotNullOptOut1(int i) => i != null;
+isNotNullOptOut2(int i) => null != i;
+isNotTestOptOut(int i) => i is! int;
+isNullOptOut1(int i) => i == null;
+isNullOptOut2(int i) => null == i;
+isTestOptOut(int i) => i is int;
+main() {}
+nullAwareIfNullSetOptOut(int i) {}
+nullAwareIfNullSetOptOutForEffect(int i) {}
+throws(void f(), [bool Function(Object) testException]) {}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index b946481..901929c 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -20,73 +20,11 @@
regress/issue_39091_2: EmptyOutput
regress/utf_16_le_content.crash: EmptyOutput
-extensions/ambiguous: FormatterCrash
-extensions/annotations: FormatterCrash
-extensions/async_extensions: FormatterCrash
-extensions/bounds: FormatterCrash
-extensions/builtin_identifiers: FormatterCrash
-extensions/call_methods: FormatterCrash
-extensions/check_bounds: FormatterCrash
-extensions/compounds: FormatterCrash
-extensions/conflict_with_object: FormatterCrash
-extensions/conflicts: FormatterCrash
-extensions/default_values: FormatterCrash
-extensions/direct_instance_access: FormatterCrash
-extensions/direct_static_access: FormatterCrash
-extensions/dynamic_invoke: FormatterCrash
-extensions/explicit_extension_access: FormatterCrash
-extensions/explicit_extension_inference: FormatterCrash
-extensions/explicit_generic_extension_access: FormatterCrash
-extensions/explicit_invalid_access: FormatterCrash
-extensions/explicit_this: FormatterCrash
-extensions/extension_call: FormatterCrash
extensions/extension_constructor: FormatterCrash
extensions/extension_field_with_type_parameter_usage: FormatterCrash
-extensions/extension_member_conflict: FormatterCrash
-extensions/extension_methods: FormatterCrash
-extensions/extension_setter: FormatterCrash
-extensions/extension_setter_error: FormatterCrash
-extensions/generic_function_in_generic_extension: FormatterCrash
-extensions/getter_setter_conflict: FormatterCrash
-extensions/if_null: FormatterCrash
-extensions/implicit_extension_inference: FormatterCrash
-extensions/implicit_this: FormatterCrash
-extensions/index: FormatterCrash
-extensions/instance_access: FormatterCrash
-extensions/instance_access_of_static: FormatterCrash
-extensions/instance_members: FormatterCrash
-extensions/instance_tearoff: FormatterCrash
-extensions/internal_resolution: FormatterCrash
-extensions/invalid_explicit_access: FormatterCrash
-extensions/invalid_explicit_static_access: FormatterCrash
extensions/issue38600: FormatterCrash
extensions/issue38712: FormatterCrash
-extensions/issue38713: FormatterCrash
extensions/issue38745: FormatterCrash
-extensions/issue38755: FormatterCrash
-extensions/issue38915: FormatterCrash
-extensions/issue39527: FormatterCrash
-extensions/issue39889: FormatterCrash
-extensions/issue40596: FormatterCrash
-extensions/issue40713: FormatterCrash
-extensions/issue40816: FormatterCrash
-extensions/issue43218: FormatterCrash
-extensions/language_issue1182: FormatterCrash
-extensions/missing_toplevel: FormatterCrash
-extensions/nested_on_types: FormatterCrash
-extensions/null_aware: FormatterCrash
-extensions/on_function_type: FormatterCrash
-extensions/on_type_inference: FormatterCrash
-extensions/on_type_variable_inference: FormatterCrash
-extensions/operators: FormatterCrash
-extensions/other_kinds: FormatterCrash
-extensions/static_access: FormatterCrash
-extensions/static_access_of_instance: FormatterCrash
-extensions/tear_offs: FormatterCrash
-extensions/type_variable_bound: FormatterCrash
-extensions/type_variables: FormatterCrash
-extensions/unnamed_extensions: FormatterCrash
-extensions/use_this: FormatterCrash
general/annotation_eof: FormatterCrash
general/bad_setter_abstract: FormatterCrash
general/bug31124: FormatterCrash
@@ -112,19 +50,15 @@
general/error_recovery/issue_39230.crash: FormatterCrash
general/error_recovery/issue_39958_01: FormatterCrash
general/function_type_default_value: FormatterCrash
-general/getter_vs_setter_type: FormatterCrash
general/incomplete_field_formal_parameter: FormatterCrash
general/invalid_operator2: FormatterCrash
general/invalid_operator: FormatterCrash
-general/issue40242: FormatterCrash
general/issue42997: FormatterCrash
general/issue43363: FormatterCrash
general/many_errors: FormatterCrash
general/null_safety_invalid_experiment_and_language_version: FormatterCrash
-general/type_parameter_usage_in_static_method_in_extension: FormatterCrash
general/type_parameters_on_void: FormatterCrash
general/var_as_type_name: FormatterCrash
-general/well_boundness_checks_in_outline: FormatterCrash
general_nnbd_opt_out/annotation_eof: FormatterCrash
general_nnbd_opt_out/bad_setter_abstract: FormatterCrash
general_nnbd_opt_out/bug31124: FormatterCrash
@@ -173,49 +107,24 @@
late_lowering/uninitialized_non_nullable_late_fields: FormatterCrash
nnbd/abstract_field_errors: FormatterCrash
nnbd/covariant_late_field: FormatterCrash
-nnbd/extension_bounds: FormatterCrash
-nnbd/extension_never: FormatterCrash
-nnbd/extension_type_variable_bound: FormatterCrash
-nnbd/external_field_errors: FormatterCrash
-nnbd/external_fields: FormatterCrash
nnbd/forbidden_supers: FormatterCrash
-nnbd/getter_vs_setter_type: FormatterCrash
nnbd/getter_vs_setter_type_late: FormatterCrash
-nnbd/getter_vs_setter_type_nnbd: FormatterCrash
-nnbd/infer_if_null: FormatterCrash
nnbd/inheritance_from_opt_in: FormatterCrash
nnbd/issue40805: FormatterCrash
-nnbd/issue41349: FormatterCrash
nnbd/issue41597: FormatterCrash
nnbd/issue42967: FormatterCrash
-nnbd/issue43211: FormatterCrash
-nnbd/issue43278: FormatterCrash
nnbd/issue43354: FormatterCrash
-nnbd/issue43591: FormatterCrash
-nnbd/language_issue1182: FormatterCrash
nnbd/late: FormatterCrash
nnbd/later: FormatterCrash
nnbd/no_null_shorting_explicit_extension: FormatterCrash
nnbd/no_null_shorting_extension: FormatterCrash
nnbd/non_nullable_field_initialization: FormatterCrash
-nnbd/null_shorting_cascade: FormatterCrash
-nnbd/null_shorting_explicit_extension: FormatterCrash
-nnbd/null_shorting_extension: FormatterCrash
-nnbd/null_shorting_index: FormatterCrash
-nnbd/nullable_extension: FormatterCrash
-nnbd/nullable_setter: FormatterCrash
nnbd/opt_out: FormatterCrash
nnbd/potentially_non_nullable_field: FormatterCrash
-nnbd/potentially_nullable_access: FormatterCrash
-nnbd/strictly_non_nullable_warnings: FormatterCrash
nnbd/uninitialized_non_nullable_late_fields: FormatterCrash
nnbd_mixed/inheritance_from_opt_in: FormatterCrash
nnbd_mixed/issue41597: FormatterCrash
-nnbd_mixed/no_null_shorting_explicit_extension: FormatterCrash
-nnbd_mixed/no_null_shorting_extension: FormatterCrash
nnbd_mixed/null_safety_invalid_language_version: FormatterCrash
-nnbd_mixed/nullable_extension_on_opt_out: FormatterCrash
-nnbd_mixed/unsound_checks: FormatterCrash
nonfunction_type_aliases/issue41501: FormatterCrash
rasta/bad_redirection: FormatterCrash
rasta/issue_000032: FormatterCrash
diff --git a/tools/VERSION b/tools/VERSION
index 45bf2ca..36ceaf1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 165
+PRERELEASE 166
PRERELEASE_PATCH 0
\ No newline at end of file