Version 2.10.0-12.0.dev

Merge commit '970f17b38e67f761f390137c1bcb36f84dbcf8ff' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 58a930c..10b2831 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2020-08-07T16:47:24.963156",
+  "generated": "2020-08-11T10:59:54.661195",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -142,7 +142,7 @@
       "name": "charcode",
       "rootUri": "../third_party/pkg/charcode",
       "packageUri": "lib/",
-      "languageVersion": "2.9"
+      "languageVersion": "2.10"
     },
     {
       "name": "cli_util",
diff --git a/DEPS b/DEPS
index f9e1d9a..4268f99 100644
--- a/DEPS
+++ b/DEPS
@@ -73,14 +73,14 @@
   "boringssl_gen_rev": "429ccb1877f7987a6f3988228bc2440e61293499",
   "boringssl_rev" : "4dfd5af70191b068aebe567b8e29ce108cee85ce",
   "browser-compat-data_tag": "v1.0.22",
-  "charcode_rev": "af1e2d59a9c383da94f99ea51dac4b93fb0626c4",
+  "charcode_rev": "4a685faba42d86ebd9d661eadd1e79d0a1c34c43",
   "chrome_rev" : "19997",
   "cli_util_tag" : "0.2.0",
   "collection_rev": "583693680fc067e34ca5b72503df25e8b80579f9",
   "convert_rev": "c1b01f832835d3d8a06b0b246a361c0eaab35d3c",
   "crypto_rev": "f7c48b334b1386bc5ab0f706fbcd6df8496a87fc",
   "csslib_rev": "451448a9ac03f87a8d0377fc0b411d8c388a6cb4",
-  "dart2js_info_tag" : "0.6.0",
+  "dart2js_info_rev" : "94ba36cb77067f28b75a4212e77b810a2d7385e9",
 
   # Note: Updates to dart_style have to be coordinated with the infrastructure
   # team so that the internal formatter in `tools/sdks/dart-sdk/bin/dartfmt`
@@ -324,7 +324,7 @@
   Var("dart_root") + "/third_party/pkg_tested/dart_style":
       Var("dart_git") + "dart_style.git" + "@" + Var("dart_style_tag"),
   Var("dart_root") + "/third_party/pkg/dart2js_info":
-      Var("dart_git") + "dart2js_info.git" + "@" + Var("dart2js_info_tag"),
+      Var("dart_git") + "dart2js_info.git" + "@" + Var("dart2js_info_rev"),
   Var("dart_root") + "/third_party/pkg/dartdoc":
       Var("dart_git") + "dartdoc.git" + "@" + Var("dartdoc_rev"),
   Var("dart_root") + "/third_party/pkg/ffi":
@@ -539,7 +539,7 @@
     "packages": [
       {
         "package": "dart/cfe/dart2js_dills",
-        "version": "binary_version:44_2",
+        "version": "binary_version:45",
       }
     ],
     "dep_type": "cipd",
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 53e40dd..4d1f27b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -4596,8 +4596,7 @@
               assert(optional('(', token.next));
             }
           } else if (identical(type, TokenType.OPEN_PAREN) ||
-              identical(type, TokenType.OPEN_SQUARE_BRACKET) ||
-              identical(type, TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET)) {
+              identical(type, TokenType.OPEN_SQUARE_BRACKET)) {
             token = parseArgumentOrIndexStar(
                 token, typeArg, /* checkedNullAware = */ false);
           } else if (identical(type, TokenType.QUESTION)) {
@@ -4661,8 +4660,7 @@
           identical(nextType, TokenType.QUESTION) ||
           identical(nextType, TokenType.OPEN_PAREN) ||
           identical(nextType, TokenType.OPEN_SQUARE_BRACKET) ||
-          identical(nextType, TokenType.QUESTION_PERIOD) ||
-          identical(nextType, TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET)) {
+          identical(nextType, TokenType.QUESTION_PERIOD)) {
         return SELECTOR_PRECEDENCE;
       }
       return POSTFIX_PRECEDENCE;
@@ -4808,7 +4806,7 @@
         if (isConditional) potentialNullAware = false;
       }
 
-      if (optional('[', next) || optional('?.[', next) || potentialNullAware) {
+      if (optional('[', next) || potentialNullAware) {
         assert(typeArg == noTypeParamOrArg);
         Token openSquareBracket = next;
         Token question;
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
index a18c954..5f87669 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
@@ -401,9 +401,7 @@
     appendPrecedenceToken(type);
     Token close = tail;
     BeginToken begin = groupingStack.head;
-    if (!identical(begin.kind, openKind) &&
-        !(begin.kind == QUESTION_PERIOD_OPEN_SQUARE_BRACKET_TOKEN &&
-            openKind == OPEN_SQUARE_BRACKET_TOKEN)) {
+    if (!identical(begin.kind, openKind)) {
       assert(begin.kind == STRING_INTERPOLATION_TOKEN &&
           openKind == OPEN_CURLY_BRACKET_TOKEN);
       // We're ending an interpolated expression.
@@ -516,9 +514,7 @@
       BeginToken begin = groupingStack.head;
       if (openKind == begin.kind ||
           (openKind == OPEN_CURLY_BRACKET_TOKEN &&
-              begin.kind == STRING_INTERPOLATION_TOKEN) ||
-          (openKind == OPEN_SQUARE_BRACKET_TOKEN &&
-              begin.kind == QUESTION_PERIOD_OPEN_SQUARE_BRACKET_TOKEN)) {
+              begin.kind == STRING_INTERPOLATION_TOKEN)) {
         if (first) {
           // If the expected opener has been found on the first pass
           // then no recovery necessary.
@@ -1017,10 +1013,6 @@
           appendPrecedenceToken(TokenType.QUESTION_PERIOD_PERIOD);
           return advance();
         }
-        if (identical($OPEN_SQUARE_BRACKET, next)) {
-          appendBeginGroup(TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET);
-          return advance();
-        }
       }
       appendPrecedenceToken(TokenType.QUESTION_PERIOD);
       return next;
@@ -1945,7 +1937,6 @@
     '{': TokenType.CLOSE_CURLY_BRACKET,
     '<': TokenType.GT,
     r'${': TokenType.CLOSE_CURLY_BRACKET,
-    '?.[': TokenType.CLOSE_SQUARE_BRACKET,
   }[begin.lexeme];
 }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
index df5ab6d..2d539c0 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
@@ -156,8 +156,7 @@
             type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
           return _makeError(ScannerErrorCode.EXPECTED_TOKEN, ['}']);
         }
-        if (type == TokenType.OPEN_SQUARE_BRACKET ||
-            type == TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET) {
+        if (type == TokenType.OPEN_SQUARE_BRACKET) {
           return _makeError(ScannerErrorCode.EXPECTED_TOKEN, [']']);
         }
         if (type == TokenType.OPEN_PAREN) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/recover.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/recover.dart
index 09e7cce..4a06122 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/recover.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/recover.dart
@@ -66,7 +66,6 @@
     '{': '}',
     '<': '>',
     r'${': '}',
-    '?.[': ']',
   }[openBrace];
 }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
index fc3bb7e..9f501af 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
@@ -51,7 +51,6 @@
         type == TokenType.OPEN_CURLY_BRACKET ||
         type == TokenType.OPEN_PAREN ||
         type == TokenType.OPEN_SQUARE_BRACKET ||
-        type == TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET ||
         type == TokenType.STRING_INTERPOLATION_EXPRESSION);
   }
 
@@ -1507,12 +1506,6 @@
       NO_PRECEDENCE,
       PERIOD_PERIOD_PERIOD_QUESTION_TOKEN);
 
-  static const TokenType QUESTION_PERIOD_OPEN_SQUARE_BRACKET = const TokenType(
-      '?.[',
-      'QUESTION_PERIOD_OPEN_SQUARE_BRACKET',
-      SELECTOR_PRECEDENCE,
-      QUESTION_PERIOD_OPEN_SQUARE_BRACKET_TOKEN);
-
   static const TokenType QUESTION_PERIOD_PERIOD = const TokenType(
       '?..',
       'QUESTION_PERIOD_PERIOD',
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token_constants.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token_constants.dart
index a0a82ea..34d7832 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token_constants.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token_constants.dart
@@ -89,6 +89,4 @@
 const int GT_GT_GT_TOKEN = GENERIC_METHOD_TYPE_LIST_TOKEN + 1;
 const int PERIOD_PERIOD_PERIOD_QUESTION_TOKEN = GT_GT_GT_TOKEN + 1;
 const int GT_GT_GT_EQ_TOKEN = PERIOD_PERIOD_PERIOD_QUESTION_TOKEN + 1;
-const int QUESTION_PERIOD_OPEN_SQUARE_BRACKET_TOKEN = GT_GT_GT_EQ_TOKEN + 1;
-const int QUESTION_PERIOD_PERIOD_TOKEN =
-    QUESTION_PERIOD_OPEN_SQUARE_BRACKET_TOKEN + 1;
+const int QUESTION_PERIOD_PERIOD_TOKEN = GT_GT_GT_EQ_TOKEN + 1;
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
index 04ae6f3..6ef8308 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
@@ -914,12 +914,15 @@
 /// This assumes that the current working directory is the repository root.
 Future<void> updateAllTests(List<String> relativeTestPaths) async {
   for (String testPath in relativeTestPaths) {
-    List<String> arguments = [
-      '--packages=${Platform.packageConfig}',
+    List<String> arguments = [];
+    if (Platform.packageConfig != null) {
+      arguments.add('--packages=${Platform.packageConfig}');
+    }
+    arguments.addAll([
       testPath,
       '-g',
-      '--run-all'
-    ];
+      '--run-all',
+    ]);
     print('Running: ${Platform.resolvedExecutable} ${arguments.join(' ')}');
     Process process = await Process.start(
         Platform.resolvedExecutable, arguments,
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index d56a21e..c39d80f 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -2990,12 +2990,13 @@
   }
 
   void test_indexed_nullAware() {
-    CompilationUnit unit = parseCompilationUnit('main() { a?.[7]; }');
+    CompilationUnit unit = parseCompilationUnit('main() { a?[7]; }');
     FunctionDeclaration method = unit.declarations[0];
     BlockFunctionBody body = method.functionExpression.body;
     ExpressionStatement statement = body.block.statements[0];
     IndexExpression expression = statement.expression;
-    expect(expression.leftBracket.lexeme, '?.[');
+    expect(expression.question, isNotNull);
+    expect(expression.leftBracket.lexeme, '[');
     expect(expression.rightBracket.lexeme, ']');
     expect(expression.leftBracket.endGroup, expression.rightBracket);
   }
@@ -3003,14 +3004,17 @@
   void test_indexed_nullAware_optOut() {
     CompilationUnit unit = parseCompilationUnit('''
 // @dart = 2.2
-main() { a?.[7]; }''',
-        errors: [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 27, 1)]);
+main() { a?[7]; }''',
+        errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 25, 1)]);
     FunctionDeclaration method = unit.declarations[0];
     BlockFunctionBody body = method.functionExpression.body;
     ExpressionStatement statement = body.block.statements[0];
-    PropertyAccess expression = statement.expression;
+    IndexExpressionImpl expression = statement.expression;
     expect(expression.target.toSource(), 'a');
-    expect(expression.operator.lexeme, '?.');
+    expect(expression.question, isNotNull);
+    expect(expression.leftBracket.lexeme, '[');
+    expect(expression.rightBracket.lexeme, ']');
+    expect(expression.leftBracket.endGroup, expression.rightBracket);
   }
 
   void test_indexExpression_nullable_disabled() {
diff --git a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
index 60b0183..c743709 100644
--- a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
@@ -247,9 +247,9 @@
 
   void test_indexOperator_nullAware() {
     testRecovery('''
-f(x) => l?.[x
+f(x) => l?[x
 ''', [ScannerErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN], '''
-f(x) => l?.[x];
+f(x) => l?[x];
 ''',
         featureSet: FeatureSet.forTesting(
             sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]));
diff --git a/pkg/dart2native/bin/dart2native.dart b/pkg/dart2native/bin/dart2native.dart
index 57c6f21..6df0953 100644
--- a/pkg/dart2native/bin/dart2native.dart
+++ b/pkg/dart2native/bin/dart2native.dart
@@ -60,6 +60,10 @@
     ..addOption('save-debugging-info', abbr: 'S', valueHelp: 'path', help: '''
 Remove debugging information from the output and save it separately to the specified file. <path> can be relative or absolute.
 ''')
+    ..addOption('enable-experiment',
+        defaultsTo: '', valueHelp: 'feature', hide: true, help: '''
+Comma separated list of experimental features.
+''')
     ..addFlag('verbose',
         abbr: 'v', negatable: false, help: 'Show verbose output.');
 
@@ -99,6 +103,7 @@
         debugFile: parsedArgs['save-debugging-info'],
         packages: parsedArgs['packages'],
         defines: parsedArgs['define'],
+        enableExperiment: parsedArgs['enable-experiment'],
         enableAsserts: parsedArgs['enable-asserts'],
         verbose: parsedArgs['verbose'],
         extraOptions: parsedArgs['extra-gen-snapshot-options']);
diff --git a/pkg/dart2native/lib/dart2native.dart b/pkg/dart2native/lib/dart2native.dart
index 06aaeec..0139b24 100644
--- a/pkg/dart2native/lib/dart2native.dart
+++ b/pkg/dart2native/lib/dart2native.dart
@@ -39,11 +39,13 @@
 
 Future generateAotKernel(String dart, String genKernel, String platformDill,
     String sourceFile, String kernelFile, String packages, List<String> defines,
-    {List<String> extraGenKernelOptions = const []}) {
+    {String enableExperiment = '',
+    List<String> extraGenKernelOptions = const []}) {
   return Process.run(dart, [
     genKernel,
     '--platform',
     platformDill,
+    if (enableExperiment.isNotEmpty) '--enable-experiment=${enableExperiment}',
     '--aot',
     '-Ddart.vm.product=true',
     ...(defines.map((d) => '-D${d}')),
diff --git a/pkg/dart2native/lib/generate.dart b/pkg/dart2native/lib/generate.dart
index c4cbbcb..7ce1f9a2 100644
--- a/pkg/dart2native/lib/generate.dart
+++ b/pkg/dart2native/lib/generate.dart
@@ -24,6 +24,7 @@
   String debugFile,
   String packages,
   List<String> defines,
+  String enableExperiment = '',
   bool enableAsserts = false,
   bool verbose = false,
   List<String> extraOptions = const [],
@@ -52,7 +53,8 @@
 
     final String kernelFile = path.join(tempDir.path, 'kernel.dill');
     final kernelResult = await generateAotKernel(Platform.executable, genKernel,
-        productPlatformDill, sourcePath, kernelFile, packages, defines);
+        productPlatformDill, sourcePath, kernelFile, packages, defines,
+        enableExperiment: enableExperiment);
     if (kernelResult.exitCode != 0) {
       stderr.writeln(kernelResult.stdout);
       stderr.writeln(kernelResult.stderr);
diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart
index 2daa5f2..57e669a 100644
--- a/pkg/dartdev/test/commands/compile_test.dart
+++ b/pkg/dartdev/test/commands/compile_test.dart
@@ -56,10 +56,10 @@
         p.relativeFilePath,
       ],
     );
-    expect(File(outFile).existsSync(), true,
-        reason: 'File not found: $outFile');
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
+    expect(File(outFile).existsSync(), true,
+        reason: 'File not found: $outFile');
 
     result = p.runSync('run', ['main.jit']);
     expect(result.stdout, contains('I love jit'));
@@ -80,10 +80,10 @@
       ],
     );
 
-    expect(File(outFile).existsSync(), true,
-        reason: 'File not found: $outFile');
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
+    expect(File(outFile).existsSync(), true,
+        reason: 'File not found: $outFile');
 
     result = Process.runSync(
       outFile,
@@ -113,10 +113,10 @@
       ],
     );
 
-    expect(File(outFile).existsSync(), true,
-        reason: 'File not found: $outFile');
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
+    expect(File(outFile).existsSync(), true,
+        reason: 'File not found: $outFile');
 
     result = Process.runSync(
       outFile,
@@ -143,10 +143,10 @@
       ],
     );
 
-    expect(File(outFile).existsSync(), true,
-        reason: 'File not found: $outFile');
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
+    expect(File(outFile).existsSync(), true,
+        reason: 'File not found: $outFile');
 
     final Directory binDir = File(Platform.resolvedExecutable).parent;
     result = Process.runSync(
@@ -195,9 +195,9 @@
       '-v',
       inFile,
     ]);
-    expect(File(outFile).existsSync(), true,
-        reason: 'File not found: $outFile');
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
+    expect(File(outFile).existsSync(), true,
+        reason: 'File not found: $outFile');
   });
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 4610fe5..89ec09f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1763,6 +1763,10 @@
       } else if (left is Generator) {
         push(left.buildBinaryOperation(token, name, right));
       } else {
+        if (left is ProblemBuilder) {
+          ProblemBuilder problem = left;
+          left = buildProblem(problem.message, problem.charOffset, noLength);
+        }
         assert(left is Expression);
         push(forest.createBinary(fileOffset, left, name, right));
       }
@@ -3767,7 +3771,7 @@
     debugEvent("IndexedExpression");
     Expression index = popForValue();
     Object receiver = pop();
-    bool isNullAware = optional('?.[', openSquareBracket) || question != null;
+    bool isNullAware = question != null;
     if (isNullAware && !libraryBuilder.isNonNullableByDefault) {
       reportMissingNonNullableSupport(openSquareBracket);
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
index 734b8b4..ab6775c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -153,6 +153,8 @@
         Procedure procedure = stub;
         if (forMemberSignature) {
           procedure.isMemberSignature = true;
+          procedure.memberSignatureOrigin =
+              interfaceMember.memberSignatureOrigin ?? interfaceMember;
         } else {
           procedure.isForwardingStub = true;
         }
@@ -161,7 +163,9 @@
       if (interfaceMember.enclosingClass == enclosingClass) return;
       stub = _createForwardingStub(
           stubTypeParameters, substitution, interfaceMember,
-          forMemberSignature: forMemberSignature);
+          memberSignatureTarget: forMemberSignature
+              ? interfaceMember.memberSignatureOrigin ?? interfaceMember
+              : null);
     }
 
     bool isImplCreated = false;
@@ -409,6 +413,11 @@
       createStubIfNeeded(forMemberSignature: true);
       stub.function.returnType = type;
     }
+    assert(
+        !(stub is Procedure &&
+            (stub as Procedure).isMemberSignature &&
+            stub.memberSignatureOrigin == null),
+        "No member signature origin for member signature $stub.");
     return stub;
   }
 
@@ -477,7 +486,7 @@
   /// Creates a forwarding stub based on the given [target].
   Procedure _createForwardingStub(List<TypeParameter> typeParameters,
       Substitution substitution, Member target,
-      {bool forMemberSignature: false}) {
+      {Member memberSignatureTarget}) {
     VariableDeclaration copyParameter(VariableDeclaration parameter) {
       return new VariableDeclaration(parameter.name,
           type: substitution.substituteType(parameter.type),
@@ -533,11 +542,12 @@
     }
     return new Procedure(name, kind, function,
         isAbstract: true,
-        isForwardingStub: !forMemberSignature,
-        isMemberSignature: forMemberSignature,
+        isForwardingStub: memberSignatureTarget == null,
+        isMemberSignature: memberSignatureTarget != null,
         fileUri: enclosingClass.fileUri,
         forwardingStubInterfaceTarget: finalTarget,
-        reference: referenceFrom?.reference)
+        reference: referenceFrom?.reference,
+        memberSignatureOrigin: memberSignatureTarget)
       ..startFileOffset = enclosingClass.fileOffset
       ..fileOffset = enclosingClass.fileOffset
       ..parent = enclosingClass
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart
index e00ed60..4bdda9a 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart
@@ -1,4 +1,6 @@
 main() {
   var c;
   c?.[1] = 42;
+  c?[1] = 42;
+  c ? [1] = 42;
 }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.expect
index fa7ddf9..7646da2 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.expect
@@ -20,15 +20,35 @@
           endInitializedIdentifier(c)
         endVariablesDeclaration(1, ;)
         handleIdentifier(c, expression)
-        handleNoTypeArguments(?.[)
-        handleNoArguments(?.[)
-        handleSend(c, ?.[)
+        handleNoTypeArguments(?.)
+        handleNoArguments(?.)
+        handleSend(c, ?.)
+        handleNoTypeArguments([)
         handleLiteralInt(1)
-        handleIndexedExpression(null, ?.[, ])
+        handleLiteralList(1, [, null, ])
+        endBinaryExpression(?.)
         handleLiteralInt(42)
         handleAssignmentExpression(=)
         handleExpressionStatement(;)
-      endBlockFunctionBody(2, {, })
+        handleIdentifier(c, expression)
+        handleNoTypeArguments(?)
+        handleNoArguments(?)
+        handleSend(c, ?)
+        handleLiteralInt(1)
+        handleIndexedExpression(?, [, ])
+        handleLiteralInt(42)
+        handleAssignmentExpression(=)
+        handleExpressionStatement(;)
+        handleIdentifier(c, expression)
+        handleNoTypeArguments(?)
+        handleNoArguments(?)
+        handleSend(c, ?)
+        handleLiteralInt(1)
+        handleIndexedExpression(?, [, ])
+        handleLiteralInt(42)
+        handleAssignmentExpression(=)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(4, {, })
     endTopLevelMethod(main, null, })
   endTopLevelDeclaration()
 endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.intertwined.expect
index 1368e76..2acd198 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.intertwined.expect
@@ -59,18 +59,119 @@
                             parseSend(;, expression)
                               ensureIdentifier(;, expression)
                                 listener: handleIdentifier(c, expression)
-                              listener: handleNoTypeArguments(?.[)
+                              listener: handleNoTypeArguments(?.)
                               parseArgumentsOpt(c)
-                                listener: handleNoArguments(?.[)
-                              listener: handleSend(c, ?.[)
-                      parseArgumentOrIndexStar(c, Instance of 'NoTypeParamOrArg', false)
-                        parseExpression(?.[)
-                          parsePrecedenceExpression(?.[, 1, true)
-                            parseUnaryExpression(?.[, true)
-                              parsePrimary(?.[, expression)
-                                parseLiteralInt(?.[)
+                                listener: handleNoArguments(?.)
+                              listener: handleSend(c, ?.)
+                      parsePrimary(?., expressionContinuation)
+                        listener: handleNoTypeArguments([)
+                        parseLiteralListSuffix(?., null)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseLiteralInt([)
+                                    listener: handleLiteralInt(1)
+                          listener: handleLiteralList(1, [, null, ])
+                      listener: endBinaryExpression(?.)
+                      parsePrecedenceExpression(=, 1, true)
+                        parseUnaryExpression(=, true)
+                          parsePrimary(=, expression)
+                            parseLiteralInt(=)
+                              listener: handleLiteralInt(42)
+                      listener: handleAssignmentExpression(=)
+                  ensureSemicolon(42)
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, c)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(c)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(c, expression)
+                              listener: handleNoTypeArguments(?)
+                              parseArgumentsOpt(c)
+                                listener: handleNoArguments(?)
+                              listener: handleSend(c, ?)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralInt([)
+                            parsePrecedenceExpression(=, 1, false)
+                              parseUnaryExpression(=, false)
+                                parsePrimary(=, expression)
+                                  parseLiteralInt(=)
+                      parseArgumentOrIndexStar(c, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralInt([)
                                   listener: handleLiteralInt(1)
-                        listener: handleIndexedExpression(null, ?.[, ])
+                        listener: handleIndexedExpression(?, [, ])
+                      parsePrecedenceExpression(=, 1, true)
+                        parseUnaryExpression(=, true)
+                          parsePrimary(=, expression)
+                            parseLiteralInt(=)
+                              listener: handleLiteralInt(42)
+                      listener: handleAssignmentExpression(=)
+                  ensureSemicolon(42)
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, c)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(c)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(c, expression)
+                              listener: handleNoTypeArguments(?)
+                              parseArgumentsOpt(c)
+                                listener: handleNoArguments(?)
+                              listener: handleSend(c, ?)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralInt([)
+                            parsePrecedenceExpression(=, 1, false)
+                              parseUnaryExpression(=, false)
+                                parsePrimary(=, expression)
+                                  parseLiteralInt(=)
+                      parseArgumentOrIndexStar(c, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralInt([)
+                                  listener: handleLiteralInt(1)
+                        listener: handleIndexedExpression(?, [, ])
                       parsePrecedenceExpression(=, 1, true)
                         parseUnaryExpression(=, true)
                           parsePrimary(=, expression)
@@ -80,7 +181,7 @@
                   ensureSemicolon(42)
                   listener: handleExpressionStatement(;)
           notEofOrValue(}, })
-          listener: endBlockFunctionBody(2, {, })
+          listener: endBlockFunctionBody(4, {, })
         listener: endTopLevelMethod(main, null, })
   listener: endTopLevelDeclaration()
   reportAllErrorTokens(main)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.parser.expect b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.parser.expect
index 0eb00a3..7eb4a63 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.parser.expect
@@ -1,9 +1,13 @@
 main() {
 var c;
 c?.[1] = 42;
+c?[1] = 42;
+c ? [1] = 42;
 }
 
 main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 var[KeywordToken] c[StringToken];[SimpleToken]
-c[StringToken]?.[[BeginToken]1[StringToken]][SimpleToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+c[StringToken]?.[SimpleToken][[BeginToken]1[StringToken]][SimpleToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+c[StringToken]?[SimpleToken][[BeginToken]1[StringToken]][SimpleToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+c[StringToken] ?[SimpleToken] [[BeginToken]1[StringToken]][SimpleToken] =[SimpleToken] 42[StringToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.scanner.expect b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.scanner.expect
index 0eb00a3..7eb4a63 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39326.dart.scanner.expect
@@ -1,9 +1,13 @@
 main() {
 var c;
 c?.[1] = 42;
+c?[1] = 42;
+c ? [1] = 42;
 }
 
 main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 var[KeywordToken] c[StringToken];[SimpleToken]
-c[StringToken]?.[[BeginToken]1[StringToken]][SimpleToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+c[StringToken]?.[SimpleToken][[BeginToken]1[StringToken]][SimpleToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+c[StringToken]?[SimpleToken][[BeginToken]1[StringToken]][SimpleToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+c[StringToken] ?[SimpleToken] [[BeginToken]1[StringToken]][SimpleToken] =[SimpleToken] 42[StringToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart
index adcde78..e516099 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart
@@ -6,4 +6,6 @@
   A? a = null;
   a!?.toString();
   a!?.[42];
+  a!?[42];
+  a! ? [42];
 }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.expect
index 77065a5..27c1185 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.expect
@@ -82,10 +82,28 @@
         handleNoArguments(!)
         handleSend(a, !)
         handleNonNullAssertExpression(!)
+        handleNoTypeArguments([)
         handleLiteralInt(42)
-        handleIndexedExpression(null, ?.[, ])
+        handleLiteralList(1, [, null, ])
+        endBinaryExpression(?.)
         handleExpressionStatement(;)
-      endBlockFunctionBody(3, {, })
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(a, !)
+        handleNonNullAssertExpression(!)
+        handleLiteralInt(42)
+        handleIndexedExpression(?, [, ])
+        handleExpressionStatement(;)
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(a, !)
+        handleNonNullAssertExpression(!)
+        handleLiteralInt(42)
+        handleIndexedExpression(?, [, ])
+        handleExpressionStatement(;)
+      endBlockFunctionBody(5, {, })
     endTopLevelMethod(main, null, })
   endTopLevelDeclaration()
 endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.intertwined.expect
index 183b237..1b89b04 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.intertwined.expect
@@ -196,18 +196,101 @@
                                 listener: handleNoArguments(!)
                               listener: handleSend(a, !)
                       listener: handleNonNullAssertExpression(!)
-                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg', false)
-                        parseExpression(?.[)
-                          parsePrecedenceExpression(?.[, 1, true)
-                            parseUnaryExpression(?.[, true)
-                              parsePrimary(?.[, expression)
-                                parseLiteralInt(?.[)
+                      parsePrimary(?., expressionContinuation)
+                        listener: handleNoTypeArguments([)
+                        parseLiteralListSuffix(?., null)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseLiteralInt([)
+                                    listener: handleLiteralInt(42)
+                          listener: handleLiteralList(1, [, null, ])
+                      listener: endBinaryExpression(?.)
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, a)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(a)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(a, !)
+                      listener: handleNonNullAssertExpression(!)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralInt([)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralInt([)
                                   listener: handleLiteralInt(42)
-                        listener: handleIndexedExpression(null, ?.[, ])
+                        listener: handleIndexedExpression(?, [, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, a)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(a)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(a, !)
+                      listener: handleNonNullAssertExpression(!)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralInt([)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralInt([)
+                                  listener: handleLiteralInt(42)
+                        listener: handleIndexedExpression(?, [, ])
                   ensureSemicolon(])
                   listener: handleExpressionStatement(;)
           notEofOrValue(}, })
-          listener: endBlockFunctionBody(3, {, })
+          listener: endBlockFunctionBody(5, {, })
         listener: endTopLevelMethod(main, null, })
   listener: endTopLevelDeclaration()
   reportAllErrorTokens(class)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.parser.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.parser.expect
index c96c7d4..5c1660425 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.parser.expect
@@ -6,6 +6,8 @@
 A? a = null;
 a!?.toString();
 a!?.[42];
+a!?[42];
+a! ? [42];
 }
 
 class[KeywordToken] A[StringToken] {[BeginToken]
@@ -15,5 +17,7 @@
 main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 A[StringToken]?[SimpleToken] a[StringToken] =[SimpleToken] null[KeywordToken];[SimpleToken]
 a[StringToken]![SimpleToken]?.[SimpleToken]toString[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
-a[StringToken]![SimpleToken]?.[[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken]![SimpleToken]?.[SimpleToken][[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken]![SimpleToken]?[SimpleToken][[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken]![SimpleToken] ?[SimpleToken] [[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.scanner.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.scanner.expect
index c96c7d4..5c1660425 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723.dart.scanner.expect
@@ -6,6 +6,8 @@
 A? a = null;
 a!?.toString();
 a!?.[42];
+a!?[42];
+a! ? [42];
 }
 
 class[KeywordToken] A[StringToken] {[BeginToken]
@@ -15,5 +17,7 @@
 main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 A[StringToken]?[SimpleToken] a[StringToken] =[SimpleToken] null[KeywordToken];[SimpleToken]
 a[StringToken]![SimpleToken]?.[SimpleToken]toString[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
-a[StringToken]![SimpleToken]?.[[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken]![SimpleToken]?.[SimpleToken][[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken]![SimpleToken]?[SimpleToken][[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken]![SimpleToken] ?[SimpleToken] [[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart
index 8816337..1d19f21 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart
@@ -6,4 +6,6 @@
   A? a = null;
   (a!)?.toString();
   (a!)?.[42];
+  (a!)?[42];
+  (a!) ? [42];
 }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.expect
index 31909ba..c08e774 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.expect
@@ -84,10 +84,30 @@
         handleSend(a, !)
         handleNonNullAssertExpression(!)
         handleParenthesizedExpression(()
+        handleNoTypeArguments([)
         handleLiteralInt(42)
-        handleIndexedExpression(null, ?.[, ])
+        handleLiteralList(1, [, null, ])
+        endBinaryExpression(?.)
         handleExpressionStatement(;)
-      endBlockFunctionBody(3, {, })
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(a, !)
+        handleNonNullAssertExpression(!)
+        handleParenthesizedExpression(()
+        handleLiteralInt(42)
+        handleIndexedExpression(?, [, ])
+        handleExpressionStatement(;)
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(a, !)
+        handleNonNullAssertExpression(!)
+        handleParenthesizedExpression(()
+        handleLiteralInt(42)
+        handleIndexedExpression(?, [, ])
+        handleExpressionStatement(;)
+      endBlockFunctionBody(5, {, })
     endTopLevelMethod(main, null, })
   endTopLevelDeclaration()
 endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
index 3af8393..4ef31d6 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.intertwined.expect
@@ -218,18 +218,123 @@
                                         listener: handleNonNullAssertExpression(!)
                                     ensureCloseParen(!, ()
                                 listener: handleParenthesizedExpression(()
-                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg', false)
-                          parseExpression(?.[)
-                            parsePrecedenceExpression(?.[, 1, true)
-                              parseUnaryExpression(?.[, true)
-                                parsePrimary(?.[, expression)
-                                  parseLiteralInt(?.[)
+                        parsePrimary(?., expressionContinuation)
+                          listener: handleNoTypeArguments([)
+                          parseLiteralListSuffix(?., null)
+                            parseExpression([)
+                              parsePrecedenceExpression([, 1, true)
+                                parseUnaryExpression([, true)
+                                  parsePrimary([, expression)
+                                    parseLiteralInt([)
+                                      listener: handleLiteralInt(42)
+                            listener: handleLiteralList(1, [, null, ])
+                        listener: endBinaryExpression(?.)
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(;)
+                              parseParenthesizedExpression(;)
+                                parseExpressionInParenthesis(;)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(a, expression)
+                                                listener: handleNoTypeArguments(!)
+                                                parseArgumentsOpt(a)
+                                                  listener: handleNoArguments(!)
+                                                listener: handleSend(a, !)
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        canParseAsConditional(?)
+                          parseExpressionWithoutCascade(?)
+                            parsePrecedenceExpression(?, 1, false)
+                              parseUnaryExpression(?, false)
+                                parsePrimary(?, expression)
+                                  parseLiteralListSuffix(?, null)
+                                    parseExpression([)
+                                      parsePrecedenceExpression([, 1, true)
+                                        parseUnaryExpression([, true)
+                                          parsePrimary([, expression)
+                                            parseLiteralInt([)
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg', true)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseLiteralInt([)
                                     listener: handleLiteralInt(42)
-                          listener: handleIndexedExpression(null, ?.[, ])
+                          listener: handleIndexedExpression(?, [, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, ()
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclaration(;, false)
+                parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement(;)
+                    parseExpression(;)
+                      parsePrecedenceExpression(;, 1, true)
+                        parseUnaryExpression(;, true)
+                          parsePrimary(;, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral(;)
+                              parseParenthesizedExpression(;)
+                                parseExpressionInParenthesis(;)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(a, expression)
+                                                listener: handleNoTypeArguments(!)
+                                                parseArgumentsOpt(a)
+                                                  listener: handleNoArguments(!)
+                                                listener: handleSend(a, !)
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        canParseAsConditional(?)
+                          parseExpressionWithoutCascade(?)
+                            parsePrecedenceExpression(?, 1, false)
+                              parseUnaryExpression(?, false)
+                                parsePrimary(?, expression)
+                                  parseLiteralListSuffix(?, null)
+                                    parseExpression([)
+                                      parsePrecedenceExpression([, 1, true)
+                                        parseUnaryExpression([, true)
+                                          parsePrimary([, expression)
+                                            parseLiteralInt([)
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg', true)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseLiteralInt([)
+                                    listener: handleLiteralInt(42)
+                          listener: handleIndexedExpression(?, [, ])
                     ensureSemicolon(])
                     listener: handleExpressionStatement(;)
           notEofOrValue(}, })
-          listener: endBlockFunctionBody(3, {, })
+          listener: endBlockFunctionBody(5, {, })
         listener: endTopLevelMethod(main, null, })
   listener: endTopLevelDeclaration()
   reportAllErrorTokens(class)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.parser.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.parser.expect
index e7e8cb1..6b80e88 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.parser.expect
@@ -6,6 +6,8 @@
 A? a = null;
 (a!)?.toString();
 (a!)?.[42];
+(a!)?[42];
+(a!) ? [42];
 }
 
 class[KeywordToken] A[StringToken] {[BeginToken]
@@ -15,5 +17,7 @@
 main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 A[StringToken]?[SimpleToken] a[StringToken] =[SimpleToken] null[KeywordToken];[SimpleToken]
 ([BeginToken]a[StringToken]![SimpleToken])[SimpleToken]?.[SimpleToken]toString[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
-([BeginToken]a[StringToken]![SimpleToken])[SimpleToken]?.[[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+([BeginToken]a[StringToken]![SimpleToken])[SimpleToken]?.[SimpleToken][[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+([BeginToken]a[StringToken]![SimpleToken])[SimpleToken]?[SimpleToken][[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+([BeginToken]a[StringToken]![SimpleToken])[SimpleToken] ?[SimpleToken] [[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.scanner.expect b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.scanner.expect
index e7e8cb1..6b80e88 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_39723_prime.dart.scanner.expect
@@ -6,6 +6,8 @@
 A? a = null;
 (a!)?.toString();
 (a!)?.[42];
+(a!)?[42];
+(a!) ? [42];
 }
 
 class[KeywordToken] A[StringToken] {[BeginToken]
@@ -15,5 +17,7 @@
 main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 A[StringToken]?[SimpleToken] a[StringToken] =[SimpleToken] null[KeywordToken];[SimpleToken]
 ([BeginToken]a[StringToken]![SimpleToken])[SimpleToken]?.[SimpleToken]toString[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
-([BeginToken]a[StringToken]![SimpleToken])[SimpleToken]?.[[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+([BeginToken]a[StringToken]![SimpleToken])[SimpleToken]?.[SimpleToken][[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+([BeginToken]a[StringToken]![SimpleToken])[SimpleToken]?[SimpleToken][[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
+([BeginToken]a[StringToken]![SimpleToken])[SimpleToken] ?[SimpleToken] [[BeginToken]42[StringToken]][SimpleToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart
index 047f2d2..f16df40 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart
@@ -2,4 +2,5 @@
   var a, b;
   a?.[b];
   a?[b];
+  a ? [b];
 }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.expect
index 3c6833e..760e325 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.expect
@@ -24,14 +24,16 @@
           endInitializedIdentifier(b)
         endVariablesDeclaration(2, ;)
         handleIdentifier(a, expression)
-        handleNoTypeArguments(?.[)
-        handleNoArguments(?.[)
-        handleSend(a, ?.[)
+        handleNoTypeArguments(?.)
+        handleNoArguments(?.)
+        handleSend(a, ?.)
+        handleNoTypeArguments([)
         handleIdentifier(b, expression)
         handleNoTypeArguments(])
         handleNoArguments(])
         handleSend(b, ])
-        handleIndexedExpression(null, ?.[, ])
+        handleLiteralList(1, [, null, ])
+        endBinaryExpression(?.)
         handleExpressionStatement(;)
         handleIdentifier(a, expression)
         handleNoTypeArguments(?)
@@ -43,7 +45,17 @@
         handleSend(b, ])
         handleIndexedExpression(?, [, ])
         handleExpressionStatement(;)
-      endBlockFunctionBody(3, {, })
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(?)
+        handleNoArguments(?)
+        handleSend(a, ?)
+        handleIdentifier(b, expression)
+        handleNoTypeArguments(])
+        handleNoArguments(])
+        handleSend(b, ])
+        handleIndexedExpression(?, [, ])
+        handleExpressionStatement(;)
+      endBlockFunctionBody(4, {, })
     endTopLevelMethod(f, null, })
   endTopLevelDeclaration()
 endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.intertwined.expect
index da5c160..45d26ab 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.intertwined.expect
@@ -66,24 +66,75 @@
                             parseSend(;, expression)
                               ensureIdentifier(;, expression)
                                 listener: handleIdentifier(a, expression)
-                              listener: handleNoTypeArguments(?.[)
+                              listener: handleNoTypeArguments(?.)
                               parseArgumentsOpt(a)
-                                listener: handleNoArguments(?.[)
-                              listener: handleSend(a, ?.[)
-                      parseArgumentOrIndexStar(a, Instance of 'NoTypeParamOrArg', false)
-                        parseExpression(?.[)
-                          parsePrecedenceExpression(?.[, 1, true)
-                            parseUnaryExpression(?.[, true)
-                              parsePrimary(?.[, expression)
-                                parseSendOrFunctionLiteral(?.[, expression)
-                                  parseSend(?.[, expression)
-                                    ensureIdentifier(?.[, expression)
+                                listener: handleNoArguments(?.)
+                              listener: handleSend(a, ?.)
+                      parsePrimary(?., expressionContinuation)
+                        listener: handleNoTypeArguments([)
+                        parseLiteralListSuffix(?., null)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(b, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(b)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(b, ])
+                          listener: handleLiteralList(1, [, null, ])
+                      listener: endBinaryExpression(?.)
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, a)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(?)
+                              parseArgumentsOpt(a)
+                                listener: handleNoArguments(?)
+                              listener: handleSend(a, ?)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseSendOrFunctionLiteral([, expression)
+                                            parseSend([, expression)
+                                              ensureIdentifier([, expression)
+                                              parseArgumentsOpt(b)
+                      parseArgumentOrIndexStar(a, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
                                       listener: handleIdentifier(b, expression)
                                     listener: handleNoTypeArguments(])
                                     parseArgumentsOpt(b)
                                       listener: handleNoArguments(])
                                     listener: handleSend(b, ])
-                        listener: handleIndexedExpression(null, ?.[, ])
+                        listener: handleIndexedExpression(?, [, ])
                   ensureSemicolon(])
                   listener: handleExpressionStatement(;)
           notEofOrValue(}, a)
@@ -135,7 +186,7 @@
                   ensureSemicolon(])
                   listener: handleExpressionStatement(;)
           notEofOrValue(}, })
-          listener: endBlockFunctionBody(3, {, })
+          listener: endBlockFunctionBody(4, {, })
         listener: endTopLevelMethod(f, null, })
   listener: endTopLevelDeclaration()
   reportAllErrorTokens(f)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.parser.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.parser.expect
index 8504155..b3ccd89 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.parser.expect
@@ -2,10 +2,12 @@
 var a, b;
 a?.[b];
 a?[b];
+a ? [b];
 }
 
 f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 var[KeywordToken] a[StringToken],[SimpleToken] b[StringToken];[SimpleToken]
-a[StringToken]?.[[BeginToken]b[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken]?.[SimpleToken][[BeginToken]b[StringToken]][SimpleToken];[SimpleToken]
 a[StringToken]?[SimpleToken][[BeginToken]b[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken] ?[SimpleToken] [[BeginToken]b[StringToken]][SimpleToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.scanner.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.scanner.expect
index 8504155..b3ccd89 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_access.dart.scanner.expect
@@ -2,10 +2,12 @@
 var a, b;
 a?.[b];
 a?[b];
+a ? [b];
 }
 
 f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 var[KeywordToken] a[StringToken],[SimpleToken] b[StringToken];[SimpleToken]
-a[StringToken]?.[[BeginToken]b[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken]?.[SimpleToken][[BeginToken]b[StringToken]][SimpleToken];[SimpleToken]
 a[StringToken]?[SimpleToken][[BeginToken]b[StringToken]][SimpleToken];[SimpleToken]
+a[StringToken] ?[SimpleToken] [[BeginToken]b[StringToken]][SimpleToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart
index a067938..dd57bcf 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart
@@ -2,4 +2,5 @@
   var a, b, c;
   a?.[b] = c;
   a?[b] = c;
+  a ? [b] = c;
 }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.expect
index 32e3968..e9a9536 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.expect
@@ -28,14 +28,16 @@
           endInitializedIdentifier(c)
         endVariablesDeclaration(3, ;)
         handleIdentifier(a, expression)
-        handleNoTypeArguments(?.[)
-        handleNoArguments(?.[)
-        handleSend(a, ?.[)
+        handleNoTypeArguments(?.)
+        handleNoArguments(?.)
+        handleSend(a, ?.)
+        handleNoTypeArguments([)
         handleIdentifier(b, expression)
         handleNoTypeArguments(])
         handleNoArguments(])
         handleSend(b, ])
-        handleIndexedExpression(null, ?.[, ])
+        handleLiteralList(1, [, null, ])
+        endBinaryExpression(?.)
         handleIdentifier(c, expression)
         handleNoTypeArguments(;)
         handleNoArguments(;)
@@ -57,7 +59,22 @@
         handleSend(c, ;)
         handleAssignmentExpression(=)
         handleExpressionStatement(;)
-      endBlockFunctionBody(3, {, })
+        handleIdentifier(a, expression)
+        handleNoTypeArguments(?)
+        handleNoArguments(?)
+        handleSend(a, ?)
+        handleIdentifier(b, expression)
+        handleNoTypeArguments(])
+        handleNoArguments(])
+        handleSend(b, ])
+        handleIndexedExpression(?, [, ])
+        handleIdentifier(c, expression)
+        handleNoTypeArguments(;)
+        handleNoArguments(;)
+        handleSend(c, ;)
+        handleAssignmentExpression(=)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(4, {, })
     endTopLevelMethod(f, null, })
   endTopLevelDeclaration()
 endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.intertwined.expect
index 05def0c..30dbcff 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.intertwined.expect
@@ -73,24 +73,94 @@
                             parseSend(;, expression)
                               ensureIdentifier(;, expression)
                                 listener: handleIdentifier(a, expression)
-                              listener: handleNoTypeArguments(?.[)
+                              listener: handleNoTypeArguments(?.)
                               parseArgumentsOpt(a)
-                                listener: handleNoArguments(?.[)
-                              listener: handleSend(a, ?.[)
-                      parseArgumentOrIndexStar(a, Instance of 'NoTypeParamOrArg', false)
-                        parseExpression(?.[)
-                          parsePrecedenceExpression(?.[, 1, true)
-                            parseUnaryExpression(?.[, true)
-                              parsePrimary(?.[, expression)
-                                parseSendOrFunctionLiteral(?.[, expression)
-                                  parseSend(?.[, expression)
-                                    ensureIdentifier(?.[, expression)
+                                listener: handleNoArguments(?.)
+                              listener: handleSend(a, ?.)
+                      parsePrimary(?., expressionContinuation)
+                        listener: handleNoTypeArguments([)
+                        parseLiteralListSuffix(?., null)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(b, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(b)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(b, ])
+                          listener: handleLiteralList(1, [, null, ])
+                      listener: endBinaryExpression(?.)
+                      parsePrecedenceExpression(=, 1, true)
+                        parseUnaryExpression(=, true)
+                          parsePrimary(=, expression)
+                            parseSendOrFunctionLiteral(=, expression)
+                              parseSend(=, expression)
+                                ensureIdentifier(=, expression)
+                                  listener: handleIdentifier(c, expression)
+                                listener: handleNoTypeArguments(;)
+                                parseArgumentsOpt(c)
+                                  listener: handleNoArguments(;)
+                                listener: handleSend(c, ;)
+                      listener: handleAssignmentExpression(=)
+                  ensureSemicolon(c)
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, a)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(a)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(a, expression)
+                              listener: handleNoTypeArguments(?)
+                              parseArgumentsOpt(a)
+                                listener: handleNoArguments(?)
+                              listener: handleSend(a, ?)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseSendOrFunctionLiteral([, expression)
+                                            parseSend([, expression)
+                                              ensureIdentifier([, expression)
+                                              parseArgumentsOpt(b)
+                            parsePrecedenceExpression(=, 1, false)
+                              parseUnaryExpression(=, false)
+                                parsePrimary(=, expression)
+                                  parseSendOrFunctionLiteral(=, expression)
+                                    parseSend(=, expression)
+                                      ensureIdentifier(=, expression)
+                                      parseArgumentsOpt(c)
+                      parseArgumentOrIndexStar(a, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
                                       listener: handleIdentifier(b, expression)
                                     listener: handleNoTypeArguments(])
                                     parseArgumentsOpt(b)
                                       listener: handleNoArguments(])
                                     listener: handleSend(b, ])
-                        listener: handleIndexedExpression(null, ?.[, ])
+                        listener: handleIndexedExpression(?, [, ])
                       parsePrecedenceExpression(=, 1, true)
                         parseUnaryExpression(=, true)
                           parsePrimary(=, expression)
@@ -173,7 +243,7 @@
                   ensureSemicolon(c)
                   listener: handleExpressionStatement(;)
           notEofOrValue(}, })
-          listener: endBlockFunctionBody(3, {, })
+          listener: endBlockFunctionBody(4, {, })
         listener: endTopLevelMethod(f, null, })
   listener: endTopLevelDeclaration()
   reportAllErrorTokens(f)
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.parser.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.parser.expect
index f8e7918..e0c4737 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.parser.expect
@@ -2,10 +2,12 @@
 var a, b, c;
 a?.[b] = c;
 a?[b] = c;
+a ? [b] = c;
 }
 
 f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 var[KeywordToken] a[StringToken],[SimpleToken] b[StringToken],[SimpleToken] c[StringToken];[SimpleToken]
-a[StringToken]?.[[BeginToken]b[StringToken]][SimpleToken] =[SimpleToken] c[StringToken];[SimpleToken]
+a[StringToken]?.[SimpleToken][[BeginToken]b[StringToken]][SimpleToken] =[SimpleToken] c[StringToken];[SimpleToken]
 a[StringToken]?[SimpleToken][[BeginToken]b[StringToken]][SimpleToken] =[SimpleToken] c[StringToken];[SimpleToken]
+a[StringToken] ?[SimpleToken] [[BeginToken]b[StringToken]][SimpleToken] =[SimpleToken] c[StringToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.scanner.expect b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.scanner.expect
index f8e7918..e0c4737 100644
--- a/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/nnbd/issue_40267_index_set.dart.scanner.expect
@@ -2,10 +2,12 @@
 var a, b, c;
 a?.[b] = c;
 a?[b] = c;
+a ? [b] = c;
 }
 
 f[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 var[KeywordToken] a[StringToken],[SimpleToken] b[StringToken],[SimpleToken] c[StringToken];[SimpleToken]
-a[StringToken]?.[[BeginToken]b[StringToken]][SimpleToken] =[SimpleToken] c[StringToken];[SimpleToken]
+a[StringToken]?.[SimpleToken][[BeginToken]b[StringToken]][SimpleToken] =[SimpleToken] c[StringToken];[SimpleToken]
 a[StringToken]?[SimpleToken][[BeginToken]b[StringToken]][SimpleToken] =[SimpleToken] c[StringToken];[SimpleToken]
+a[StringToken] ?[SimpleToken] [[BeginToken]b[StringToken]][SimpleToken] =[SimpleToken] c[StringToken];[SimpleToken]
 }[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart
index 66d340e..28a5a2b 100644
--- a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart
+++ b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart
@@ -11,4 +11,10 @@
   Class1? c1;
   c1?.[0];
   c1?.[0] = 1;
+
+  c1?[0];
+  c1?[0] = 1;
+
+  c1 ? [0];
+  c1 ? [0] = 1;
 }
diff --git a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.expect b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.expect
index b5fe182..f9edc0e 100644
--- a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.expect
+++ b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.expect
@@ -99,22 +99,58 @@
           endInitializedIdentifier(c1)
         endVariablesDeclaration(1, ;)
         handleIdentifier(c1, expression)
-        handleNoTypeArguments(?.[)
-        handleNoArguments(?.[)
-        handleSend(c1, ?.[)
+        handleNoTypeArguments(?.)
+        handleNoArguments(?.)
+        handleSend(c1, ?.)
+        handleNoTypeArguments([)
         handleLiteralInt(0)
-        handleIndexedExpression(null, ?.[, ])
+        handleLiteralList(1, [, null, ])
+        endBinaryExpression(?.)
         handleExpressionStatement(;)
         handleIdentifier(c1, expression)
-        handleNoTypeArguments(?.[)
-        handleNoArguments(?.[)
-        handleSend(c1, ?.[)
+        handleNoTypeArguments(?.)
+        handleNoArguments(?.)
+        handleSend(c1, ?.)
+        handleNoTypeArguments([)
         handleLiteralInt(0)
-        handleIndexedExpression(null, ?.[, ])
+        handleLiteralList(1, [, null, ])
+        endBinaryExpression(?.)
         handleLiteralInt(1)
         handleAssignmentExpression(=)
         handleExpressionStatement(;)
-      endBlockFunctionBody(3, {, })
+        handleIdentifier(c1, expression)
+        handleNoTypeArguments(?)
+        handleNoArguments(?)
+        handleSend(c1, ?)
+        handleLiteralInt(0)
+        handleIndexedExpression(?, [, ])
+        handleExpressionStatement(;)
+        handleIdentifier(c1, expression)
+        handleNoTypeArguments(?)
+        handleNoArguments(?)
+        handleSend(c1, ?)
+        handleLiteralInt(0)
+        handleIndexedExpression(?, [, ])
+        handleLiteralInt(1)
+        handleAssignmentExpression(=)
+        handleExpressionStatement(;)
+        handleIdentifier(c1, expression)
+        handleNoTypeArguments(?)
+        handleNoArguments(?)
+        handleSend(c1, ?)
+        handleLiteralInt(0)
+        handleIndexedExpression(?, [, ])
+        handleExpressionStatement(;)
+        handleIdentifier(c1, expression)
+        handleNoTypeArguments(?)
+        handleNoArguments(?)
+        handleSend(c1, ?)
+        handleLiteralInt(0)
+        handleIndexedExpression(?, [, ])
+        handleLiteralInt(1)
+        handleAssignmentExpression(=)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(7, {, })
     endTopLevelMethod(main, null, })
   endTopLevelDeclaration()
 endCompilationUnit(2, )
diff --git a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.intertwined.expect
index 2a6ddba..39fda9b 100644
--- a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.intertwined.expect
@@ -200,18 +200,21 @@
                             parseSend(;, expression)
                               ensureIdentifier(;, expression)
                                 listener: handleIdentifier(c1, expression)
-                              listener: handleNoTypeArguments(?.[)
+                              listener: handleNoTypeArguments(?.)
                               parseArgumentsOpt(c1)
-                                listener: handleNoArguments(?.[)
-                              listener: handleSend(c1, ?.[)
-                      parseArgumentOrIndexStar(c1, Instance of 'NoTypeParamOrArg', false)
-                        parseExpression(?.[)
-                          parsePrecedenceExpression(?.[, 1, true)
-                            parseUnaryExpression(?.[, true)
-                              parsePrimary(?.[, expression)
-                                parseLiteralInt(?.[)
-                                  listener: handleLiteralInt(0)
-                        listener: handleIndexedExpression(null, ?.[, ])
+                                listener: handleNoArguments(?.)
+                              listener: handleSend(c1, ?.)
+                      parsePrimary(?., expressionContinuation)
+                        listener: handleNoTypeArguments([)
+                        parseLiteralListSuffix(?., null)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseLiteralInt([)
+                                    listener: handleLiteralInt(0)
+                          listener: handleLiteralList(1, [, null, ])
+                      listener: endBinaryExpression(?.)
                   ensureSemicolon(])
                   listener: handleExpressionStatement(;)
           notEofOrValue(}, c1)
@@ -228,18 +231,197 @@
                             parseSend(;, expression)
                               ensureIdentifier(;, expression)
                                 listener: handleIdentifier(c1, expression)
-                              listener: handleNoTypeArguments(?.[)
+                              listener: handleNoTypeArguments(?.)
                               parseArgumentsOpt(c1)
-                                listener: handleNoArguments(?.[)
-                              listener: handleSend(c1, ?.[)
-                      parseArgumentOrIndexStar(c1, Instance of 'NoTypeParamOrArg', false)
-                        parseExpression(?.[)
-                          parsePrecedenceExpression(?.[, 1, true)
-                            parseUnaryExpression(?.[, true)
-                              parsePrimary(?.[, expression)
-                                parseLiteralInt(?.[)
+                                listener: handleNoArguments(?.)
+                              listener: handleSend(c1, ?.)
+                      parsePrimary(?., expressionContinuation)
+                        listener: handleNoTypeArguments([)
+                        parseLiteralListSuffix(?., null)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseLiteralInt([)
+                                    listener: handleLiteralInt(0)
+                          listener: handleLiteralList(1, [, null, ])
+                      listener: endBinaryExpression(?.)
+                      parsePrecedenceExpression(=, 1, true)
+                        parseUnaryExpression(=, true)
+                          parsePrimary(=, expression)
+                            parseLiteralInt(=)
+                              listener: handleLiteralInt(1)
+                      listener: handleAssignmentExpression(=)
+                  ensureSemicolon(1)
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, c1)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(c1)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(c1, expression)
+                              listener: handleNoTypeArguments(?)
+                              parseArgumentsOpt(c1)
+                                listener: handleNoArguments(?)
+                              listener: handleSend(c1, ?)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralInt([)
+                      parseArgumentOrIndexStar(c1, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralInt([)
                                   listener: handleLiteralInt(0)
-                        listener: handleIndexedExpression(null, ?.[, ])
+                        listener: handleIndexedExpression(?, [, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, c1)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(c1)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(c1, expression)
+                              listener: handleNoTypeArguments(?)
+                              parseArgumentsOpt(c1)
+                                listener: handleNoArguments(?)
+                              listener: handleSend(c1, ?)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralInt([)
+                            parsePrecedenceExpression(=, 1, false)
+                              parseUnaryExpression(=, false)
+                                parsePrimary(=, expression)
+                                  parseLiteralInt(=)
+                      parseArgumentOrIndexStar(c1, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralInt([)
+                                  listener: handleLiteralInt(0)
+                        listener: handleIndexedExpression(?, [, ])
+                      parsePrecedenceExpression(=, 1, true)
+                        parseUnaryExpression(=, true)
+                          parsePrimary(=, expression)
+                            parseLiteralInt(=)
+                              listener: handleLiteralInt(1)
+                      listener: handleAssignmentExpression(=)
+                  ensureSemicolon(1)
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, c1)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(c1)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(c1, expression)
+                              listener: handleNoTypeArguments(?)
+                              parseArgumentsOpt(c1)
+                                listener: handleNoArguments(?)
+                              listener: handleSend(c1, ?)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralInt([)
+                      parseArgumentOrIndexStar(c1, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralInt([)
+                                  listener: handleLiteralInt(0)
+                        listener: handleIndexedExpression(?, [, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, c1)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(c1)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(c1, expression)
+                              listener: handleNoTypeArguments(?)
+                              parseArgumentsOpt(c1)
+                                listener: handleNoArguments(?)
+                              listener: handleSend(c1, ?)
+                      canParseAsConditional(?)
+                        parseExpressionWithoutCascade(?)
+                          parsePrecedenceExpression(?, 1, false)
+                            parseUnaryExpression(?, false)
+                              parsePrimary(?, expression)
+                                parseLiteralListSuffix(?, null)
+                                  parseExpression([)
+                                    parsePrecedenceExpression([, 1, true)
+                                      parseUnaryExpression([, true)
+                                        parsePrimary([, expression)
+                                          parseLiteralInt([)
+                            parsePrecedenceExpression(=, 1, false)
+                              parseUnaryExpression(=, false)
+                                parsePrimary(=, expression)
+                                  parseLiteralInt(=)
+                      parseArgumentOrIndexStar(c1, Instance of 'NoTypeParamOrArg', true)
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseLiteralInt([)
+                                  listener: handleLiteralInt(0)
+                        listener: handleIndexedExpression(?, [, ])
                       parsePrecedenceExpression(=, 1, true)
                         parseUnaryExpression(=, true)
                           parsePrimary(=, expression)
@@ -249,7 +431,7 @@
                   ensureSemicolon(1)
                   listener: handleExpressionStatement(;)
           notEofOrValue(}, })
-          listener: endBlockFunctionBody(3, {, })
+          listener: endBlockFunctionBody(7, {, })
         listener: endTopLevelMethod(main, null, })
   listener: endTopLevelDeclaration()
   reportAllErrorTokens(class)
diff --git a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.parser.expect b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.parser.expect
index 9dc7175..8de92ff 100644
--- a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.parser.expect
@@ -7,6 +7,12 @@
 Class1? c1;
 c1?.[0];
 c1?.[0] = 1;
+
+c1?[0];
+c1?[0] = 1;
+
+c1 ? [0];
+c1 ? [0] = 1;
 }
 
 
@@ -17,7 +23,13 @@
 
 main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 Class1[StringToken]?[SimpleToken] c1[StringToken];[SimpleToken]
-c1[StringToken]?.[[BeginToken]0[StringToken]][SimpleToken];[SimpleToken]
-c1[StringToken]?.[[BeginToken]0[StringToken]][SimpleToken] =[SimpleToken] 1[StringToken];[SimpleToken]
+c1[StringToken]?.[SimpleToken][[BeginToken]0[StringToken]][SimpleToken];[SimpleToken]
+c1[StringToken]?.[SimpleToken][[BeginToken]0[StringToken]][SimpleToken] =[SimpleToken] 1[StringToken];[SimpleToken]
+
+c1[StringToken]?[SimpleToken][[BeginToken]0[StringToken]][SimpleToken];[SimpleToken]
+c1[StringToken]?[SimpleToken][[BeginToken]0[StringToken]][SimpleToken] =[SimpleToken] 1[StringToken];[SimpleToken]
+
+c1[StringToken] ?[SimpleToken] [[BeginToken]0[StringToken]][SimpleToken];[SimpleToken]
+c1[StringToken] ?[SimpleToken] [[BeginToken]0[StringToken]][SimpleToken] =[SimpleToken] 1[StringToken];[SimpleToken]
 }[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.scanner.expect b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.scanner.expect
index 9dc7175..8de92ff 100644
--- a/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.scanner.expect
+++ b/pkg/front_end/parser_testcases/nnbd/null_shorting_index.dart.scanner.expect
@@ -7,6 +7,12 @@
 Class1? c1;
 c1?.[0];
 c1?.[0] = 1;
+
+c1?[0];
+c1?[0] = 1;
+
+c1 ? [0];
+c1 ? [0] = 1;
 }
 
 
@@ -17,7 +23,13 @@
 
 main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
 Class1[StringToken]?[SimpleToken] c1[StringToken];[SimpleToken]
-c1[StringToken]?.[[BeginToken]0[StringToken]][SimpleToken];[SimpleToken]
-c1[StringToken]?.[[BeginToken]0[StringToken]][SimpleToken] =[SimpleToken] 1[StringToken];[SimpleToken]
+c1[StringToken]?.[SimpleToken][[BeginToken]0[StringToken]][SimpleToken];[SimpleToken]
+c1[StringToken]?.[SimpleToken][[BeginToken]0[StringToken]][SimpleToken] =[SimpleToken] 1[StringToken];[SimpleToken]
+
+c1[StringToken]?[SimpleToken][[BeginToken]0[StringToken]][SimpleToken];[SimpleToken]
+c1[StringToken]?[SimpleToken][[BeginToken]0[StringToken]][SimpleToken] =[SimpleToken] 1[StringToken];[SimpleToken]
+
+c1[StringToken] ?[SimpleToken] [[BeginToken]0[StringToken]][SimpleToken];[SimpleToken]
+c1[StringToken] ?[SimpleToken] [[BeginToken]0[StringToken]][SimpleToken] =[SimpleToken] 1[StringToken];[SimpleToken]
 }[SimpleToken]
 [SimpleToken]
diff --git a/pkg/front_end/test/flutter_gallery_leak_tester.dart b/pkg/front_end/test/flutter_gallery_leak_tester.dart
new file mode 100644
index 0000000..b0aacdb
--- /dev/null
+++ b/pkg/front_end/test/flutter_gallery_leak_tester.dart
@@ -0,0 +1,395 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+
+import "vm_service_heap_helper.dart" as helper;
+
+Completer completer;
+
+Set<String> files = {};
+
+// General idea: Do the once-a-week leak testing script
+// => In this file:
+//    * Start the frontend_server
+//    * Do a compilation
+//    * Pause the VM and do a "leak iteration"
+//    * Once the VM has been unpaused, do an invalidation etc and repeat.
+//
+// This script also makes sure to clone flutter gallery,
+// but assumes that flutter has been setup as by the script
+// `tools/bots/flutter/compile_flutter.sh`.
+
+main(List<String> args) async {
+  if (Platform.isWindows) {
+    throw "This script cannot run on Windows as it uses non-Windows "
+        "assumptions both for the placement of pub packages and the presence "
+        "of 'ln' for symbolic links. It has only been tested on Linux but will "
+        "probably also work on Mac.";
+  }
+
+  bool quicker = false;
+  bool alternativeInvalidation = false;
+  String rootPath;
+
+  for (String arg in args) {
+    if (arg == "--quicker") {
+      quicker = true;
+    } else if (arg == "--alternativeInvalidation") {
+      alternativeInvalidation = true;
+    } else if (arg.startsWith("--path=")) {
+      rootPath = arg.substring("--path=".length);
+    } else {
+      throw "Unknown argument '$arg'";
+    }
+  }
+
+  if (rootPath == null) {
+    throw "No path given. Pass with --path=<path>";
+  }
+
+  Directory patchedSdk = new Directory("$rootPath/flutter_patched_sdk/");
+  if (!patchedSdk.existsSync()) {
+    throw "Directory $patchedSdk doesn't exist.";
+  }
+  Uri frontendServerStarter = Platform.script
+      .resolve("../../frontend_server/bin/frontend_server_starter.dart");
+  if (!new File.fromUri(frontendServerStarter).existsSync()) {
+    throw "File not found: $frontendServerStarter";
+  }
+
+  Directory gallery = new Directory("$rootPath/gallery");
+  if (!gallery.existsSync()) {
+    print("Gallery not found... Attempting to clone via git.");
+    // git clone https://github.com/flutter/gallery.git
+    Process process = await Process.start("git", [
+      "clone",
+      "https://github.com/flutter/gallery.git",
+      "$rootPath/gallery"
+    ]);
+    process.stdout
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      print("git stdout> $line");
+    });
+    process.stderr
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      print("git stderr> $line");
+    });
+    int processExitCode = await process.exitCode;
+    print("Exit code from git: $processExitCode");
+
+    process = await Process.start("../flutter/bin/flutter", ["pub", "get"],
+        workingDirectory: "$rootPath/gallery/");
+    process.stdout
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      print("flutter stdout> $line");
+    });
+    process.stderr
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      print("flutter stderr> $line");
+    });
+    processExitCode = await process.exitCode;
+    print("Exit code from flutter: $processExitCode");
+
+    // Attempt to hack around strings being truncated to 128 bytes in heap dumps
+    // https://github.com/dart-lang/sdk/blob/c59cdee365b94ce066344840f9e3412d642019b5/runtime/vm/object_graph.cc#L809
+    // (pub paths can become too long, so two distinct files will look to have
+    // the same url and thus give a false positive).
+    Uri pubDirUri = Uri.parse("file://${Platform.environment['HOME']}/"
+        ".pub-cache/hosted/pub.dartlang.org/");
+    Directory pubDir = new Directory.fromUri(pubDirUri);
+    if (!pubDir.existsSync()) throw "Expected to find $pubDir";
+    File galleryDotPackages = new File("$rootPath/gallery/.packages");
+    if (!galleryDotPackages.existsSync()) {
+      throw "Didn't find $galleryDotPackages";
+    }
+    String data = galleryDotPackages.readAsStringSync();
+    data = data.replaceAll(pubDirUri.toString(), "pub/");
+    galleryDotPackages.writeAsStringSync(data);
+
+    File galleryPackageConfig =
+        new File("$rootPath/gallery/.dart_tool/package_config.json");
+    if (!galleryPackageConfig.existsSync()) {
+      throw "Didn't find $galleryPackageConfig";
+    }
+    data = galleryPackageConfig.readAsStringSync();
+    data = data.replaceAll(pubDirUri.toString(), "../pub/");
+    galleryPackageConfig.writeAsStringSync(data);
+
+    process = await Process.start("ln", ["-s", pubDir.path, "pub"],
+        workingDirectory: "$rootPath/gallery/");
+    process.stdout
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      print("ln stdout> $line");
+    });
+    process.stderr
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      print("ln stderr> $line");
+    });
+    processExitCode = await process.exitCode;
+    print("Exit code from ln: $processExitCode");
+  }
+
+  File galleryDotPackages = new File("$rootPath/gallery/.packages");
+  if (!galleryDotPackages.existsSync()) {
+    throw "Didn't find $galleryDotPackages";
+  }
+
+  List<helper.Interest> interests = new List<helper.Interest>();
+  interests.add(new helper.Interest(
+      Uri.parse("package:kernel/ast.dart"), "Library", ["fileUri"]));
+  helper.VMServiceHeapHelperSpecificExactLeakFinder heapHelper =
+      new helper.VMServiceHeapHelperSpecificExactLeakFinder(
+          interests,
+          [
+            new helper.Interest(Uri.parse("package:kernel/ast.dart"), "Library",
+                ["fileUri", "_libraryIdString"]),
+          ],
+          true,
+          false);
+
+  print("About to run with "
+      "quicker = $quicker; "
+      "alternativeInvalidation = $alternativeInvalidation; "
+      "path = $rootPath; "
+      "...");
+
+  List<String> processArgs = [
+    "--disable_dart_dev",
+    "--disable-service-auth-codes",
+    frontendServerStarter.toString(),
+    "--sdk-root",
+    "$rootPath/flutter_patched_sdk/",
+    "--incremental",
+    "--target=flutter",
+    "--debugger-module-names",
+    "-Ddart.developer.causal_async_stacks=true",
+    "--output-dill",
+    "$rootPath/flutter_server_tmp.dill",
+    "--packages",
+    "$rootPath/gallery/.packages",
+    "-Ddart.vm.profile=false",
+    "-Ddart.vm.product=false",
+    "--bytecode-options=source-positions,local-var-info,debugger-stops,"
+        "instance-field-initializers,keep-unreachable-code,"
+        "avoid-closure-call-instructions",
+    "--enable-asserts",
+    "--track-widget-creation",
+    "--initialize-from-dill",
+    "$rootPath/cache.dill",
+  ];
+  if (alternativeInvalidation) {
+    processArgs.add("--enable-experiment=alternative-invalidation-strategy");
+  }
+
+  await heapHelper.start(processArgs,
+      stdinReceiver: (s) {
+        if (s.startsWith("+")) {
+          files.add(s.substring(1));
+        } else if (s.startsWith("-")) {
+          files.remove(s.substring(1));
+        } else {
+          List<String> split = s.split(" ");
+          if (int.tryParse(split.last) != null &&
+              split[split.length - 2].endsWith(".dill")) {
+            // e.g. something like "filename.dill 0" for output file and 0
+            // errors.
+            completer.complete();
+          } else {
+            print("out> $s");
+          }
+        }
+      },
+      stderrReceiver: (s) => print("err> $s"));
+
+  await sendAndWait(heapHelper.process, ['compile package:gallery/main.dart']);
+  Stopwatch stopwatch = new Stopwatch()..start();
+  await pauseAndWait(heapHelper);
+  print("First compile took ${stopwatch.elapsedMilliseconds} ms");
+
+  await recompileAndWait(heapHelper.process, "package:gallery/main.dart", []);
+  await accept(heapHelper);
+  await sendAndWaitSetSelection(heapHelper.process);
+  await sendAndWaitToObjectForSourceLocation(heapHelper.process);
+  await sendAndWaitToObject(heapHelper.process);
+  await pauseAndWait(heapHelper);
+
+  print("Knows about ${files.length} files...");
+  List<String> listFiles = new List<String>.from(files);
+  int iteration = 0;
+  for (String s in listFiles) {
+    print("On iteration ${iteration++} / ${listFiles.length}");
+    print(" => Invalidating $s");
+    stopwatch.reset();
+    await recompileAndWait(
+        heapHelper.process, "package:gallery/main.dart", [s]);
+    await accept(heapHelper);
+    print("Recompile took ${stopwatch.elapsedMilliseconds} ms");
+    await sendAndWaitSetSelection(heapHelper.process);
+    await sendAndWaitToObjectForSourceLocation(heapHelper.process);
+    await sendAndWaitToObject(heapHelper.process);
+    if (quicker) {
+      if (iteration % 10 == 0) {
+        await pauseAndWait(heapHelper);
+      }
+    } else {
+      await pauseAndWait(heapHelper);
+    }
+  }
+  if (quicker) {
+    await pauseAndWait(heapHelper);
+  }
+
+  // We should now be done.
+  print("Done!");
+  heapHelper.process.kill();
+}
+
+Future accept(
+    helper.VMServiceHeapHelperSpecificExactLeakFinder heapHelper) async {
+  heapHelper.process.stdin.writeln('accept');
+  int waits = 0;
+  while (!await heapHelper.isIdle()) {
+    if (waits > 100) {
+      // Waited for at least 10 seconds --- assume there's something wrong.
+      throw "Timed out waiting to become idle!";
+    }
+    await new Future.delayed(new Duration(milliseconds: 100));
+    waits++;
+  }
+}
+
+class Uuid {
+  final Random _random = new Random();
+
+  /// Generate a version 4 (random) uuid. This is a uuid scheme that only uses
+  /// random numbers as the source of the generated uuid.
+  String generateV4() {
+    // Generate xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx / 8-4-4-4-12.
+    int special = 8 + _random.nextInt(4);
+
+    return '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}-'
+        '${_bitsDigits(16, 4)}-'
+        '4${_bitsDigits(12, 3)}-'
+        '${_printDigits(special, 1)}${_bitsDigits(12, 3)}-'
+        '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}';
+  }
+
+  String _bitsDigits(int bitCount, int digitCount) =>
+      _printDigits(_generateBits(bitCount), digitCount);
+
+  int _generateBits(int bitCount) => _random.nextInt(1 << bitCount);
+
+  String _printDigits(int value, int count) =>
+      value.toRadixString(16).padLeft(count, '0');
+}
+
+Future pauseAndWait(
+    helper.VMServiceHeapHelperSpecificExactLeakFinder heapHelper) async {
+  int prevIterationNumber = heapHelper.iterationNumber;
+  await heapHelper.pause();
+
+  int waits = 0;
+  while (heapHelper.iterationNumber == prevIterationNumber) {
+    if (waits > 10000) {
+      // Waited for at least 1000 seconds --- assume there's something wrong.
+      throw "Timed out waiting for the helper iteration number to increase!";
+    }
+    await new Future.delayed(new Duration(milliseconds: 100));
+    waits++;
+  }
+}
+
+Future recompileAndWait(
+    Process _server, String what, List<String> invalidates) async {
+  String inputKey = Uuid().generateV4();
+  List<String> data = ['recompile $what $inputKey'];
+  invalidates.forEach(data.add);
+  data.add('$inputKey');
+  await sendAndWait(_server, data);
+}
+
+Future sendAndWait(Process _server, List<String> data) async {
+  completer = new Completer();
+  data.forEach(_server.stdin.writeln);
+  await completer.future;
+}
+
+Future sendAndWaitDebugDidSendFirstFrameEvent(Process _server) async {
+  String inputKey = Uuid().generateV4();
+  await sendAndWait(_server, [
+    /* 'compile-expression' <boundarykey> */ 'compile-expression $inputKey',
+    /* expression */ 'WidgetsBinding.instance.debugDidSendFirstFrameEvent',
+    /* no definitions */
+    /* <boundarykey> */ inputKey,
+    /* no type-defintions */
+    /* <boundarykey> */ inputKey,
+    /* libraryUri */ 'package:flutter/src/widgets/binding.dart',
+    /* class */ '',
+    /* isStatic */ 'true'
+  ]);
+}
+
+Future sendAndWaitSetSelection(Process _server) async {
+  String inputKey = Uuid().generateV4();
+  await sendAndWait(_server, [
+    /* 'compile-expression' <boundarykey> */ 'compile-expression $inputKey',
+    /* expression */ 'WidgetInspectorService.instance.setSelection('
+        'arg1, "dummy_68")',
+    /* definition #1 */ 'arg1',
+    /* <boundarykey> */ inputKey,
+    /* no type-defintions */
+    /* <boundarykey> */ inputKey,
+    /* libraryUri */ 'package:flutter/src/widgets/widget_inspector.dart',
+    /* class */ '',
+    /* isStatic */ 'true'
+  ]);
+}
+
+Future sendAndWaitToObject(Process _server) async {
+  String inputKey = Uuid().generateV4();
+  await sendAndWait(_server, [
+    /* 'compile-expression' <boundarykey> */ 'compile-expression $inputKey',
+    /* expression */ 'WidgetInspectorService.instance.toObject('
+        '"inspector-836", "tree_112")',
+    /* no definitions */
+    /* <boundarykey> */ inputKey,
+    /* no type-defintions */
+    /* <boundarykey> */ inputKey,
+    /* libraryUri */ 'package:flutter/src/widgets/widget_inspector.dart',
+    /* class */ '',
+    /* isStatic */ 'true'
+  ]);
+}
+
+Future sendAndWaitToObjectForSourceLocation(Process _server) async {
+  String inputKey = Uuid().generateV4();
+  await sendAndWait(_server, [
+    /* 'compile-expression' <boundarykey> */ 'compile-expression $inputKey',
+    /* expression */ 'WidgetInspectorService.instance.'
+        'toObjectForSourceLocation("inspector-607", "tree_112")',
+    /* no definitions */
+    /* <boundarykey> */ inputKey,
+    /* no type-defintions */
+    /* <boundarykey> */ inputKey,
+    /* libraryUri */ 'package:flutter/src/widgets/widget_inspector.dart',
+    /* class */ '',
+    /* isStatic */ 'true'
+  ]);
+}
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 64c9d24..b348828 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -65,6 +65,7 @@
 boo
 bootstrap
 bots
+boundarykey
 bowtie
 boz
 bq
@@ -75,6 +76,7 @@
 bulk2
 bulkcompile
 c's
+c59cdee365b94ce066344840f9e3412d642019b
 ca
 cafebabe
 callable
@@ -131,6 +133,7 @@
 conversion
 conversions
 coo
+costly
 cov
 crashes
 cumulative
@@ -145,11 +148,13 @@
 dashes
 day
 db
+ddart
 dds
 debugger
 decrease
 decrements
 def
+defintions
 deleting
 denylist
 depended
@@ -185,6 +190,7 @@
 doo
 downstream
 dumping
+dumps
 dupe
 durations
 dw
@@ -284,6 +290,7 @@
 hints
 home
 hoo
+hosted
 hosting
 hot
 hotreload
@@ -291,6 +298,7 @@
 hurray
 i'm
 ia
+idle
 ikg
 illustrate
 image
@@ -357,6 +365,7 @@
 linux
 listening
 ll
+ln
 local1a
 local1b
 local1c
@@ -443,6 +452,7 @@
 person
 phrase
 pink
+placement
 places
 plug
 pointed
@@ -468,6 +478,7 @@
 px
 py
 python
+quicker
 quot
 quux
 qux
@@ -512,6 +523,7 @@
 sdks
 secondary
 segment
+selection
 sensitive
 services
 severe
@@ -561,6 +573,7 @@
 supermixin
 supplement
 suspension
+symbolic
 t\b\f\u
 t\u0008\f\u
 tails
@@ -571,6 +584,7 @@
 thereof
 thing
 threw
+timed
 timeout
 timer
 timing
@@ -599,6 +613,7 @@
 unawaited
 unbreak
 unpacked
+unpaused
 unregistered
 untransformed
 untrimmed
@@ -608,13 +623,17 @@
 upward
 uses8
 usual
+uuid
 val
 vars
 verbatim
 versioning
+waited
 waiting
+waits
 walt
 warmup
+week
 wherever
 whiskers
 wins
@@ -626,5 +645,8 @@
 xlate
 xrequired
 xxx
+xxxxxxxx
+xxxxxxxxxxxx
 y's
 year
+yxxx
diff --git a/pkg/front_end/test/vm_service_for_leak_detection.dart b/pkg/front_end/test/vm_service_for_leak_detection.dart
index efead40..9879b9c 100644
--- a/pkg/front_end/test/vm_service_for_leak_detection.dart
+++ b/pkg/front_end/test/vm_service_for_leak_detection.dart
@@ -30,6 +30,7 @@
             new helper.Interest(Uri.parse("package:kernel/ast.dart"), "Library",
                 ["fileUri", "_libraryIdString"]),
           ],
+          true,
           true);
 
   if (args.length > 0 && args[0] == "--dart2js") {
diff --git a/pkg/front_end/test/vm_service_heap_finder.dart b/pkg/front_end/test/vm_service_heap_finder.dart
index 6535c13..ea3bcea 100644
--- a/pkg/front_end/test/vm_service_heap_finder.dart
+++ b/pkg/front_end/test/vm_service_heap_finder.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 import "dart:io";
 import "vm_service_heap_helper.dart";
 
diff --git a/pkg/front_end/test/vm_service_heap_helper.dart b/pkg/front_end/test/vm_service_heap_helper.dart
index de7cde8..74e92c4 100644
--- a/pkg/front_end/test/vm_service_heap_helper.dart
+++ b/pkg/front_end/test/vm_service_heap_helper.dart
@@ -1,5 +1,8 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 import "dart:convert";
-import "dart:developer";
 import "dart:io";
 
 import "package:vm_service/vm_service.dart" as vmService;
@@ -214,10 +217,13 @@
 
 abstract class LaunchingVMServiceHeapHelper extends VMServiceHeapHelperBase {
   Process _process;
+  Process get process => _process;
 
   bool _started = false;
 
-  void start(List<String> scriptAndArgs) async {
+  void start(List<String> scriptAndArgs,
+      {void stdinReceiver(String line),
+      void stderrReceiver(String line)}) async {
     if (_started) throw "Already started";
     _started = true;
     _process = await Process.start(
@@ -232,15 +238,29 @@
       if (line.startsWith(kObservatoryListening)) {
         Uri observatoryUri =
             Uri.parse(line.substring(kObservatoryListening.length));
-        _setupAndRun(observatoryUri);
+        _setupAndRun(observatoryUri).catchError((e, st) {
+          // Manually kill the process or it will leak,
+          // see http://dartbug.com/42918
+          killProcess();
+          // This seems to rethrow.
+          throw e;
+        });
       }
-      stdout.writeln("> $line");
+      if (stdinReceiver != null) {
+        stdinReceiver(line);
+      } else {
+        stdout.writeln("> $line");
+      }
     });
     _process.stderr
         .transform(utf8.decoder)
         .transform(new LineSplitter())
         .listen((line) {
-      stderr.writeln("> $line");
+      if (stderrReceiver != null) {
+        stderrReceiver(line);
+      } else {
+        stderr.writeln("> $line");
+      }
     });
     // ignore: unawaited_futures
     _process.exitCode.then((value) {
@@ -254,7 +274,7 @@
     _process.kill();
   }
 
-  void _setupAndRun(Uri observatoryUri) async {
+  Future _setupAndRun(Uri observatoryUri) async {
     await connect(observatoryUri);
     await run();
   }
@@ -269,9 +289,13 @@
   final Map<Uri, Map<String, List<String>>> _prettyPrints =
       new Map<Uri, Map<String, List<String>>>();
   final bool throwOnPossibleLeak;
+  final bool tryToFindShortestPathToLeaks;
 
-  VMServiceHeapHelperSpecificExactLeakFinder(List<Interest> interests,
-      List<Interest> prettyPrints, this.throwOnPossibleLeak) {
+  VMServiceHeapHelperSpecificExactLeakFinder(
+      List<Interest> interests,
+      List<Interest> prettyPrints,
+      this.throwOnPossibleLeak,
+      this.tryToFindShortestPathToLeaks) {
     if (interests.isEmpty) throw "Empty list of interests given";
     for (Interest interest in interests) {
       Map<String, List<String>> classToFields = _interests[interest.uri];
@@ -301,28 +325,50 @@
     }
   }
 
+  void pause() async {
+    await _serviceClient.pause(_isolateRef.id);
+  }
+
+  vmService.VM _vm;
+  vmService.IsolateRef _isolateRef;
+  int _iterationNumber;
+  int get iterationNumber => _iterationNumber;
+
+  /// Best effort check if the isolate is idle.
+  Future<bool> isIdle() async {
+    dynamic tmp = await _serviceClient.getIsolate(_isolateRef.id);
+    if (tmp is vmService.Isolate) {
+      vmService.Isolate isolate = tmp;
+      return isolate.pauseEvent.topFrame == null;
+    }
+    return false;
+  }
+
   @override
   Future<void> run() async {
-    vmService.VM vm = await _serviceClient.getVM();
-    if (vm.isolates.length != 1) {
-      throw "Expected 1 isolate, got ${vm.isolates.length}";
+    _vm = await _serviceClient.getVM();
+    if (_vm.isolates.length != 1) {
+      throw "Expected 1 isolate, got ${_vm.isolates.length}";
     }
-    vmService.IsolateRef isolateRef = vm.isolates.single;
-    await forceGC(isolateRef.id);
+    _isolateRef = _vm.isolates.single;
+    await forceGC(_isolateRef.id);
 
-    assert(await _isPausedAtStart(isolateRef.id));
-    await _serviceClient.resume(isolateRef.id);
+    assert(await _isPausedAtStart(_isolateRef.id));
+    await _serviceClient.resume(_isolateRef.id);
 
-    int iterationNumber = 1;
+    _iterationNumber = 1;
     while (true) {
-      await waitUntilPaused(isolateRef.id);
-      print("Iteration: #$iterationNumber");
-      iterationNumber++;
-      await forceGC(isolateRef.id);
+      await waitUntilPaused(_isolateRef.id);
+      print("Iteration: #$_iterationNumber");
+      await forceGC(_isolateRef.id);
 
       vmService.HeapSnapshotGraph heapSnapshotGraph =
           await vmService.HeapSnapshotGraph.getSnapshot(
-              _serviceClient, isolateRef);
+              _serviceClient, _isolateRef);
+      // TODO: Considering the single source shortest path algorithm
+      // doesn't seem to give a useful trace anymore (the snapshot seems to
+      // have changed) and that converting the graph is very costly,
+      // maybe don't do that...
       HeapGraph graph = convertHeapGraph(heapSnapshotGraph);
 
       Set<String> seenPrints = {};
@@ -363,48 +409,54 @@
         for (String s in duplicatePrints) {
           int count = groupedByToString[s].length;
           print("$s ($count)");
+          for (HeapGraphElement duplicate in groupedByToString[s]) {
+            print(" => ${duplicate.getPrettyPrint(_prettyPrints)}");
+          }
           print("");
         }
-        print("======================================");
-        for (String duplicateString in duplicatePrints) {
-          print("$duplicateString:");
-          List<HeapGraphElement> Function(HeapGraphElement target)
-              dijkstraTarget = dijkstra(graph.elements.first, graph);
-          for (HeapGraphElement duplicate
-              in groupedByToString[duplicateString]) {
-            print("${duplicate} pointed to from:");
-            print(duplicate.getPrettyPrint(_prettyPrints));
-            List<HeapGraphElement> shortestPath = dijkstraTarget(duplicate);
-            for (int i = 0; i < shortestPath.length - 1; i++) {
-              HeapGraphElement thisOne = shortestPath[i];
-              HeapGraphElement nextOne = shortestPath[i + 1];
-              String indexFieldName;
-              if (thisOne is HeapGraphElementActual) {
-                HeapGraphClass c = thisOne.class_;
-                if (c is HeapGraphClassActual) {
-                  for (vmService.HeapSnapshotField field in c.origin.fields) {
-                    if (thisOne.references[field.index] == nextOne) {
-                      indexFieldName = field.name;
+        if (tryToFindShortestPathToLeaks) {
+          print("======================================");
+          for (String duplicateString in duplicatePrints) {
+            print("$duplicateString:");
+            List<HeapGraphElement> Function(HeapGraphElement target)
+                dijkstraTarget = dijkstra(graph.elements.first, graph);
+            for (HeapGraphElement duplicate
+                in groupedByToString[duplicateString]) {
+              print("${duplicate} pointed to from:");
+              print(duplicate.getPrettyPrint(_prettyPrints));
+              List<HeapGraphElement> shortestPath = dijkstraTarget(duplicate);
+              for (int i = 0; i < shortestPath.length - 1; i++) {
+                HeapGraphElement thisOne = shortestPath[i];
+                HeapGraphElement nextOne = shortestPath[i + 1];
+                String indexFieldName;
+                if (thisOne is HeapGraphElementActual) {
+                  HeapGraphClass c = thisOne.class_;
+                  if (c is HeapGraphClassActual) {
+                    for (vmService.HeapSnapshotField field in c.origin.fields) {
+                      if (thisOne.references[field.index] == nextOne) {
+                        indexFieldName = field.name;
+                      }
                     }
                   }
                 }
+                if (indexFieldName == null) {
+                  indexFieldName = "no field found; index "
+                      "${thisOne.references.indexOf(nextOne)}";
+                }
+                print("  $thisOne -> $nextOne ($indexFieldName)");
               }
-              if (indexFieldName == null) {
-                indexFieldName = "no field found; index "
-                    "${thisOne.references.indexOf(nextOne)}";
-              }
-              print("  $thisOne -> $nextOne ($indexFieldName)");
+              print("---------------------------");
             }
-            print("---------------------------");
           }
         }
 
         if (throwOnPossibleLeak) {
-          debugger();
           throw "Possible leak detected.";
         }
       }
-      await _serviceClient.resume(isolateRef.id);
+
+      await _serviceClient.resume(_isolateRef.id);
+      _iterationNumber++;
     }
   }
 
@@ -545,7 +597,6 @@
       }
     };
   }
-
   return new HeapGraph(classSentinel, classes, elementSentinel, elements);
 }
 
diff --git a/pkg/front_end/testcases/general/issue42997.dart b/pkg/front_end/testcases/general/issue42997.dart
new file mode 100644
index 0000000..1b1ee96
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42997.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 42997
+
+main() {}
+
+PropertyState();
+class PropertyState<I, O> {
+  void dispose() {
+    for (PropertyState<Object, Object>> state in _states) ;
+  }
+}
diff --git a/pkg/front_end/testcases/general/issue42997.dart.outline.expect b/pkg/front_end/testcases/general/issue42997.dart.outline.expect
new file mode 100644
index 0000000..c5c0bd8
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42997.dart.outline.expect
@@ -0,0 +1,38 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42997.dart:9:16: Error: Expected a function body or '=>'.
+// Try adding {}.
+// PropertyState();
+//                ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:10:7: Error: 'PropertyState' is already declared in this scope.
+// class PropertyState<I, O> {
+//       ^^^^^^^^^^^^^
+// pkg/front_end/testcases/general/issue42997.dart:9:1: Context: Previous declaration of 'PropertyState'.
+// PropertyState();
+// ^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class PropertyState#1<I extends core::Object* = dynamic, O extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::PropertyState#1<self::PropertyState#1::I*, self::PropertyState#1::O*>*
+    ;
+  method dispose() → void
+    ;
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+static method main() → dynamic
+  ;
+static abstract method PropertyState() → dynamic;
diff --git a/pkg/front_end/testcases/general/issue42997.dart.strong.expect b/pkg/front_end/testcases/general/issue42997.dart.strong.expect
new file mode 100644
index 0000000..cad2517
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42997.dart.strong.expect
@@ -0,0 +1,82 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42997.dart:9:16: Error: Expected a function body or '=>'.
+// Try adding {}.
+// PropertyState();
+//                ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:10:7: Error: 'PropertyState' is already declared in this scope.
+// class PropertyState<I, O> {
+//       ^^^^^^^^^^^^^
+// pkg/front_end/testcases/general/issue42997.dart:9:1: Context: Previous declaration of 'PropertyState'.
+// PropertyState();
+// ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:10: Error: Can't use 'PropertyState' because it is declared more than once.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//          ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:24: Error: Expected ';' after this.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                        ^^^^^^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:30: Error: Expected an identifier, but got ','.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                              ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:30: Error: Expected ';' after this.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                              ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:47: Error: Unexpected token 'in'.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                                               ^^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:41: Error: The getter 'state' isn't defined for the class 'PropertyState#1<I, O>'.
+//  - 'PropertyState#1' is from 'pkg/front_end/testcases/general/issue42997.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'state'.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                                         ^^^^^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:38: Error: The operator '>>' isn't defined for the class 'Type'.
+//  - 'Type' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '>>' operator.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                                      ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class PropertyState#1<I extends core::Object* = dynamic, O extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::PropertyState#1<self::PropertyState#1::I*, self::PropertyState#1::O*>*
+    : super core::Object::•()
+    ;
+  method dispose() → void {
+    for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue42997.dart:12:10: Error: Can't use 'PropertyState' because it is declared more than once.
+    for (PropertyState<Object, Object>> state in _states) ;
+         ^".<(core::Object*); invalid-expression "pkg/front_end/testcases/general/issue42997.dart:12:30: Error: This couldn't be parsed.
+    for (PropertyState<Object, Object>> state in _states) ;
+                             ^" as{TypeError,ForDynamic} core::bool*; invalid-expression "pkg/front_end/testcases/general/issue42997.dart:12:30: Error: This couldn't be parsed.
+    for (PropertyState<Object, Object>> state in _states) ;
+                             ^", invalid-expression "pkg/front_end/testcases/general/issue42997.dart:12:38: Error: The operator '>>' isn't defined for the class 'Type'.
+ - 'Type' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '>>' operator.
+    for (PropertyState<Object, Object>> state in _states) ;
+                                     ^^")
+      ;
+  }
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+static method main() → dynamic {}
+static abstract method PropertyState() → dynamic;
diff --git a/pkg/front_end/testcases/general/issue42997.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue42997.dart.strong.transformed.expect
new file mode 100644
index 0000000..796765b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42997.dart.strong.transformed.expect
@@ -0,0 +1,82 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42997.dart:9:16: Error: Expected a function body or '=>'.
+// Try adding {}.
+// PropertyState();
+//                ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:10:7: Error: 'PropertyState' is already declared in this scope.
+// class PropertyState<I, O> {
+//       ^^^^^^^^^^^^^
+// pkg/front_end/testcases/general/issue42997.dart:9:1: Context: Previous declaration of 'PropertyState'.
+// PropertyState();
+// ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:10: Error: Can't use 'PropertyState' because it is declared more than once.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//          ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:24: Error: Expected ';' after this.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                        ^^^^^^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:30: Error: Expected an identifier, but got ','.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                              ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:30: Error: Expected ';' after this.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                              ^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:47: Error: Unexpected token 'in'.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                                               ^^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:41: Error: The getter 'state' isn't defined for the class 'PropertyState#1<I, O>'.
+//  - 'PropertyState#1' is from 'pkg/front_end/testcases/general/issue42997.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'state'.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                                         ^^^^^
+//
+// pkg/front_end/testcases/general/issue42997.dart:12:38: Error: The operator '>>' isn't defined for the class 'Type'.
+//  - 'Type' is from 'dart:core'.
+// Try correcting the operator to an existing operator, or defining a '>>' operator.
+//     for (PropertyState<Object, Object>> state in _states) ;
+//                                      ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class PropertyState#1<I extends core::Object* = dynamic, O extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::PropertyState#1<self::PropertyState#1::I*, self::PropertyState#1::O*>*
+    : super core::Object::•()
+    ;
+  method dispose() → void {
+    for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue42997.dart:12:10: Error: Can't use 'PropertyState' because it is declared more than once.
+    for (PropertyState<Object, Object>> state in _states) ;
+         ^".<(core::Object*); invalid-expression "pkg/front_end/testcases/general/issue42997.dart:12:30: Error: This couldn't be parsed.
+    for (PropertyState<Object, Object>> state in _states) ;
+                             ^"; invalid-expression "pkg/front_end/testcases/general/issue42997.dart:12:30: Error: This couldn't be parsed.
+    for (PropertyState<Object, Object>> state in _states) ;
+                             ^", invalid-expression "pkg/front_end/testcases/general/issue42997.dart:12:38: Error: The operator '>>' isn't defined for the class 'Type'.
+ - 'Type' is from 'dart:core'.
+Try correcting the operator to an existing operator, or defining a '>>' operator.
+    for (PropertyState<Object, Object>> state in _states) ;
+                                     ^^")
+      ;
+  }
+  abstract member-signature get _identityHashCode() → core::int*;
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
+  abstract member-signature operator ==(dynamic other) → core::bool*;
+  abstract member-signature get hashCode() → core::int*;
+  abstract member-signature method toString() → core::String*;
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
+  abstract member-signature get runtimeType() → core::Type*;
+}
+static method main() → dynamic {}
+static abstract method PropertyState() → dynamic;
diff --git a/pkg/front_end/testcases/general/issue42997.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue42997.dart.textual_outline.expect
new file mode 100644
index 0000000..60bb19e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42997.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+main() { }
+PropertyState();
+class PropertyState<I, O> {
+  void dispose() { }
+}
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart b/pkg/front_end/testcases/nnbd/never_receiver.dart
index caf301bf..d13eb48 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart
@@ -18,14 +18,14 @@
   y?.bar; // Not an error.
   y?.baz = 42; // Not an error.
   y?.call(); // Not an error.
-  y?.[42]; // Not an error.
-  y?.[42] = 42; // Not an error.
+  y?[42]; // Not an error.
+  y?[42] = 42; // Not an error.
 
   x?.foo(); // Warning.
   x?.bar; // Warning.
   x?.baz = 42; // Warning.
-  x?.[42]; // Warning.
-  x?.[42] = 42; // Warning.
+  x?[42]; // Warning.
+  x?[42] = 42; // Warning.
 
   y.foo(); // Error.
   y.bar; // Error.
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
index 64f137e..8a67b5a 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.expect
@@ -15,11 +15,11 @@
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:27:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
-//   x?.[42]; // Warning.
+//   x?[42]; // Warning.
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:28:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
-//   x?.[42] = 42; // Warning.
+//   x?[42] = 42; // Warning.
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never?'.
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
index 2a5f9c5..aa42b16 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.strong.transformed.expect
@@ -15,11 +15,11 @@
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:27:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
-//   x?.[42]; // Warning.
+//   x?[42]; // Warning.
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:28:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
-//   x?.[42] = 42; // Warning.
+//   x?[42] = 42; // Warning.
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never?'.
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
index 64f137e..8a67b5a 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect
@@ -15,11 +15,11 @@
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:27:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
-//   x?.[42]; // Warning.
+//   x?[42]; // Warning.
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:28:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
-//   x?.[42] = 42; // Warning.
+//   x?[42] = 42; // Warning.
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never?'.
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
index 2a5f9c5..aa42b16 100644
--- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect
@@ -15,11 +15,11 @@
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:27:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
-//   x?.[42]; // Warning.
+//   x?[42]; // Warning.
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:28:3: Warning: Operand of null-aware operation '?.' has type 'Never' which excludes null.
-//   x?.[42] = 42; // Warning.
+//   x?[42] = 42; // Warning.
 //   ^
 //
 // pkg/front_end/testcases/nnbd/never_receiver.dart:30:5: Error: The method 'foo' isn't defined for the class 'Never?'.
diff --git a/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart
new file mode 100644
index 0000000..b98db8c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  dynamic c;
+  c?.[42];
+  c?.[42] = 42;
+  c?.[42]++;
+  ++c?.[42];
+  c?.[42]?.[0];
+  c?.[42]?.[0] ??= 42;
+  c?.[42]?.[0]++;
+  ++c?.[42]?.[0];
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.outline.expect b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.outline.expect
new file mode 100644
index 0000000..e2cba6b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.outline.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.strong.expect b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.strong.expect
new file mode 100644
index 0000000..82f387d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.strong.expect
@@ -0,0 +1,113 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:7:6: Error: Expected an identifier, but got '['.
+//   c?.[42];
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:6: Error: Expected an identifier, but got '['.
+//   c?.[42] = 42;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:11: Error: Can't assign to this.
+//   c?.[42] = 42;
+//           ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Expected an identifier, but got '['.
+//   c?.[42]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Can't assign to this.
+//   c?.[42]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Expected an identifier, but got '['.
+//   ++c?.[42];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Can't assign to this.
+//   ++c?.[42];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0];
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0];
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0] ??= 42;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0] ??= 42;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:16: Error: Can't assign to this.
+//   c?.[42]?.[0] ??= 42;
+//                ^^^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0]++;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Can't assign to this.
+//   c?.[42]?.[0]++;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:8: Error: Expected an identifier, but got '['.
+//   ++c?.[42]?.[0];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Expected an identifier, but got '['.
+//   ++c?.[42]?.[0];
+//              ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Can't assign to this.
+//   ++c?.[42]?.[0];
+//              ^
+//
+import self as self;
+
+static method main() → dynamic {
+  dynamic c;
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:7:6: Error: Expected an identifier, but got '['.
+  c?.[42];
+     ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:11: Error: Can't assign to this.
+  c?.[42] = 42;
+          ^";
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Can't assign to this.
+  c?.[42]++;
+     ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Expected an identifier, but got '['.
+  c?.[42]++;
+     ^";
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Can't assign to this.
+  ++c?.[42];
+       ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Expected an identifier, but got '['.
+  ++c?.[42];
+       ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:12: Error: Expected an identifier, but got '['.
+  c?.[42]?.[0];
+           ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:16: Error: Can't assign to this.
+  c?.[42]?.[0] ??= 42;
+               ^^^";
+  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Can't assign to this.
+  c?.[42]?.[0]++;
+           ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Expected an identifier, but got '['.
+  c?.[42]?.[0]++;
+           ^";
+  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Can't assign to this.
+  ++c?.[42]?.[0];
+             ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Expected an identifier, but got '['.
+  ++c?.[42]?.[0];
+             ^";
+}
diff --git a/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.strong.transformed.expect
new file mode 100644
index 0000000..82f387d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.strong.transformed.expect
@@ -0,0 +1,113 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:7:6: Error: Expected an identifier, but got '['.
+//   c?.[42];
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:6: Error: Expected an identifier, but got '['.
+//   c?.[42] = 42;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:11: Error: Can't assign to this.
+//   c?.[42] = 42;
+//           ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Expected an identifier, but got '['.
+//   c?.[42]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Can't assign to this.
+//   c?.[42]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Expected an identifier, but got '['.
+//   ++c?.[42];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Can't assign to this.
+//   ++c?.[42];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0];
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0];
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0] ??= 42;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0] ??= 42;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:16: Error: Can't assign to this.
+//   c?.[42]?.[0] ??= 42;
+//                ^^^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0]++;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Can't assign to this.
+//   c?.[42]?.[0]++;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:8: Error: Expected an identifier, but got '['.
+//   ++c?.[42]?.[0];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Expected an identifier, but got '['.
+//   ++c?.[42]?.[0];
+//              ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Can't assign to this.
+//   ++c?.[42]?.[0];
+//              ^
+//
+import self as self;
+
+static method main() → dynamic {
+  dynamic c;
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:7:6: Error: Expected an identifier, but got '['.
+  c?.[42];
+     ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:11: Error: Can't assign to this.
+  c?.[42] = 42;
+          ^";
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Can't assign to this.
+  c?.[42]++;
+     ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Expected an identifier, but got '['.
+  c?.[42]++;
+     ^";
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Can't assign to this.
+  ++c?.[42];
+       ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Expected an identifier, but got '['.
+  ++c?.[42];
+       ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:12: Error: Expected an identifier, but got '['.
+  c?.[42]?.[0];
+           ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:16: Error: Can't assign to this.
+  c?.[42]?.[0] ??= 42;
+               ^^^";
+  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Can't assign to this.
+  c?.[42]?.[0]++;
+           ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Expected an identifier, but got '['.
+  c?.[42]?.[0]++;
+           ^";
+  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Can't assign to this.
+  ++c?.[42]?.[0];
+             ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Expected an identifier, but got '['.
+  ++c?.[42]?.[0];
+             ^";
+}
diff --git a/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.weak.expect b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.weak.expect
new file mode 100644
index 0000000..82f387d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.weak.expect
@@ -0,0 +1,113 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:7:6: Error: Expected an identifier, but got '['.
+//   c?.[42];
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:6: Error: Expected an identifier, but got '['.
+//   c?.[42] = 42;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:11: Error: Can't assign to this.
+//   c?.[42] = 42;
+//           ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Expected an identifier, but got '['.
+//   c?.[42]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Can't assign to this.
+//   c?.[42]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Expected an identifier, but got '['.
+//   ++c?.[42];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Can't assign to this.
+//   ++c?.[42];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0];
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0];
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0] ??= 42;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0] ??= 42;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:16: Error: Can't assign to this.
+//   c?.[42]?.[0] ??= 42;
+//                ^^^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0]++;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Can't assign to this.
+//   c?.[42]?.[0]++;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:8: Error: Expected an identifier, but got '['.
+//   ++c?.[42]?.[0];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Expected an identifier, but got '['.
+//   ++c?.[42]?.[0];
+//              ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Can't assign to this.
+//   ++c?.[42]?.[0];
+//              ^
+//
+import self as self;
+
+static method main() → dynamic {
+  dynamic c;
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:7:6: Error: Expected an identifier, but got '['.
+  c?.[42];
+     ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:11: Error: Can't assign to this.
+  c?.[42] = 42;
+          ^";
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Can't assign to this.
+  c?.[42]++;
+     ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Expected an identifier, but got '['.
+  c?.[42]++;
+     ^";
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Can't assign to this.
+  ++c?.[42];
+       ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Expected an identifier, but got '['.
+  ++c?.[42];
+       ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:12: Error: Expected an identifier, but got '['.
+  c?.[42]?.[0];
+           ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:16: Error: Can't assign to this.
+  c?.[42]?.[0] ??= 42;
+               ^^^";
+  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Can't assign to this.
+  c?.[42]?.[0]++;
+           ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Expected an identifier, but got '['.
+  c?.[42]?.[0]++;
+           ^";
+  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Can't assign to this.
+  ++c?.[42]?.[0];
+             ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Expected an identifier, but got '['.
+  ++c?.[42]?.[0];
+             ^";
+}
diff --git a/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.weak.transformed.expect
new file mode 100644
index 0000000..82f387d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart.weak.transformed.expect
@@ -0,0 +1,113 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:7:6: Error: Expected an identifier, but got '['.
+//   c?.[42];
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:6: Error: Expected an identifier, but got '['.
+//   c?.[42] = 42;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:11: Error: Can't assign to this.
+//   c?.[42] = 42;
+//           ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Expected an identifier, but got '['.
+//   c?.[42]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Can't assign to this.
+//   c?.[42]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Expected an identifier, but got '['.
+//   ++c?.[42];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Can't assign to this.
+//   ++c?.[42];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0];
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0];
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0] ??= 42;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0] ??= 42;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:16: Error: Can't assign to this.
+//   c?.[42]?.[0] ??= 42;
+//                ^^^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:6: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0]++;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Expected an identifier, but got '['.
+//   c?.[42]?.[0]++;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Can't assign to this.
+//   c?.[42]?.[0]++;
+//            ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:8: Error: Expected an identifier, but got '['.
+//   ++c?.[42]?.[0];
+//        ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Expected an identifier, but got '['.
+//   ++c?.[42]?.[0];
+//              ^
+//
+// pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Can't assign to this.
+//   ++c?.[42]?.[0];
+//              ^
+//
+import self as self;
+
+static method main() → dynamic {
+  dynamic c;
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:7:6: Error: Expected an identifier, but got '['.
+  c?.[42];
+     ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:8:11: Error: Can't assign to this.
+  c?.[42] = 42;
+          ^";
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Can't assign to this.
+  c?.[42]++;
+     ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:9:6: Error: Expected an identifier, but got '['.
+  c?.[42]++;
+     ^";
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Can't assign to this.
+  ++c?.[42];
+       ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:10:8: Error: Expected an identifier, but got '['.
+  ++c?.[42];
+       ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:11:12: Error: Expected an identifier, but got '['.
+  c?.[42]?.[0];
+           ^";
+  invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:12:16: Error: Can't assign to this.
+  c?.[42]?.[0] ??= 42;
+               ^^^";
+  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Can't assign to this.
+  c?.[42]?.[0]++;
+           ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:13:12: Error: Expected an identifier, but got '['.
+  c?.[42]?.[0]++;
+           ^";
+  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Can't assign to this.
+  ++c?.[42]?.[0];
+             ^" in invalid-expression "pkg/front_end/testcases/nnbd/no_support_for_old_null_aware_index_access_syntax.dart:14:14: Error: Expected an identifier, but got '['.
+  ++c?.[42]?.[0];
+             ^";
+}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart b/pkg/front_end/testcases/nnbd/null_shorting.dart
index 8b1c781..410596b 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting.dart
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart
@@ -164,25 +164,25 @@
   Class2? nullable2 = n2;
   Class3? nullable3 = n3;
 
-  n1?.[nullable1];
-  n1?.[nullable1] = new Class1();
-  n1?.[nullable1]?.nonNullable1Method();
+  n1?[nullable1];
+  n1?[nullable1] = new Class1();
+  n1?[nullable1]?.nonNullable1Method();
   n1?.nonNullable1[nullable1];
   n1?.nonNullable1[nullable1] = new Class1();
   nullable1 = n1?.nonNullable1[nullable1] = new Class1();
   n1?.nonNullable1[nullable1]?.nonNullable1Method();
   n1?.nonNullable2[nullable2] += 0;
   nullable2 = n1?.nonNullable2[nullable2] += 0;
-  n1?.[nullable1] ??= nullable1;
-  nullable1 = n1?.[nullable1] ??= nullable1;
-  n2?.[nullable2] += 0;
-  nullable2 = n2?.[nullable2] += 0;
-  n2?.[nullable2] += 0;
-  nullable2 = n2?.[nullable2] += 0;
-  n2?.[nullable2]++;
-  nullable2 = n2?.[nullable2]++;
-  ++n2?.[nullable2];
-  nullable2 = ++n2?.[nullable2];
+  n1?[nullable1] ??= nullable1;
+  nullable1 = n1?[nullable1] ??= nullable1;
+  n2?[nullable2] += 0;
+  nullable2 = n2?[nullable2] += 0;
+  n2?[nullable2] += 0;
+  nullable2 = n2?[nullable2] += 0;
+  n2?[nullable2]++;
+  nullable2 = n2?[nullable2]++;
+  ++n2?[nullable2];
+  nullable2 = ++n2?[nullable2];
   n1?.nonNullable2[nullable2]++;
   nullable2 = n1?.nonNullable2[nullable2]++;
   ++n1?.nonNullable2[nullable2];
@@ -199,19 +199,19 @@
   ++n1?.nonNullable2[nullable2][nullable2];
   nullable2 = ++n1?.nonNullable2[nullable2][nullable2];
 
-  n1?.[nullable1]?.[nullable1];
-  n1?.[nullable1]?.[nullable1] = new Class1();
-  nullable1 = n1?.[nullable1]?.[nullable1] = new Class1();
-  n1?.[nullable1]?.[nullable1]?.nonNullable1Method();
-  nullable1 = n1?.[nullable1]?.[nullable1]?.nonNullable1Method();
-  n1?.[nullable1]?.[nullable1] ??= nullable1;
-  nullable1 = n1?.[nullable1]?.[nullable1] ??= nullable1;
-  n3?.[nullable3]?.[nullable2] += 0;
-  nullable2 = n3?.[nullable3]?.[nullable2] += 0;
-  n3?.[nullable3]?.[nullable2]++;
-  nullable2 = n3?.[nullable3]?.[nullable2]++;
-  ++n3?.[nullable3]?.[nullable2];
-  nullable2 = ++n3?.[nullable3]?.[nullable2];
+  n1?[nullable1]?[nullable1];
+  n1?[nullable1]?[nullable1] = new Class1();
+  nullable1 = n1?[nullable1]?[nullable1] = new Class1();
+  n1?[nullable1]?[nullable1]?.nonNullable1Method();
+  nullable1 = n1?[nullable1]?[nullable1]?.nonNullable1Method();
+  n1?[nullable1]?[nullable1] ??= nullable1;
+  nullable1 = n1?[nullable1]?[nullable1] ??= nullable1;
+  n3?[nullable3]?[nullable2] += 0;
+  nullable2 = n3?[nullable3]?[nullable2] += 0;
+  n3?[nullable3]?[nullable2]++;
+  nullable2 = n3?[nullable3]?[nullable2]++;
+  ++n3?[nullable3]?[nullable2];
+  nullable2 = ++n3?[nullable3]?[nullable2];
 }
 
 void operatorAccess(Class1? n1, Class2? n2) {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart
index 64f63c5..616467f 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart
@@ -188,25 +188,25 @@
   Class2? nullable2 = n2;
   Class3? nullable3 = n3;
 
-  Extension1(n1)?.[nullable1];
-  Extension1(n1)?.[nullable1] = new Class1();
-  Extension1(n1)?.[nullable1]?.nonNullable1Method();
+  Extension1(n1)?[nullable1];
+  Extension1(n1)?[nullable1] = new Class1();
+  Extension1(n1)?[nullable1]?.nonNullable1Method();
   Extension1(n1)?.nonNullable1[nullable1];
   Extension1(n1)?.nonNullable1[nullable1] = new Class1();
   nullable1 = Extension1(n1)?.nonNullable1[nullable1] = new Class1();
   Extension1(n1)?.nonNullable1[nullable1]?.nonNullable1Method();
   Extension1(n1)?.nonNullable2[nullable2] += 0;
   nullable2 = Extension1(n1)?.nonNullable2[nullable2] += 0;
-  Extension1(n1)?.[nullable1] ??= nullable1;
-  nullable1 = Extension1(n1)?.[nullable1] ??= nullable1;
-  Extension2(n2)?.[nullable2] += 0;
-  nullable2 = Extension2(n2)?.[nullable2] += 0;
-  Extension2(n2)?.[nullable2] += 0;
-  nullable2 = Extension2(n2)?.[nullable2] += 0;
-  Extension2(n2)?.[nullable2]++;
-  nullable2 = Extension2(n2)?.[nullable2]++;
-  ++Extension2(n2)?.[nullable2];
-  nullable2 = ++Extension2(n2)?.[nullable2];
+  Extension1(n1)?[nullable1] ??= nullable1;
+  nullable1 = Extension1(n1)?[nullable1] ??= nullable1;
+  Extension2(n2)?[nullable2] += 0;
+  nullable2 = Extension2(n2)?[nullable2] += 0;
+  Extension2(n2)?[nullable2] += 0;
+  nullable2 = Extension2(n2)?[nullable2] += 0;
+  Extension2(n2)?[nullable2]++;
+  nullable2 = Extension2(n2)?[nullable2]++;
+  ++Extension2(n2)?[nullable2];
+  nullable2 = ++Extension2(n2)?[nullable2];
   Extension1(n1)?.nonNullable2[nullable2]++;
   nullable2 = Extension1(n1)?.nonNullable2[nullable2]++;
   ++Extension1(n1)?.nonNullable2[nullable2];
@@ -223,19 +223,19 @@
   ++Extension1(n1)?.nonNullable2[nullable2][nullable2];
   nullable2 = ++Extension1(n1)?.nonNullable2[nullable2][nullable2];
 
-  Extension1(n1)?.[nullable1]?.[nullable1];
-  Extension1(n1)?.[nullable1]?.[nullable1] = new Class1();
-  nullable1 = Extension1(n1)?.[nullable1]?.[nullable1] = new Class1();
-  Extension1(n1)?.[nullable1]?.[nullable1]?.nonNullable1Method();
-  nullable1 = Extension1(n1)?.[nullable1]?.[nullable1]?.nonNullable1Method();
-  Extension1(n1)?.[nullable1]?.[nullable1] ??= nullable1;
-  nullable1 = Extension1(n1)?.[nullable1]?.[nullable1] ??= nullable1;
-  Extension3(n3)?.[nullable3]?.[nullable2] += 0;
-  nullable2 = Extension3(n3)?.[nullable3]?.[nullable2] += 0;
-  Extension3(n3)?.[nullable3]?.[nullable2]++;
-  nullable2 = Extension3(n3)?.[nullable3]?.[nullable2]++;
-  ++Extension3(n3)?.[nullable3]?.[nullable2];
-  nullable2 = ++Extension3(n3)?.[nullable3]?.[nullable2];
+  Extension1(n1)?[nullable1]?[nullable1];
+  Extension1(n1)?[nullable1]?[nullable1] = new Class1();
+  nullable1 = Extension1(n1)?[nullable1]?[nullable1] = new Class1();
+  Extension1(n1)?[nullable1]?[nullable1]?.nonNullable1Method();
+  nullable1 = Extension1(n1)?[nullable1]?[nullable1]?.nonNullable1Method();
+  Extension1(n1)?[nullable1]?[nullable1] ??= nullable1;
+  nullable1 = Extension1(n1)?[nullable1]?[nullable1] ??= nullable1;
+  Extension3(n3)?[nullable3]?[nullable2] += 0;
+  nullable2 = Extension3(n3)?[nullable3]?[nullable2] += 0;
+  Extension3(n3)?[nullable3]?[nullable2]++;
+  nullable2 = Extension3(n3)?[nullable3]?[nullable2]++;
+  ++Extension3(n3)?[nullable3]?[nullable2];
+  nullable2 = ++Extension3(n3)?[nullable3]?[nullable2];
 }
 
 void operatorAccess(Class1? n1, Class2? n2) {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart
index baa5adc..1d11f2d 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart
@@ -170,25 +170,25 @@
   Class2? nullable2 = n2;
   Class3? nullable3 = n3;
 
-  n1?.[nullable1];
-  n1?.[nullable1] = new Class1();
-  n1?.[nullable1]?.nonNullable1Method();
+  n1?[nullable1];
+  n1?[nullable1] = new Class1();
+  n1?[nullable1]?.nonNullable1Method();
   n1?.nonNullable1[nullable1];
   n1?.nonNullable1[nullable1] = new Class1();
   nullable1 = n1?.nonNullable1[nullable1] = new Class1();
   n1?.nonNullable1[nullable1]?.nonNullable1Method();
   n1?.nonNullable2[nullable2] += 0;
   nullable2 = n1?.nonNullable2[nullable2] += 0;
-  n1?.[nullable1] ??= nullable1;
-  nullable1 = n1?.[nullable1] ??= nullable1;
-  n2?.[nullable2] += 0;
-  nullable2 = n2?.[nullable2] += 0;
-  n2?.[nullable2] += 0;
-  nullable2 = n2?.[nullable2] += 0;
-  n2?.[nullable2]++;
-  nullable2 = n2?.[nullable2]++;
-  ++n2?.[nullable2];
-  nullable2 = ++n2?.[nullable2];
+  n1?[nullable1] ??= nullable1;
+  nullable1 = n1?[nullable1] ??= nullable1;
+  n2?[nullable2] += 0;
+  nullable2 = n2?[nullable2] += 0;
+  n2?[nullable2] += 0;
+  nullable2 = n2?[nullable2] += 0;
+  n2?[nullable2]++;
+  nullable2 = n2?[nullable2]++;
+  ++n2?[nullable2];
+  nullable2 = ++n2?[nullable2];
   n1?.nonNullable2[nullable2]++;
   nullable2 = n1?.nonNullable2[nullable2]++;
   ++n1?.nonNullable2[nullable2];
@@ -205,19 +205,19 @@
   ++n1?.nonNullable2[nullable2][nullable2];
   nullable2 = ++n1?.nonNullable2[nullable2][nullable2];
 
-  n1?.[nullable1]?.[nullable1];
-  n1?.[nullable1]?.[nullable1] = new Class1();
-  nullable1 = n1?.[nullable1]?.[nullable1] = new Class1();
-  n1?.[nullable1]?.[nullable1]?.nonNullable1Method();
-  nullable1 = n1?.[nullable1]?.[nullable1]?.nonNullable1Method();
-  n1?.[nullable1]?.[nullable1] ??= nullable1;
-  nullable1 = n1?.[nullable1]?.[nullable1] ??= nullable1;
-  n3?.[nullable3]?.[nullable2] += 0;
-  nullable2 = n3?.[nullable3]?.[nullable2] += 0;
-  n3?.[nullable3]?.[nullable2]++;
-  nullable2 = n3?.[nullable3]?.[nullable2]++;
-  ++n3?.[nullable3]?.[nullable2];
-  nullable2 = ++n3?.[nullable3]?.[nullable2];
+  n1?[nullable1]?[nullable1];
+  n1?[nullable1]?[nullable1] = new Class1();
+  nullable1 = n1?[nullable1]?[nullable1] = new Class1();
+  n1?[nullable1]?[nullable1]?.nonNullable1Method();
+  nullable1 = n1?[nullable1]?[nullable1]?.nonNullable1Method();
+  n1?[nullable1]?[nullable1] ??= nullable1;
+  nullable1 = n1?[nullable1]?[nullable1] ??= nullable1;
+  n3?[nullable3]?[nullable2] += 0;
+  nullable2 = n3?[nullable3]?[nullable2] += 0;
+  n3?[nullable3]?[nullable2]++;
+  nullable2 = n3?[nullable3]?[nullable2]++;
+  ++n3?[nullable3]?[nullable2];
+  nullable2 = ++n3?[nullable3]?[nullable2];
 }
 
 void operatorAccess(Class1? n1, Class2? n2) {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart b/pkg/front_end/testcases/nnbd/null_shorting_index.dart
index 79991fa..ce82366 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart
@@ -21,64 +21,64 @@
 
 main() {
   Class1? c1;
-  c1?.[0];
-  c1?.[0] = 1;
-  c1?.[0] = 1 + c1[0];
-  c1?.[0] += 1;
-  c1?.[0] += 1 + c1[0];
+  c1?[0];
+  c1?[0] = 1;
+  c1?[0] = 1 + c1[0];
+  c1?[0] += 1;
+  c1?[0] += 1 + c1[0];
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  ++c1?.[0];
-  c1?.[0]++;
-  c1?.[0] ??= 1;
-  c1?.[0] ??= 1 + c1[1];
+  ++c1?[0];
+  c1?[0]++;
+  c1?[0] ??= 1;
+  c1?[0] ??= 1 + c1[1];
 
   Class2? c2;
-  c2?.[0];
-  c2?.[0] = 1;
-  c2?.[0] = 1 + c2[0];
-  c2?.[0] += 1;
-  c2?.[0] += 1 + c2[0];
+  c2?[0];
+  c2?[0] = 1;
+  c2?[0] = 1 + c2[0];
+  c2?[0] += 1;
+  c2?[0] += 1 + c2[0];
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  ++c2?.[0];
-  c2?.[0]++;
-  c2?.[0] ??= 1;
-  c2?.[0] ??= 1 + c2[1];
+  ++c2?[0];
+  c2?[0]++;
+  c2?[0] ??= 1;
+  c2?[0] ??= 1 + c2[1];
 
-  Extension(c2)?.[0];
-  Extension(c2)?.[0] = 1;
-  Extension(c2)?.[0] = 1 + Extension(c2)[0];
-  Extension(c2)?.[0] += 1;
-  Extension(c2)?.[0] += 1 + Extension(c2)[0];
+  Extension(c2)?[0];
+  Extension(c2)?[0] = 1;
+  Extension(c2)?[0] = 1 + Extension(c2)[0];
+  Extension(c2)?[0] += 1;
+  Extension(c2)?[0] += 1 + Extension(c2)[0];
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  ++Extension(c2)?.[0];
-  Extension(c2)?.[0]++;
-  Extension(c2)?.[0] ??= 1;
-  Extension(c2)?.[0] ??= 1 + Extension(c2)[1];
+  ++Extension(c2)?[0];
+  Extension(c2)?[0]++;
+  Extension(c2)?[0] ??= 1;
+  Extension(c2)?[0] ??= 1 + Extension(c2)[1];
 
-  c1?.field?.[0];
-  c1?.field?.[0] = 1;
-  c1?.field?.[0] = 1 + c1[0];
-  c1?.field?.[0] += 1;
-  c1?.field?.[0] += 1 + c1[0];
+  c1?.field?[0];
+  c1?.field?[0] = 1;
+  c1?.field?[0] = 1 + c1[0];
+  c1?.field?[0] += 1;
+  c1?.field?[0] += 1 + c1[0];
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  ++c1?.field?.[0];
-  c1?.field?.[0]++;
-  c1?.field?.[0] ??= 1;
-  c1?.field?.[0] ??= 1 + c1[1];
+  ++c1?.field?[0];
+  c1?.field?[0]++;
+  c1?.field?[0] ??= 1;
+  c1?.field?[0] ??= 1 + c1[1];
 
-  Extension(c1?.field)?.[0];
-  Extension(c1?.field)?.[0] = 1;
-  Extension(c1?.field)?.[0] = 1 + Extension(c2)?.[0]!;
-  Extension(c1?.field)?.[0] += 1;
-  Extension(c1?.field)?.[0] += 1 + Extension(c2)?.[0]!;
+  Extension(c1?.field)?[0];
+  Extension(c1?.field)?[0] = 1;
+  Extension(c1?.field)?[0] = 1 + Extension(c2)?[0]!;
+  Extension(c1?.field)?[0] += 1;
+  Extension(c1?.field)?[0] += 1 + Extension(c2)?[0]!;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  ++Extension(c1?.field)?.[0];
-  Extension(c1?.field)?.[0]++;
-  Extension(c1?.field)?.[0] ??= 1;
-  Extension(c1?.field)?.[0] ??= 1 + Extension(c2)?.[1]!;
+  ++Extension(c1?.field)?[0];
+  Extension(c1?.field)?[0]++;
+  Extension(c1?.field)?[0] ??= 1;
+  Extension(c1?.field)?[0] ??= 1 + Extension(c2)?[1]!;
 }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
index 111b12b..e1edbab 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
@@ -2,45 +2,45 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:33:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.[0] ??= 1;
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:33:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?[0] ??= 1;
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:34:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.[0] ??= 1 + c1[1];
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:34:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?[0] ??= 1 + c1[1];
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:46:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c2?.[0] ??= 1;
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:46:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c2?[0] ??= 1;
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:47:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c2?.[0] ??= 1 + c2[1];
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:47:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c2?[0] ??= 1 + c2[1];
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:58:16: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c2)?.[0] ??= 1;
-//                ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:58:17: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c2)?[0] ??= 1;
+//                 ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:59:16: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c2)?.[0] ??= 1 + Extension(c2)[1];
-//                ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:59:17: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c2)?[0] ??= 1 + Extension(c2)[1];
+//                 ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:70:12: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.field?.[0] ??= 1;
-//            ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:70:13: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?.field?[0] ??= 1;
+//             ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:71:12: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.field?.[0] ??= 1 + c1[1];
-//            ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:71:13: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?.field?[0] ??= 1 + c1[1];
+//             ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:82:23: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c1?.field)?.[0] ??= 1;
-//                       ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:82:24: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c1?.field)?[0] ??= 1;
+//                        ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:83:23: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c1?.field)?.[0] ??= 1 + Extension(c2)?.[1]!;
-//                       ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:83:24: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c1?.field)?[0] ??= 1 + Extension(c2)?[1]!;
+//                        ^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
index 111b12b..e1edbab 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
@@ -2,45 +2,45 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:33:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.[0] ??= 1;
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:33:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?[0] ??= 1;
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:34:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.[0] ??= 1 + c1[1];
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:34:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?[0] ??= 1 + c1[1];
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:46:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c2?.[0] ??= 1;
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:46:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c2?[0] ??= 1;
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:47:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c2?.[0] ??= 1 + c2[1];
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:47:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c2?[0] ??= 1 + c2[1];
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:58:16: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c2)?.[0] ??= 1;
-//                ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:58:17: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c2)?[0] ??= 1;
+//                 ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:59:16: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c2)?.[0] ??= 1 + Extension(c2)[1];
-//                ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:59:17: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c2)?[0] ??= 1 + Extension(c2)[1];
+//                 ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:70:12: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.field?.[0] ??= 1;
-//            ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:70:13: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?.field?[0] ??= 1;
+//             ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:71:12: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.field?.[0] ??= 1 + c1[1];
-//            ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:71:13: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?.field?[0] ??= 1 + c1[1];
+//             ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:82:23: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c1?.field)?.[0] ??= 1;
-//                       ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:82:24: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c1?.field)?[0] ??= 1;
+//                        ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:83:23: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c1?.field)?.[0] ??= 1 + Extension(c2)?.[1]!;
-//                       ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:83:24: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c1?.field)?[0] ??= 1 + Extension(c2)?[1]!;
+//                        ^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
index 111b12b..e1edbab 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
@@ -2,45 +2,45 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:33:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.[0] ??= 1;
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:33:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?[0] ??= 1;
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:34:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.[0] ??= 1 + c1[1];
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:34:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?[0] ??= 1 + c1[1];
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:46:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c2?.[0] ??= 1;
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:46:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c2?[0] ??= 1;
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:47:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c2?.[0] ??= 1 + c2[1];
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:47:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c2?[0] ??= 1 + c2[1];
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:58:16: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c2)?.[0] ??= 1;
-//                ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:58:17: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c2)?[0] ??= 1;
+//                 ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:59:16: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c2)?.[0] ??= 1 + Extension(c2)[1];
-//                ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:59:17: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c2)?[0] ??= 1 + Extension(c2)[1];
+//                 ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:70:12: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.field?.[0] ??= 1;
-//            ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:70:13: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?.field?[0] ??= 1;
+//             ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:71:12: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.field?.[0] ??= 1 + c1[1];
-//            ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:71:13: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?.field?[0] ??= 1 + c1[1];
+//             ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:82:23: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c1?.field)?.[0] ??= 1;
-//                       ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:82:24: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c1?.field)?[0] ??= 1;
+//                        ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:83:23: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c1?.field)?.[0] ??= 1 + Extension(c2)?.[1]!;
-//                       ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:83:24: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c1?.field)?[0] ??= 1 + Extension(c2)?[1]!;
+//                        ^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
index 111b12b..e1edbab 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
@@ -2,45 +2,45 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:33:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.[0] ??= 1;
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:33:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?[0] ??= 1;
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:34:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.[0] ??= 1 + c1[1];
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:34:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?[0] ??= 1 + c1[1];
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:46:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c2?.[0] ??= 1;
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:46:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c2?[0] ??= 1;
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:47:5: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c2?.[0] ??= 1 + c2[1];
-//     ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:47:6: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c2?[0] ??= 1 + c2[1];
+//      ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:58:16: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c2)?.[0] ??= 1;
-//                ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:58:17: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c2)?[0] ??= 1;
+//                 ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:59:16: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c2)?.[0] ??= 1 + Extension(c2)[1];
-//                ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:59:17: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c2)?[0] ??= 1 + Extension(c2)[1];
+//                 ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:70:12: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.field?.[0] ??= 1;
-//            ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:70:13: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?.field?[0] ??= 1;
+//             ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:71:12: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   c1?.field?.[0] ??= 1 + c1[1];
-//            ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:71:13: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   c1?.field?[0] ??= 1 + c1[1];
+//             ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:82:23: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c1?.field)?.[0] ??= 1;
-//                       ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:82:24: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c1?.field)?[0] ??= 1;
+//                        ^
 //
-// pkg/front_end/testcases/nnbd/null_shorting_index.dart:83:23: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
-//   Extension(c1?.field)?.[0] ??= 1 + Extension(c2)?.[1]!;
-//                       ^
+// pkg/front_end/testcases/nnbd/null_shorting_index.dart:83:24: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
+//   Extension(c1?.field)?[0] ??= 1 + Extension(c2)?[1]!;
+//                        ^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart
index a1d5321..48e08b3 100644
--- a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart
@@ -30,5 +30,5 @@
   String? s = null;
   dynamic c;
   c?..f;
-  c?.[0];
+  c?[0];
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.expect
index 8dc052e..1d469ae 100644
--- a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.expect
@@ -127,9 +127,13 @@
 //   c?..f;
 //      ^
 //
-// pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:37:6: Error: Expected an identifier, but got '['.
-//   c?.[0];
-//      ^
+// pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:37:5: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+//   c?[0];
+//     ^
+// pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.5
+// ^^^^^^^^^^^^
 //
 import self as self2;
 import "dart:core" as core;
@@ -170,9 +174,7 @@
   invalid-expression "pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:36:6: Error: Expected an identifier, but got ''.
   c?..f;
      ^".f;
-  invalid-expression "pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:37:6: Error: Expected an identifier, but got '['.
-  c?.[0];
-     ^";
+  let final dynamic #t3 = c in #t3.{core::Object::==}(null) ?{dynamic} null : #t3.[](0);
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.transformed.expect
index 8dc052e..1d469ae 100644
--- a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.transformed.expect
@@ -127,9 +127,13 @@
 //   c?..f;
 //      ^
 //
-// pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:37:6: Error: Expected an identifier, but got '['.
-//   c?.[0];
-//      ^
+// pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:37:5: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+//   c?[0];
+//     ^
+// pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.5
+// ^^^^^^^^^^^^
 //
 import self as self2;
 import "dart:core" as core;
@@ -170,9 +174,7 @@
   invalid-expression "pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:36:6: Error: Expected an identifier, but got ''.
   c?..f;
      ^".f;
-  invalid-expression "pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart:37:6: Error: Expected an identifier, but got '['.
-  c?.[0];
-     ^";
+  let final dynamic #t3 = c in #t3.{core::Object::==}(null) ?{dynamic} null : #t3.[](0);
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart b/pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart
index 99b935f9..0721435 100644
--- a/pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/opt_out_lib.dart
@@ -34,5 +34,5 @@
   var t = s!;
   dynamic c;
   c?..f;
-  c?.[0];
+  c?[0];
 }
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart b/pkg/front_end/testcases/regress/issue_31180.dart
index acf97d6..7109223 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart
+++ b/pkg/front_end/testcases/regress/issue_31180.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 bad() {
-  return null?.[1];
+  return null?[1];
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
index b503b42..9187650 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
@@ -2,15 +2,15 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
-//   return null?.[1];
-//                ^
+// pkg/front_end/testcases/regress/issue_31180.dart:6:15: Error: This requires the 'non-nullable' language feature to be enabled.
+// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.9 or higher, and running 'pub get'.
+//   return null?[1];
+//               ^
 //
 import self as self;
+import "dart:core" as core;
 
 static method bad() → dynamic {
-  return invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
-  return null?.[1];
-               ^";
+  return let final dynamic #t1 = null in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.[](1);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
index b503b42..20ed682 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
@@ -2,15 +2,15 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
-//   return null?.[1];
-//                ^
+// pkg/front_end/testcases/regress/issue_31180.dart:6:15: Error: This requires the 'non-nullable' language feature to be enabled.
+// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.9 or higher, and running 'pub get'.
+//   return null?[1];
+//               ^
 //
 import self as self;
+import "dart:core" as core;
 
 static method bad() → dynamic {
-  return invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
-  return null?.[1];
-               ^";
+  return let final<BottomType> #t1 = null in #t1.{core::Object::==}(null) ?{dynamic} null : #t1.[](1);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index a38ef25a..b1ab8a2 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -174,6 +174,7 @@
 nnbd/issue41180: RuntimeError # Strong mode runtime checking fails due to mixed strong mode.
 nnbd/issue42546: TypeCheckError
 nnbd/issue42603: TypeCheckError
+nnbd/no_support_for_old_null_aware_index_access_syntax: RuntimeError # Expected.
 nnbd/nullable_object_access: TypeCheckError
 nnbd/nullable_receiver: TypeCheckError
 nnbd/potentially_nullable_access: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index bac74e7..b1c53c0 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -172,6 +172,7 @@
 nnbd/issue41180: RuntimeError
 nnbd/issue42546: TypeCheckError
 nnbd/issue42603: TypeCheckError
+nnbd/no_support_for_old_null_aware_index_access_syntax: RuntimeError # Expected.
 nnbd/nullable_object_access: TypeCheckError
 nnbd/nullable_receiver: TypeCheckError
 nnbd/potentially_nullable_access: TypeCheckError
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 93d5a75..3526184 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -62,6 +62,7 @@
 nnbd/covariant_late_field: TypeCheckError
 nnbd/issue42546: TypeCheckError
 nnbd/issue42603: TypeCheckError
+nnbd/no_support_for_old_null_aware_index_access_syntax: RuntimeError # Expected.
 nnbd/nullable_object_access: TypeCheckError
 nnbd/nullable_receiver: TypeCheckError
 nnbd/potentially_nullable_access: TypeCheckError
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 0ecae65..b36cb0c 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -143,7 +143,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 44;
+  UInt32 formatVersion = 45;
   Byte[10] shortSdkHash;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
@@ -421,6 +421,7 @@
   // Only present if the 'isForwardingStub' flag is set.
   MemberReference forwardingStubSuperTarget; // May be NullReference.
   MemberReference forwardingStubInterfaceTarget; // May be NullReference.
+  MemberReference memberSignatureOrigin; // May be NullReference.
   // Can only be absent if abstract, but tag is there anyway.
   Option<FunctionNode> function;
 }
@@ -582,6 +583,7 @@
   Expression receiver;
   Name name;
   MemberReference interfaceTarget; // May be NullReference.
+  MemberReference interfaceTargetOrigin; // May be NullReference.
 }
 
 type PropertySet extends Expression {
@@ -591,6 +593,7 @@
   Name name;
   Expression value;
   MemberReference interfaceTarget; // May be NullReference.
+  MemberReference interfaceTargetOrigin; // May be NullReference.
 }
 
 type SuperPropertyGet extends Expression {
@@ -598,6 +601,7 @@
   FileOffset fileOffset;
   Name name;
   MemberReference interfaceTarget; // May be NullReference.
+  MemberReference interfaceTargetOrigin; // May be NullReference.
 }
 
 type SuperPropertySet extends Expression {
@@ -606,6 +610,7 @@
   Name name;
   Expression value;
   MemberReference interfaceTarget; // May be NullReference.
+  MemberReference interfaceTargetOrigin; // May be NullReference.
 }
 
 type DirectPropertyGet extends Expression {
@@ -613,6 +618,7 @@
   FileOffset fileOffset;
   Expression receiver;
   MemberReference target;
+  MemberReference targetOrigin; // May be NullReference.
 }
 
 type DirectPropertySet extends Expression {
@@ -620,6 +626,7 @@
   FileOffset fileOffset;
   Expression receiver;
   MemberReference target;
+  MemberReference targetOrigin; // May be NullReference.
   Expression value;
 }
 
@@ -657,6 +664,7 @@
   Name name;
   Arguments arguments;
   MemberReference interfaceTarget; // May be NullReference.
+  MemberReference interfaceTargetOrigin; // May be NullReference.
 }
 
 type SuperMethodInvocation extends Expression {
@@ -665,6 +673,7 @@
   Name name;
   Arguments arguments;
   MemberReference interfaceTarget; // May be NullReference.
+  MemberReference interfaceTargetOrigin; // May be NullReference.
 }
 
 type DirectMethodInvocation extends Expression {
@@ -672,6 +681,7 @@
   FileOffset fileOffset;
   Expression receiver;
   MemberReference target;
+  MemberReference targetOrigin; // May be NullReference.
   Arguments arguments;
 }
 
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index e1bf6e0..b34f51f 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1690,6 +1690,10 @@
   bool get containsSuperCalls {
     return transformerFlags & TransformerFlag.superCalls != 0;
   }
+
+  /// If this member is a member signature, [memberSignatureOrigin] is one of
+  /// the non-member signature members from which it was created.
+  Member get memberSignatureOrigin => null;
 }
 
 /// A field declaration.
@@ -2197,6 +2201,7 @@
 
   Reference forwardingStubSuperTargetReference;
   Reference forwardingStubInterfaceTargetReference;
+  Reference memberSignatureOriginReference;
 
   Procedure(Name name, ProcedureKind kind, FunctionNode function,
       {bool isAbstract: false,
@@ -2211,7 +2216,8 @@
       Uri fileUri,
       Reference reference,
       Member forwardingStubSuperTarget,
-      Member forwardingStubInterfaceTarget})
+      Member forwardingStubInterfaceTarget,
+      Member memberSignatureOrigin})
       : this._byReferenceRenamed(name, kind, function,
             isAbstract: isAbstract,
             isStatic: isStatic,
@@ -2227,7 +2233,9 @@
             forwardingStubSuperTargetReference:
                 getMemberReference(forwardingStubSuperTarget),
             forwardingStubInterfaceTargetReference:
-                getMemberReference(forwardingStubInterfaceTarget));
+                getMemberReference(forwardingStubInterfaceTarget),
+            memberSignatureOriginReference:
+                getMemberReference(memberSignatureOrigin));
 
   Procedure._byReferenceRenamed(Name name, this.kind, this.function,
       {bool isAbstract: false,
@@ -2242,7 +2250,8 @@
       Uri fileUri,
       Reference reference,
       this.forwardingStubSuperTargetReference,
-      this.forwardingStubInterfaceTargetReference})
+      this.forwardingStubInterfaceTargetReference,
+      this.memberSignatureOriginReference})
       : super(name, fileUri, reference) {
     function?.parent = this;
     this.isAbstract = isAbstract;
@@ -2254,6 +2263,13 @@
     this.isMemberSignature = isMemberSignature;
     this.isExtensionMember = isExtensionMember;
     this.transformerFlags = transformerFlags;
+    assert(!(isMemberSignature && memberSignatureOriginReference == null),
+        "No member signature origin for member signature $this.");
+    assert(
+        !(memberSignatureOrigin is Procedure &&
+            (memberSignatureOrigin as Procedure).isMemberSignature),
+        "Member signature origin cannot be a member signature "
+        "$memberSignatureOrigin for $this.");
   }
 
   static const int FlagStatic = 1 << 0; // Must match serialized bit positions.
@@ -2397,6 +2413,13 @@
     forwardingStubInterfaceTargetReference = getMemberReference(target);
   }
 
+  @override
+  Member get memberSignatureOrigin => memberSignatureOriginReference?.asMember;
+
+  void set memberSignatureOrigin(Member target) {
+    memberSignatureOriginReference = getMemberReference(target);
+  }
+
   R accept<R>(MemberVisitor<R> v) => v.visitProcedure(this);
 
   acceptReference(MemberReferenceVisitor v) => v.visitProcedureReference(this);
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index b5e70b6..d718a30 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -929,6 +929,12 @@
     return name?.getReference();
   }
 
+  Reference readInstanceMemberReference({bool allowNull: false}) {
+    var reference = readMemberReference(allowNull: allowNull);
+    readMemberReference(allowNull: true); // Skip origin
+    return reference;
+  }
+
   Reference getMemberReferenceFromInt(int index, {bool allowNull: false}) {
     var name = getCanonicalNameReferenceFromInt(index);
     if (name == null && !allowNull) {
@@ -1414,6 +1420,7 @@
         readMemberReference(allowNull: true);
     var forwardingStubInterfaceTargetReference =
         readMemberReference(allowNull: true);
+    var memberSignatureTargetReference = readMemberReference(allowNull: true);
     var function = readFunctionNodeOption(!readFunctionNodeNow, endOffset);
     var transformerFlags = getAndResetTransformerFlags();
     assert(((_) => true)(debugPath.removeLast()));
@@ -1432,10 +1439,14 @@
         forwardingStubSuperTargetReference;
     node.forwardingStubInterfaceTargetReference =
         forwardingStubInterfaceTargetReference;
+    node.memberSignatureOriginReference = memberSignatureTargetReference;
 
     assert((node.forwardingStubSuperTargetReference != null) ||
         !(node.isForwardingStub && node.function.body != null));
-    _byteOffset = endOffset;
+    assert(
+        !(node.isMemberSignature &&
+            node.memberSignatureOriginReference == null),
+        "No member signature origin for member signature $node.");
     return node;
   }
 
@@ -1689,35 +1700,35 @@
           ..fileOffset = offset;
       case Tag.PropertyGet:
         int offset = readOffset();
-        return new PropertyGet.byReference(
-            readExpression(), readName(), readMemberReference(allowNull: true))
+        return new PropertyGet.byReference(readExpression(), readName(),
+            readInstanceMemberReference(allowNull: true))
           ..fileOffset = offset;
       case Tag.PropertySet:
         int offset = readOffset();
         return new PropertySet.byReference(readExpression(), readName(),
-            readExpression(), readMemberReference(allowNull: true))
+            readExpression(), readInstanceMemberReference(allowNull: true))
           ..fileOffset = offset;
       case Tag.SuperPropertyGet:
         int offset = readOffset();
         addTransformerFlag(TransformerFlag.superCalls);
         return new SuperPropertyGet.byReference(
-            readName(), readMemberReference(allowNull: true))
+            readName(), readInstanceMemberReference(allowNull: true))
           ..fileOffset = offset;
       case Tag.SuperPropertySet:
         int offset = readOffset();
         addTransformerFlag(TransformerFlag.superCalls);
-        return new SuperPropertySet.byReference(
-            readName(), readExpression(), readMemberReference(allowNull: true))
+        return new SuperPropertySet.byReference(readName(), readExpression(),
+            readInstanceMemberReference(allowNull: true))
           ..fileOffset = offset;
       case Tag.DirectPropertyGet:
         int offset = readOffset();
         return new DirectPropertyGet.byReference(
-            readExpression(), readMemberReference())
+            readExpression(), readInstanceMemberReference())
           ..fileOffset = offset;
       case Tag.DirectPropertySet:
         int offset = readOffset();
         return new DirectPropertySet.byReference(
-            readExpression(), readMemberReference(), readExpression())
+            readExpression(), readInstanceMemberReference(), readExpression())
           ..fileOffset = offset;
       case Tag.StaticGet:
         int offset = readOffset();
@@ -1731,18 +1742,18 @@
       case Tag.MethodInvocation:
         int offset = readOffset();
         return new MethodInvocation.byReference(readExpression(), readName(),
-            readArguments(), readMemberReference(allowNull: true))
+            readArguments(), readInstanceMemberReference(allowNull: true))
           ..fileOffset = offset;
       case Tag.SuperMethodInvocation:
         int offset = readOffset();
         addTransformerFlag(TransformerFlag.superCalls);
-        return new SuperMethodInvocation.byReference(
-            readName(), readArguments(), readMemberReference(allowNull: true))
+        return new SuperMethodInvocation.byReference(readName(),
+            readArguments(), readInstanceMemberReference(allowNull: true))
           ..fileOffset = offset;
       case Tag.DirectMethodInvocation:
         int offset = readOffset();
         return new DirectMethodInvocation.byReference(
-            readExpression(), readMemberReference(), readArguments())
+            readExpression(), readInstanceMemberReference(), readArguments())
           ..fileOffset = offset;
       case Tag.StaticInvocation:
         int offset = readOffset();
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index dc3be1e..7654469 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -834,6 +834,12 @@
     writeUInt30(index);
   }
 
+  void writeNullAllowedInstanceMemberReference(Reference reference) {
+    writeNullAllowedReference(reference);
+    Member member = reference?.asMember;
+    writeNullAllowedReference(member?.memberSignatureOrigin?.reference);
+  }
+
   void writeNullAllowedReference(Reference reference) {
     if (reference == null) {
       writeUInt30(0);
@@ -847,6 +853,12 @@
     }
   }
 
+  void writeNonNullInstanceMemberReference(Reference reference) {
+    writeNonNullReference(reference);
+    Member member = reference.asMember;
+    writeNullAllowedReference(member?.memberSignatureOrigin?.reference);
+  }
+
   void writeNonNullReference(Reference reference) {
     if (reference == null) {
       throw new ArgumentError('Got null reference');
@@ -1175,6 +1187,11 @@
 
   @override
   void visitProcedure(Procedure node) {
+    assert(
+        !(node.isMemberSignature &&
+            node.memberSignatureOriginReference == null),
+        "No member signature origin for member signature $node.");
+
     procedureOffsets.add(getBufferOffset());
 
     if (node.canonicalName == null) {
@@ -1200,6 +1217,7 @@
     writeAnnotationList(node.annotations);
     writeNullAllowedReference(node.forwardingStubSuperTargetReference);
     writeNullAllowedReference(node.forwardingStubInterfaceTargetReference);
+    writeNullAllowedReference(node.memberSignatureOriginReference);
     writeOptionalFunctionNode(node.function);
     leaveScope(memberScope: true);
 
@@ -1381,7 +1399,7 @@
     writeOffset(node.fileOffset);
     writeNode(node.receiver);
     writeName(node.name);
-    writeNullAllowedReference(node.interfaceTargetReference);
+    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1391,7 +1409,7 @@
     writeNode(node.receiver);
     writeName(node.name);
     writeNode(node.value);
-    writeNullAllowedReference(node.interfaceTargetReference);
+    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1399,7 +1417,7 @@
     writeByte(Tag.SuperPropertyGet);
     writeOffset(node.fileOffset);
     writeName(node.name);
-    writeNullAllowedReference(node.interfaceTargetReference);
+    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1408,7 +1426,7 @@
     writeOffset(node.fileOffset);
     writeName(node.name);
     writeNode(node.value);
-    writeNullAllowedReference(node.interfaceTargetReference);
+    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1416,7 +1434,7 @@
     writeByte(Tag.DirectPropertyGet);
     writeOffset(node.fileOffset);
     writeNode(node.receiver);
-    writeNonNullReference(node.targetReference);
+    writeNonNullInstanceMemberReference(node.targetReference);
   }
 
   @override
@@ -1424,7 +1442,7 @@
     writeByte(Tag.DirectPropertySet);
     writeOffset(node.fileOffset);
     writeNode(node.receiver);
-    writeNonNullReference(node.targetReference);
+    writeNonNullInstanceMemberReference(node.targetReference);
     writeNode(node.value);
   }
 
@@ -1450,7 +1468,7 @@
     writeNode(node.receiver);
     writeName(node.name);
     writeArgumentsNode(node.arguments);
-    writeNullAllowedReference(node.interfaceTargetReference);
+    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1459,7 +1477,7 @@
     writeOffset(node.fileOffset);
     writeName(node.name);
     writeArgumentsNode(node.arguments);
-    writeNullAllowedReference(node.interfaceTargetReference);
+    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1467,7 +1485,7 @@
     writeByte(Tag.DirectMethodInvocation);
     writeOffset(node.fileOffset);
     writeNode(node.receiver);
-    writeNonNullReference(node.targetReference);
+    writeNonNullInstanceMemberReference(node.targetReference);
     writeArgumentsNode(node.arguments);
   }
 
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index f23d4ca..a70bec0 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -149,7 +149,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 44;
+  static const int BinaryFormatVersion = 45;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 6b4328a..6b7bbad 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -664,7 +664,8 @@
         transformerFlags: node.transformerFlags,
         fileUri: _activeFileUri,
         forwardingStubSuperTarget: node.forwardingStubSuperTarget,
-        forwardingStubInterfaceTarget: node.forwardingStubInterfaceTarget)
+        forwardingStubInterfaceTarget: node.forwardingStubInterfaceTarget,
+        memberSignatureOrigin: node.memberSignatureOrigin)
       ..annotations = cloneAnnotations && !node.annotations.isEmpty
           ? node.annotations.map(super.clone).toList()
           : const <Expression>[]
diff --git a/runtime/bin/snapshot_utils.cc b/runtime/bin/snapshot_utils.cc
index ed6b491a..d31be2d 100644
--- a/runtime/bin/snapshot_utils.cc
+++ b/runtime/bin/snapshot_utils.cc
@@ -468,6 +468,7 @@
   dfe.ReadScript(script_name, &kernel_buffer, &kernel_buffer_size);
   if (kernel_buffer != NULL) {
     WriteSnapshotFile(snapshot_filename, kernel_buffer, kernel_buffer_size);
+    free(kernel_buffer);
   } else {
     Dart_KernelCompilationResult result =
         dfe.CompileScript(script_name, false, package_config);
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index 2d1515f..0edfb70 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -4,8 +4,10 @@
 
 #include "vm/compiler/assembler/disassembler.h"
 
+#include "platform/text_buffer.h"
 #include "platform/unaligned.h"
 #include "vm/code_patcher.h"
+#include "vm/dart_entry.h"
 #include "vm/deopt_instructions.h"
 #include "vm/globals.h"
 #include "vm/instructions.h"
@@ -215,6 +217,7 @@
 }
 
 void Disassembler::DisassembleCodeHelper(const char* function_fullname,
+                                         const char* function_info,
                                          const Code& code,
                                          bool optimized) {
   Zone* zone = Thread::Current()->zone();
@@ -222,8 +225,8 @@
   if (FLAG_print_variable_descriptors) {
     var_descriptors = code.GetLocalVarDescriptors();
   }
-  THR_Print("Code for %sfunction '%s' {\n", optimized ? "optimized " : "",
-            function_fullname);
+  THR_Print("Code for %sfunction '%s' (%s) {\n", optimized ? "optimized " : "",
+            function_fullname, function_info);
   code.Disassemble();
   THR_Print("}\n");
 
@@ -450,9 +453,18 @@
 void Disassembler::DisassembleCode(const Function& function,
                                    const Code& code,
                                    bool optimized) {
+  TextBuffer buffer(128);
   const char* function_fullname = function.ToFullyQualifiedCString();
+  buffer.Printf("%s", Function::KindToCString(function.kind()));
+  if (function.IsInvokeFieldDispatcher() ||
+      function.IsNoSuchMethodDispatcher()) {
+    const auto& args_desc_array = Array::Handle(function.saved_args_desc());
+    const ArgumentsDescriptor args_desc(args_desc_array);
+    buffer.AddString(", ");
+    args_desc.PrintTo(&buffer);
+  }
   LogBlock lb;
-  DisassembleCodeHelper(function_fullname, code, optimized);
+  DisassembleCodeHelper(function_fullname, buffer.buffer(), code, optimized);
 }
 
 void Disassembler::DisassembleStub(const char* name, const Code& code) {
diff --git a/runtime/vm/compiler/assembler/disassembler.h b/runtime/vm/compiler/assembler/disassembler.h
index 4a86177..dde4e49 100644
--- a/runtime/vm/compiler/assembler/disassembler.h
+++ b/runtime/vm/compiler/assembler/disassembler.h
@@ -191,6 +191,7 @@
 
  private:
   static void DisassembleCodeHelper(const char* function_fullname,
+                                    const char* function_info,
                                     const Code& code,
                                     bool optimized);
 
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index b326057..3f921d2 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -52,7 +52,17 @@
 
 void FlowGraphPrinter::PrintBlocks() {
   if (!function_.IsNull()) {
-    THR_Print("==== %s\n", function_.ToFullyQualifiedCString());
+    THR_Print("==== %s (%s", function_.ToFullyQualifiedCString(),
+              Function::KindToCString(function_.kind()));
+    // Output saved arguments descriptor information for dispatchers that
+    // have it, so it's easy to see which dispatcher this graph represents.
+    if (function_.IsInvokeFieldDispatcher() ||
+        function_.IsNoSuchMethodDispatcher()) {
+      const auto& args_desc_array = Array::Handle(function_.saved_args_desc());
+      const ArgumentsDescriptor args_desc(args_desc_array);
+      THR_Print(", %s", args_desc.ToCString());
+    }
+    THR_Print(")\n");
   }
 
   for (intptr_t i = 0; i < block_order_.length(); ++i) {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index ee3a6bb..01bade0 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -2308,7 +2308,7 @@
   const Function* interface_target = &Function::null_function();
   const Function* tearoff_interface_target = &Function::null_function();
   const NameIndex itarget_name =
-      ReadCanonicalNameReference();  // read interface_target_reference.
+      ReadInterfaceMemberNameReference();  // read interface_target_reference.
   if (!H.IsRoot(itarget_name) &&
       (H.IsGetter(itarget_name) || H.IsField(itarget_name))) {
     interface_target = &Function::ZoneHandle(
@@ -2401,7 +2401,7 @@
 
   const Function* interface_target = &Function::null_function();
   const NameIndex itarget_name =
-      ReadCanonicalNameReference();  // read interface_target_reference.
+      ReadInterfaceMemberNameReference();  // read interface_target_reference.
   if (!H.IsRoot(itarget_name)) {
     interface_target = &Function::ZoneHandle(
         Z,
@@ -2536,7 +2536,7 @@
   const String& getter_name = H.DartGetterName(library_reference, name_index);
   const String& method_name = H.DartMethodName(library_reference, name_index);
 
-  SkipCanonicalNameReference();  // skip target_reference.
+  SkipInterfaceMemberNameReference();  // skip target_reference.
 
   // Search the superclass chain for the selector looking for either getter or
   // method.
@@ -2627,7 +2627,7 @@
         /* argument_names = */ Object::empty_array(), actuals_array,
         build_rest_of_actuals);
 
-    SkipCanonicalNameReference();  // skip target_reference.
+    SkipInterfaceMemberNameReference();  // skip target_reference.
 
     Function& nsm_function = GetNoSuchMethodOrDie(Z, klass);
     instructions +=
@@ -2642,7 +2642,7 @@
     instructions += BuildExpression();  // read value.
     instructions += StoreLocal(position, value);
 
-    SkipCanonicalNameReference();  // skip target_reference.
+    SkipInterfaceMemberNameReference();  // skip target_reference.
 
     instructions += StaticCall(
         position, Function::ZoneHandle(Z, function.raw()),
@@ -2666,7 +2666,7 @@
   const Tag receiver_tag = PeekTag();         // peek tag for receiver.
   Fragment instructions = BuildExpression();  // read receiver.
   const NameIndex kernel_name =
-      ReadCanonicalNameReference();  // read target_reference.
+      ReadInterfaceMemberNameReference();  // read target_reference.
 
   Function& target = Function::ZoneHandle(Z);
   if (H.IsProcedure(kernel_name)) {
@@ -2720,7 +2720,7 @@
   instructions += BuildExpression();  // read receiver.
 
   const NameIndex target_reference =
-      ReadCanonicalNameReference();  // read target_reference.
+      ReadInterfaceMemberNameReference();  // read target_reference.
   const String& method_name = H.DartSetterName(target_reference);
   const Function& target = Function::ZoneHandle(
       Z, H.LookupMethodByMember(target_reference, method_name));
@@ -2924,7 +2924,7 @@
     instructions +=
         BuildArguments(NULL /* named */, NULL /* arg count */,
                        NULL /* positional arg count */);  // read arguments.
-    SkipCanonicalNameReference();          // read interface_target_reference.
+    SkipInterfaceMemberNameReference();  // read interface_target_reference.
     Token::Kind strict_cmp_kind =
         token_kind == Token::kEQ ? Token::kEQ_STRICT : Token::kNE_STRICT;
     return instructions +
@@ -2964,7 +2964,7 @@
 
   const Function* interface_target = &Function::null_function();
   const NameIndex itarget_name =
-      ReadCanonicalNameReference();  // read interface_target_reference.
+      ReadInterfaceMemberNameReference();  // read interface_target_reference.
   // TODO(dartbug.com/34497): Once front-end desugars calls via
   // fields/getters, filtering of field and getter interface targets here
   // can be turned into assertions.
@@ -3066,7 +3066,7 @@
   {
     AlternativeReadingScope alt(&reader_);
     SkipExpression();                         // skip receiver
-    ReadCanonicalNameReference();             // skip target reference
+    ReadInterfaceMemberNameReference();       // skip target reference
     ReadUInt();                               // read argument count.
     intptr_t list_length = ReadListLength();  // read types list length.
     if (list_length > 0) {
@@ -3080,7 +3080,7 @@
   instructions += BuildExpression();  // read receiver.
 
   NameIndex kernel_name =
-      ReadCanonicalNameReference();  // read target_reference.
+      ReadInterfaceMemberNameReference();  // read target_reference.
   const String& method_name = H.DartProcedureName(kernel_name);
   const Token::Kind token_kind =
       MethodTokenRecognizer::RecognizeTokenKind(method_name);
@@ -3215,7 +3215,7 @@
         /* num_arguments = */ argument_count + 1, argument_names, actuals_array,
         build_rest_of_actuals);
 
-    SkipCanonicalNameReference();  //  skip target_reference.
+    SkipInterfaceMemberNameReference();  //  skip target_reference.
 
     Function& nsm_function = GetNoSuchMethodOrDie(Z, klass);
     instructions += StaticCall(TokenPosition::kNoSource,
@@ -3246,7 +3246,7 @@
         &argument_names, &argument_count,
         /* positional_argument_count = */ NULL);  // read arguments.
     ++argument_count;                             // include receiver
-    SkipCanonicalNameReference();                 // interfaceTargetReference
+    SkipInterfaceMemberNameReference();           // interfaceTargetReference
     return instructions +
            StaticCall(position, Function::ZoneHandle(Z, function.raw()),
                       argument_count, argument_names, ICData::kSuper,
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 5b16ddd..1b53cde 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -47,6 +47,7 @@
   void CalculateTypeParameterFingerprint();
   void CalculateTypeParametersListFingerprint();
   void CalculateCanonicalNameFingerprint();
+  void CalculateInterfaceMemberNameFingerprint();
   void CalculateInitializerFingerprint();
   void CalculateDartTypeFingerprint();
   void CalculateOptionalDartTypeFingerprint();
@@ -187,6 +188,11 @@
   BuildHash(H.DartString(i).Hash());
 }
 
+void KernelFingerprintHelper::CalculateInterfaceMemberNameFingerprint() {
+  CalculateCanonicalNameFingerprint();
+  ReadCanonicalNameReference();  // read target_origin_reference
+}
+
 void KernelFingerprintHelper::CalculateInitializerFingerprint() {
   Tag tag = ReadTag();
   ReadByte();  // read isSynthetic flag.
@@ -320,6 +326,7 @@
   if (!H.IsRoot(name) && (H.IsGetter(name) || H.IsField(name))) {
     BuildHash(H.DartGetterName(name).Hash());
   }
+  ReadCanonicalNameReference();  // read interface_target_origin_reference
 }
 
 void KernelFingerprintHelper::CalculateSetterNameFingerprint() {
@@ -327,6 +334,7 @@
   if (!H.IsRoot(name)) {
     BuildHash(H.DartSetterName(name).Hash());
   }
+  ReadCanonicalNameReference();  // read interface_target_origin_reference
 }
 
 void KernelFingerprintHelper::CalculateMethodNameFingerprint() {
@@ -335,6 +343,7 @@
   if (!H.IsRoot(name) && !H.IsField(name)) {
     BuildHash(H.DartProcedureName(name).Hash());
   }
+  ReadCanonicalNameReference();  // read interface_target_origin_reference
 }
 
 void KernelFingerprintHelper::CalculateExpressionFingerprint() {
@@ -394,12 +403,12 @@
     case kDirectPropertyGet:
       ReadPosition();                       // read position.
       CalculateExpressionFingerprint();     // read receiver.
-      CalculateCanonicalNameFingerprint();  // read target_reference.
+      CalculateInterfaceMemberNameFingerprint();  // read target_reference.
       return;
     case kDirectPropertySet:
       ReadPosition();                       // read position.
       CalculateExpressionFingerprint();     // read receiver.
-      CalculateCanonicalNameFingerprint();  // read target_reference.
+      CalculateInterfaceMemberNameFingerprint();  // read target_reference.
       CalculateExpressionFingerprint();     // read value·
       return;
     case kStaticGet:
@@ -422,12 +431,12 @@
       ReadPosition();                            // read position.
       BuildHash(ReadNameAsMethodName().Hash());  // read name.
       CalculateArgumentsFingerprint();           // read arguments.
-      CalculateCanonicalNameFingerprint();       // read target_reference.
+      CalculateInterfaceMemberNameFingerprint();  // read target_reference.
       return;
     case kDirectMethodInvocation:
       ReadPosition();                       // read position.
       CalculateExpressionFingerprint();     // read receiver.
-      CalculateCanonicalNameFingerprint();  // read target_reference.
+      CalculateInterfaceMemberNameFingerprint();  // read target_reference.
       CalculateArgumentsFingerprint();      // read arguments.
       return;
     case kStaticInvocation:
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 4812287..a1ea46f 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1099,6 +1099,10 @@
       helper_->ReadCanonicalNameReference();
       if (++next_read_ == field) return;
       FALL_THROUGH;
+    case kMemberSignatureTarget:
+      helper_->ReadCanonicalNameReference();
+      if (++next_read_ == field) return;
+      FALL_THROUGH;
     case kFunction:
       if (helper_->ReadTag() == kSomething) {
         helper_->SkipFunctionNode();  // read function node.
@@ -1995,6 +1999,13 @@
   return reader_.ReadCanonicalNameReference();
 }
 
+NameIndex KernelReaderHelper::ReadInterfaceMemberNameReference() {
+  NameIndex name_index = reader_.ReadCanonicalNameReference();
+  reader_
+      .ReadCanonicalNameReference();  // read interface target origin reference
+  return name_index;
+}
+
 StringIndex KernelReaderHelper::ReadNameAsStringIndex() {
   StringIndex name_index = ReadStringReference();  // read name index.
   if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
@@ -2063,6 +2074,11 @@
   ReadUInt();
 }
 
+void KernelReaderHelper::SkipInterfaceMemberNameReference() {
+  SkipCanonicalNameReference();
+  SkipCanonicalNameReference();
+}
+
 void KernelReaderHelper::ReportUnexpectedTag(const char* variant, Tag tag) {
   FATAL3("Unexpected tag %d (%s) in ?, expected %s", tag, Reader::TagName(tag),
          variant);
@@ -2286,35 +2302,35 @@
       ReadPosition();                // read position.
       SkipExpression();              // read receiver.
       SkipName();                    // read name.
-      SkipCanonicalNameReference();  // read interface_target_reference.
+      SkipInterfaceMemberNameReference();  // read interface_target_reference.
       return;
     case kPropertySet:
       ReadPosition();                // read position.
       SkipExpression();              // read receiver.
       SkipName();                    // read name.
       SkipExpression();              // read value.
-      SkipCanonicalNameReference();  // read interface_target_reference.
+      SkipInterfaceMemberNameReference();  // read interface_target_reference.
       return;
     case kSuperPropertyGet:
       ReadPosition();                // read position.
       SkipName();                    // read name.
-      SkipCanonicalNameReference();  // read interface_target_reference.
+      SkipInterfaceMemberNameReference();  // read interface_target_reference.
       return;
     case kSuperPropertySet:
       ReadPosition();                // read position.
       SkipName();                    // read name.
       SkipExpression();              // read value.
-      SkipCanonicalNameReference();  // read interface_target_reference.
+      SkipInterfaceMemberNameReference();  // read interface_target_reference.
       return;
     case kDirectPropertyGet:
       ReadPosition();                // read position.
       SkipExpression();              // read receiver.
-      SkipCanonicalNameReference();  // read target_reference.
+      SkipInterfaceMemberNameReference();  // read target_reference.
       return;
     case kDirectPropertySet:
       ReadPosition();                // read position.
       SkipExpression();              // read receiver.
-      SkipCanonicalNameReference();  // read target_reference.
+      SkipInterfaceMemberNameReference();  // read target_reference.
       SkipExpression();              // read value·
       return;
     case kStaticGet:
@@ -2331,18 +2347,18 @@
       SkipExpression();              // read receiver.
       SkipName();                    // read name.
       SkipArguments();               // read arguments.
-      SkipCanonicalNameReference();  // read interface_target_reference.
+      SkipInterfaceMemberNameReference();  // read interface_target_reference.
       return;
     case kSuperMethodInvocation:
       ReadPosition();                // read position.
       SkipName();                    // read name.
       SkipArguments();               // read arguments.
-      SkipCanonicalNameReference();  // read interface_target_reference.
+      SkipInterfaceMemberNameReference();  // read interface_target_reference.
       return;
     case kDirectMethodInvocation:
       ReadPosition();                // read position.
       SkipExpression();              // read receiver.
-      SkipCanonicalNameReference();  // read target_reference.
+      SkipInterfaceMemberNameReference();  // read target_reference.
       SkipArguments();               // read arguments.
       return;
     case kStaticInvocation:
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index e2c8540a..f05d261 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -523,6 +523,7 @@
     kAnnotations,
     kForwardingStubSuperTarget,
     kForwardingStubInterfaceTarget,
+    kMemberSignatureTarget,
     kFunction,
     kEnd,
   };
@@ -1200,6 +1201,7 @@
   uint32_t PeekListLength();
   StringIndex ReadStringReference();
   NameIndex ReadCanonicalNameReference();
+  NameIndex ReadInterfaceMemberNameReference();
   StringIndex ReadNameAsStringIndex();
   const String& ReadNameAsMethodName();
   const String& ReadNameAsGetterName();
@@ -1209,6 +1211,7 @@
   void SkipStringReference();
   void SkipConstantReference();
   void SkipCanonicalNameReference();
+  void SkipInterfaceMemberNameReference();
   void SkipDartType();
   void SkipOptionalDartType();
   void SkipInterfaceType(bool simple);
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index fd73901..72d7ead 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -721,7 +721,7 @@
       VisitExpression();       // read receiver.
       helper_.SkipName();      // read name.
       // read interface_target_reference.
-      helper_.SkipCanonicalNameReference();
+      helper_.SkipInterfaceMemberNameReference();
       return;
     case kPropertySet:
       helper_.ReadPosition();  // read position.
@@ -729,31 +729,31 @@
       helper_.SkipName();      // read name.
       VisitExpression();       // read value.
       // read interface_target_reference.
-      helper_.SkipCanonicalNameReference();
+      helper_.SkipInterfaceMemberNameReference();
       return;
     case kDirectPropertyGet:
       helper_.ReadPosition();                // read position.
       VisitExpression();                     // read receiver.
-      helper_.SkipCanonicalNameReference();  // read target_reference.
+      helper_.SkipInterfaceMemberNameReference();  // read target_reference.
       return;
     case kDirectPropertySet:
       helper_.ReadPosition();                // read position.
       VisitExpression();                     // read receiver.
-      helper_.SkipCanonicalNameReference();  // read target_reference.
+      helper_.SkipInterfaceMemberNameReference();  // read target_reference.
       VisitExpression();                     // read value·
       return;
     case kSuperPropertyGet:
       HandleLoadReceiver();
       helper_.ReadPosition();                // read position.
       helper_.SkipName();                    // read name.
-      helper_.SkipCanonicalNameReference();  // read target_reference.
+      helper_.SkipInterfaceMemberNameReference();  // read target_reference.
       return;
     case kSuperPropertySet:
       HandleLoadReceiver();
       helper_.ReadPosition();                // read position.
       helper_.SkipName();                    // read name.
       VisitExpression();                     // read value.
-      helper_.SkipCanonicalNameReference();  // read target_reference.
+      helper_.SkipInterfaceMemberNameReference();  // read target_reference.
       return;
     case kStaticGet:
       helper_.ReadPosition();                // read position.
@@ -770,12 +770,12 @@
       helper_.SkipName();      // read name.
       VisitArguments();        // read arguments.
       // read interface_target_reference.
-      helper_.SkipCanonicalNameReference();
+      helper_.SkipInterfaceMemberNameReference();
       return;
     case kDirectMethodInvocation:
       helper_.ReadPosition();                // read position.
       VisitExpression();                     // read receiver.
-      helper_.SkipCanonicalNameReference();  // read target_reference.
+      helper_.SkipInterfaceMemberNameReference();  // read target_reference.
       VisitArguments();                      // read arguments.
       return;
     case kSuperMethodInvocation:
@@ -784,7 +784,7 @@
       helper_.SkipName();      // read name.
       VisitArguments();        // read arguments.
       // read interface_target_reference.
-      helper_.SkipCanonicalNameReference();
+      helper_.SkipInterfaceMemberNameReference();
       return;
     case kStaticInvocation:
       helper_.ReadPosition();                // read position.
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index f60c17b..8cb10d9 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -16,6 +16,7 @@
 #include "vm/simulator.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
+#include "vm/zone_text_buffer.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/compiler/frontend/bytecode_reader.h"
@@ -432,6 +433,32 @@
   return names.raw();
 }
 
+void ArgumentsDescriptor::PrintTo(BaseTextBuffer* buffer) const {
+  buffer->Printf("%" Pd " arg%s", Count(), Count() == 1 ? "" : "s");
+  if (TypeArgsLen() > 0) {
+    buffer->Printf(", %" Pd " type arg%s", TypeArgsLen(),
+                   TypeArgsLen() == 1 ? "" : "s");
+  }
+  if (NamedCount() > 0) {
+    buffer->AddString(", names [");
+    auto& str = String::Handle();
+    for (intptr_t i = 0; i < NamedCount(); i++) {
+      if (i != 0) {
+        buffer->AddString(", ");
+      }
+      str = NameAt(i);
+      buffer->Printf("'%s'", str.ToCString());
+    }
+    buffer->Printf("]");
+  }
+}
+
+const char* ArgumentsDescriptor::ToCString() const {
+  ZoneTextBuffer buf(Thread::Current()->zone());
+  PrintTo(&buf);
+  return buf.buffer();
+}
+
 ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
                                   intptr_t num_arguments,
                                   intptr_t size_arguments,
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index f635cb2..01f4d1a 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -46,6 +46,8 @@
   bool MatchesNameAt(intptr_t i, const String& other) const;
   // Returns array of argument names in the arguments order.
   ArrayPtr GetArgumentNames() const;
+  void PrintTo(BaseTextBuffer* buffer) const;
+  const char* ToCString() const;
 
   // Generated code support.
   static intptr_t type_args_len_offset() {
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 01e34ab..bc9203b 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,8 +20,8 @@
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
 
 // Both version numbers are inclusive.
-static const uint32_t kMinSupportedKernelFormatVersion = 44;
-static const uint32_t kMaxSupportedKernelFormatVersion = 44;
+static const uint32_t kMinSupportedKernelFormatVersion = 45;
+static const uint32_t kMaxSupportedKernelFormatVersion = 45;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 58327ce..66ccafa 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -9682,65 +9682,76 @@
 }
 
 const char* Function::ToCString() const {
-  NoSafepointScope no_safepoint;
   if (IsNull()) {
     return "Function: null";
   }
-  const char* static_str = is_static() ? " static" : "";
-  const char* abstract_str = is_abstract() ? " abstract" : "";
-  const char* kind_str = NULL;
-  const char* const_str = is_const() ? " const" : "";
+  Zone* zone = Thread::Current()->zone();
+  ZoneTextBuffer buffer(zone);
+  buffer.Printf("Function '%s':", String::Handle(zone, name()).ToCString());
+  if (is_static()) {
+    buffer.AddString(" static");
+  }
+  if (is_abstract()) {
+    buffer.AddString(" abstract");
+  }
   switch (kind()) {
     case FunctionLayout::kRegularFunction:
     case FunctionLayout::kClosureFunction:
     case FunctionLayout::kImplicitClosureFunction:
     case FunctionLayout::kGetterFunction:
     case FunctionLayout::kSetterFunction:
-      kind_str = "";
       break;
     case FunctionLayout::kSignatureFunction:
-      kind_str = " signature";
+      buffer.AddString(" signature");
       break;
     case FunctionLayout::kConstructor:
-      kind_str = is_static() ? " factory" : " constructor";
+      buffer.AddString(is_static() ? " factory" : " constructor");
       break;
     case FunctionLayout::kImplicitGetter:
-      kind_str = " getter";
+      buffer.AddString(" getter");
       break;
     case FunctionLayout::kImplicitSetter:
-      kind_str = " setter";
+      buffer.AddString(" setter");
       break;
     case FunctionLayout::kImplicitStaticGetter:
-      kind_str = " static-getter";
+      buffer.AddString(" static-getter");
       break;
     case FunctionLayout::kFieldInitializer:
-      kind_str = " field-initializer";
+      buffer.AddString(" field-initializer");
       break;
     case FunctionLayout::kMethodExtractor:
-      kind_str = " method-extractor";
+      buffer.AddString(" method-extractor");
       break;
     case FunctionLayout::kNoSuchMethodDispatcher:
-      kind_str = " no-such-method-dispatcher";
+      buffer.AddString(" no-such-method-dispatcher");
       break;
     case FunctionLayout::kDynamicInvocationForwarder:
-      kind_str = " dynamic-invocation-forwarder";
+      buffer.AddString(" dynamic-invocation-forwarder");
       break;
     case FunctionLayout::kInvokeFieldDispatcher:
-      kind_str = " invoke-field-dispatcher";
+      buffer.AddString(" invoke-field-dispatcher");
       break;
     case FunctionLayout::kIrregexpFunction:
-      kind_str = " irregexp-function";
+      buffer.AddString(" irregexp-function");
       break;
     case FunctionLayout::kFfiTrampoline:
-      kind_str = " ffi-trampoline-function";
+      buffer.AddString(" ffi-trampoline-function");
       break;
     default:
       UNREACHABLE();
   }
-  const char* function_name = String::Handle(name()).ToCString();
-  return OS::SCreate(Thread::Current()->zone(), "Function '%s':%s%s%s%s.",
-                     function_name, static_str, abstract_str, kind_str,
-                     const_str);
+  if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher()) {
+    const auto& args_desc_array = Array::Handle(zone, saved_args_desc());
+    const ArgumentsDescriptor args_desc(args_desc_array);
+    buffer.AddChar('[');
+    args_desc.PrintTo(&buffer);
+    buffer.AddChar(']');
+  }
+  if (is_const()) {
+    buffer.AddString(" const");
+  }
+  buffer.AddChar('.');
+  return buffer.buffer();
 }
 
 void ClosureData::set_context_scope(const ContextScope& value) const {
diff --git a/samples/ffi/sqlite/.gitignore b/samples/ffi/sqlite/.gitignore
index 7a6bc2e..61f2cb6 100644
--- a/samples/ffi/sqlite/.gitignore
+++ b/samples/ffi/sqlite/.gitignore
@@ -4,4 +4,4 @@
 .vscode
 pubspec.lock
 test.db
-test.db-journal
\ No newline at end of file
+test.db-journal
diff --git a/samples/ffi/sqlite/lib/src/bindings/bindings.dart b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
deleted file mode 100644
index 0271506..0000000
--- a/samples/ffi/sqlite/lib/src/bindings/bindings.dart
+++ /dev/null
@@ -1,394 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:ffi";
-import "package:ffi/ffi.dart";
-
-import "../ffi/dylib_utils.dart";
-
-import "signatures.dart";
-import "types.dart";
-
-class _SQLiteBindings {
-  DynamicLibrary sqlite;
-
-  /// Opening A New Database Connection
-  ///
-  /// ^These routines open an SQLite database file as specified by the
-  /// filename argument. ^The filename argument is interpreted as UTF-8 for
-  /// sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
-  /// order for sqlite3_open16(). ^(A database connection handle is usually
-  /// returned in *ppDb, even if an error occurs.  The only exception is that
-  /// if SQLite is unable to allocate memory to hold the sqlite3 object,
-  /// a NULL will be written into *ppDb instead of a pointer to the sqlite3
-  /// object.)^ ^(If the database is opened (and/or created) successfully, then
-  /// [SQLITE_OK] is returned.  Otherwise an error code is returned.)^ ^The
-  /// [sqlite3_errmsg] or sqlite3_errmsg16() routines can be used to obtain
-  /// an English language description of the error following a failure of any
-  /// of the sqlite3_open() routines.
-  int Function(Pointer<Utf8> filename, Pointer<Pointer<Database>> databaseOut,
-      int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
-
-  int Function(Pointer<Database> database) sqlite3_close_v2;
-
-  /// Compiling An SQL Statement
-  ///
-  /// To execute an SQL query, it must first be compiled into a byte-code
-  /// program using one of these routines.
-  ///
-  /// The first argument, "db", is a database connection obtained from a
-  /// prior successful call to sqlite3_open, [sqlite3_open_v2] or
-  /// sqlite3_open16.  The database connection must not have been closed.
-  ///
-  /// The second argument, "zSql", is the statement to be compiled, encoded
-  /// as either UTF-8 or UTF-16.  The sqlite3_prepare() and sqlite3_prepare_v2()
-  /// interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
-  /// use UTF-16.
-  ///
-  /// ^If the nByte argument is less than zero, then zSql is read up to the
-  /// first zero terminator. ^If nByte is non-negative, then it is the maximum
-  /// number of  bytes read from zSql.  ^When nByte is non-negative, the
-  /// zSql string ends at either the first '\000' or '\u0000' character or
-  /// the nByte-th byte, whichever comes first. If the caller knows
-  /// that the supplied string is nul-terminated, then there is a small
-  /// performance advantage to be gained by passing an nByte parameter that
-  /// is equal to the number of bytes in the input string <i>including</i>
-  /// the nul-terminator bytes.
-  ///
-  /// ^If pzTail is not NULL then *pzTail is made to point to the first byte
-  /// past the end of the first SQL statement in zSql.  These routines only
-  /// compile the first statement in zSql, so *pzTail is left pointing to
-  /// what remains uncompiled.
-  ///
-  /// ^*ppStmt is left pointing to a compiled prepared statement that can be
-  /// executed using sqlite3_step.  ^If there is an error, *ppStmt is set
-  /// to NULL.  ^If the input text contains no SQL (if the input is an empty
-  /// string or a comment) then *ppStmt is set to NULL.
-  /// The calling procedure is responsible for deleting the compiled
-  /// SQL statement using [sqlite3_finalize] after it has finished with it.
-  /// ppStmt may not be NULL.
-  ///
-  /// ^On success, the sqlite3_prepare family of routines return [SQLITE_OK];
-  /// otherwise an error code is returned.
-  ///
-  /// The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
-  /// recommended for all new programs. The two older interfaces are retained
-  /// for backwards compatibility, but their use is discouraged.
-  /// ^In the "v2" interfaces, the prepared statement
-  /// that is returned (the sqlite3_stmt object) contains a copy of the
-  /// original SQL text. This causes the [sqlite3_step] interface to
-  /// behave differently in three ways:
-  int Function(
-      Pointer<Database> database,
-      Pointer<Utf8> query,
-      int nbytes,
-      Pointer<Pointer<Statement>> statementOut,
-      Pointer<Pointer<Utf8>> tail) sqlite3_prepare_v2;
-
-  /// Evaluate An SQL Statement
-  ///
-  /// After a prepared statement has been prepared using either
-  /// [sqlite3_prepare_v2] or sqlite3_prepare16_v2() or one of the legacy
-  /// interfaces sqlite3_prepare() or sqlite3_prepare16(), this function
-  /// must be called one or more times to evaluate the statement.
-  ///
-  /// The details of the behavior of the sqlite3_step() interface depend
-  /// on whether the statement was prepared using the newer "v2" interface
-  /// [sqlite3_prepare_v2] and sqlite3_prepare16_v2() or the older legacy
-  /// interface sqlite3_prepare() and sqlite3_prepare16().  The use of the
-  /// new "v2" interface is recommended for new applications but the legacy
-  /// interface will continue to be supported.
-  ///
-  /// ^In the legacy interface, the return value will be either [SQLITE_BUSY],
-  /// [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
-  /// ^With the "v2" interface, any of the other [result codes] or
-  /// [extended result codes] might be returned as well.
-  ///
-  /// ^[SQLITE_BUSY] means that the database engine was unable to acquire the
-  /// database locks it needs to do its job.  ^If the statement is a [COMMIT]
-  /// or occurs outside of an explicit transaction, then you can retry the
-  /// statement.  If the statement is not a [COMMIT] and occurs within an
-  /// explicit transaction then you should rollback the transaction before
-  /// continuing.
-  ///
-  /// ^[SQLITE_DONE] means that the statement has finished executing
-  /// successfully.  sqlite3_step() should not be called again on this virtual
-  /// machine without first calling [sqlite3_reset()] to reset the virtual
-  /// machine back to its initial state.
-  ///
-  /// ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
-  /// is returned each time a new row of data is ready for processing by the
-  /// caller. The values may be accessed using the [column access functions].
-  /// sqlite3_step() is called again to retrieve the next row of data.
-  ///
-  /// ^[SQLITE_ERROR] means that a run-time error (such as a constraint
-  /// violation) has occurred.  sqlite3_step() should not be called again on
-  /// the VM. More information may be found by calling [sqlite3_errmsg()].
-  /// ^With the legacy interface, a more specific error code (for example,
-  /// [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
-  /// can be obtained by calling [sqlite3_reset()] on the
-  /// prepared statement.  ^In the "v2" interface,
-  /// the more specific error code is returned directly by sqlite3_step().
-  ///
-  /// [SQLITE_MISUSE] means that the this routine was called inappropriately.
-  /// Perhaps it was called on a prepared statement that has
-  /// already been [sqlite3_finalize | finalized] or on one that had
-  /// previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
-  /// be the case that the same database connection is being used by two or
-  /// more threads at the same moment in time.
-  ///
-  /// For all versions of SQLite up to and including 3.6.23.1, a call to
-  /// [sqlite3_reset] was required after sqlite3_step() returned anything
-  /// other than [Errors.SQLITE_ROW] before any subsequent invocation of
-  /// sqlite3_step().  Failure to reset the prepared statement using
-  /// [sqlite3_reset()] would result in an [Errors.SQLITE_MISUSE] return from
-  /// sqlite3_step().  But after version 3.6.23.1, sqlite3_step() began
-  /// calling [sqlite3_reset] automatically in this circumstance rather
-  /// than returning [Errors.SQLITE_MISUSE]. This is not considered a
-  /// compatibility break because any application that ever receives an
-  /// [Errors.SQLITE_MISUSE] error is broken by definition.  The
-  /// [SQLITE_OMIT_AUTORESET] compile-time option
-  /// can be used to restore the legacy behavior.
-  ///
-  /// <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
-  /// API always returns a generic error code, [SQLITE_ERROR], following any
-  /// error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
-  /// [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
-  /// specific [error codes] that better describes the error.
-  /// We admit that this is a goofy design.  The problem has been fixed
-  /// with the "v2" interface.  If you prepare all of your SQL statements
-  /// using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
-  /// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
-  /// then the more specific [error codes] are returned directly
-  /// by sqlite3_step().  The use of the "v2" interface is recommended.
-  int Function(Pointer<Statement> statement) sqlite3_step;
-
-  /// CAPI3REF: Reset A Prepared Statement Object
-  ///
-  /// The sqlite3_reset() function is called to reset a prepared statement
-  /// object back to its initial state, ready to be re-executed.
-  /// ^Any SQL statement variables that had values bound to them using
-  /// the sqlite3_bind_blob | sqlite3_bind_*() API retain their values.
-  /// Use sqlite3_clear_bindings() to reset the bindings.
-  ///
-  /// ^The [sqlite3_reset] interface resets the prepared statement S
-  /// back to the beginning of its program.
-  ///
-  /// ^If the most recent call to [sqlite3_step] for the
-  /// prepared statement S returned [Errors.SQLITE_ROW] or [Errors.SQLITE_DONE],
-  /// or if [sqlite3_step] has never before been called on S,
-  /// then [sqlite3_reset] returns [Errors.SQLITE_OK].
-  ///
-  /// ^If the most recent call to [sqlite3_step(S)] for the
-  /// prepared statement S indicated an error, then
-  /// [sqlite3_reset] returns an appropriate [Errors].
-  ///
-  /// ^The [sqlite3_reset] interface does not change the values
-  int Function(Pointer<Statement> statement) sqlite3_reset;
-
-  /// Destroy A Prepared Statement Object
-  ///
-  /// ^The sqlite3_finalize() function is called to delete a prepared statement.
-  /// ^If the most recent evaluation of the statement encountered no errors
-  /// or if the statement is never been evaluated, then sqlite3_finalize()
-  /// returns SQLITE_OK.  ^If the most recent evaluation of statement S failed,
-  /// then sqlite3_finalize(S) returns the appropriate error code or extended
-  /// error code.
-  ///
-  /// ^The sqlite3_finalize(S) routine can be called at any point during
-  /// the life cycle of prepared statement S:
-  /// before statement S is ever evaluated, after
-  /// one or more calls to [sqlite3_reset], or after any call
-  /// to [sqlite3_step] regardless of whether or not the statement has
-  /// completed execution.
-  ///
-  /// ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
-  ///
-  /// The application must finalize every prepared statement in order to avoid
-  /// resource leaks.  It is a grievous error for the application to try to use
-  /// a prepared statement after it has been finalized.  Any use of a prepared
-  /// statement after it has been finalized can result in undefined and
-  /// undesirable behavior such as segfaults and heap corruption.
-  int Function(Pointer<Statement> statement) sqlite3_finalize;
-
-  /// Number Of Columns In A Result Set
-  ///
-  /// ^Return the number of columns in the result set returned by the
-  /// prepared statement. ^This routine returns 0 if pStmt is an SQL
-  /// statement that does not return data (for example an [UPDATE]).
-  int Function(Pointer<Statement> statement) sqlite3_column_count;
-
-  /// Column Names In A Result Set
-  ///
-  /// ^These routines return the name assigned to a particular column
-  /// in the result set of a SELECT statement.  ^The sqlite3_column_name()
-  /// interface returns a pointer to a zero-terminated UTF-8 string
-  /// and sqlite3_column_name16() returns a pointer to a zero-terminated
-  /// UTF-16 string.  ^The first parameter is the prepared statement
-  /// that implements the SELECT statement. ^The second parameter is the
-  /// column number.  ^The leftmost column is number 0.
-  ///
-  /// ^The returned string pointer is valid until either the prepared statement
-  /// is destroyed by [sqlite3_finalize] or until the statement is automatically
-  /// reprepared by the first call to [sqlite3_step] for a particular run
-  /// or until the next call to
-  /// sqlite3_column_name() or sqlite3_column_name16() on the same column.
-  ///
-  /// ^If sqlite3_malloc() fails during the processing of either routine
-  /// (for example during a conversion from UTF-8 to UTF-16) then a
-  /// NULL pointer is returned.
-  ///
-  /// ^The name of a result column is the value of the "AS" clause for
-  /// that column, if there is an AS clause.  If there is no AS clause
-  /// then the name of the column is unspecified and may change from
-  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
-      sqlite3_column_name;
-
-  /// CAPI3REF: Declared Datatype Of A Query Result
-  ///
-  /// ^(The first parameter is a prepared statement.
-  /// If this statement is a SELECT statement and the Nth column of the
-  /// returned result set of that SELECT is a table column (not an
-  /// expression or subquery) then the declared type of the table
-  /// column is returned.)^  ^If the Nth column of the result set is an
-  /// expression or subquery, then a NULL pointer is returned.
-  /// ^The returned string is always UTF-8 encoded.
-  ///
-  /// ^(For example, given the database schema:
-  ///
-  /// CREATE TABLE t1(c1 VARIANT);
-  ///
-  /// and the following statement to be compiled:
-  ///
-  /// SELECT c1 + 1, c1 FROM t1;
-  ///
-  /// this routine would return the string "VARIANT" for the second result
-  /// column (i==1), and a NULL pointer for the first result column (i==0).)^
-  ///
-  /// ^SQLite uses dynamic run-time typing.  ^So just because a column
-  /// is declared to contain a particular type does not mean that the
-  /// data stored in that column is of the declared type.  SQLite is
-  /// strongly typed, but the typing is dynamic not static.  ^Type
-  /// is associated with individual values, not with the containers
-  /// used to hold those values.
-  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
-      sqlite3_column_decltype;
-
-  int Function(Pointer<Statement> statement, int columnIndex)
-      sqlite3_column_type;
-
-  Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
-      sqlite3_column_value;
-
-  double Function(Pointer<Statement> statement, int columnIndex)
-      sqlite3_column_double;
-
-  int Function(Pointer<Statement> statement, int columnIndex)
-      sqlite3_column_int;
-
-  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
-      sqlite3_column_text;
-
-  /// The sqlite3_errstr() interface returns the English-language text that
-  /// describes the result code, as UTF-8. Memory to hold the error message
-  /// string is managed internally and must not be freed by the application.
-  Pointer<Utf8> Function(int code) sqlite3_errstr;
-
-  /// Error Codes And Messages
-  ///
-  /// ^The sqlite3_errcode() interface returns the numeric [result code] or
-  /// [extended result code] for the most recent failed sqlite3_* API call
-  /// associated with a [database connection]. If a prior API call failed
-  /// but the most recent API call succeeded, the return value from
-  /// sqlite3_errcode() is undefined.  ^The sqlite3_extended_errcode()
-  /// interface is the same except that it always returns the
-  /// [extended result code] even when extended result codes are
-  /// disabled.
-  ///
-  /// ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
-  /// text that describes the error, as either UTF-8 or UTF-16 respectively.
-  /// ^(Memory to hold the error message string is managed internally.
-  /// The application does not need to worry about freeing the result.
-  /// However, the error string might be overwritten or deallocated by
-  /// subsequent calls to other SQLite interface functions.)^
-  ///
-  /// When the serialized [threading mode] is in use, it might be the
-  /// case that a second error occurs on a separate thread in between
-  /// the time of the first error and the call to these interfaces.
-  /// When that happens, the second error will be reported since these
-  /// interfaces always report the most recent result.  To avoid
-  /// this, each thread can obtain exclusive use of the [database connection] D
-  /// by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
-  /// to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
-  /// all calls to the interfaces listed here are completed.
-  ///
-  /// If an interface fails with SQLITE_MISUSE, that means the interface
-  /// was invoked incorrectly by the application.  In that case, the
-  /// error code and message may or may not be set.
-  Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
-
-  _SQLiteBindings() {
-    sqlite = dlopenPlatformSpecific("sqlite3");
-    sqlite3_open_v2 = sqlite
-        .lookup<NativeFunction<sqlite3_open_v2_native_t>>("sqlite3_open_v2")
-        .asFunction();
-    sqlite3_close_v2 = sqlite
-        .lookup<NativeFunction<sqlite3_close_v2_native_t>>("sqlite3_close_v2")
-        .asFunction();
-    sqlite3_prepare_v2 = sqlite
-        .lookup<NativeFunction<sqlite3_prepare_v2_native_t>>(
-            "sqlite3_prepare_v2")
-        .asFunction();
-    sqlite3_step = sqlite
-        .lookup<NativeFunction<sqlite3_step_native_t>>("sqlite3_step")
-        .asFunction();
-    sqlite3_reset = sqlite
-        .lookup<NativeFunction<sqlite3_reset_native_t>>("sqlite3_reset")
-        .asFunction();
-    sqlite3_finalize = sqlite
-        .lookup<NativeFunction<sqlite3_finalize_native_t>>("sqlite3_finalize")
-        .asFunction();
-    sqlite3_errstr = sqlite
-        .lookup<NativeFunction<sqlite3_errstr_native_t>>("sqlite3_errstr")
-        .asFunction();
-    sqlite3_errmsg = sqlite
-        .lookup<NativeFunction<sqlite3_errmsg_native_t>>("sqlite3_errmsg")
-        .asFunction();
-    sqlite3_column_count = sqlite
-        .lookup<NativeFunction<sqlite3_column_count_native_t>>(
-            "sqlite3_column_count")
-        .asFunction();
-    sqlite3_column_name = sqlite
-        .lookup<NativeFunction<sqlite3_column_name_native_t>>(
-            "sqlite3_column_name")
-        .asFunction();
-    sqlite3_column_decltype = sqlite
-        .lookup<NativeFunction<sqlite3_column_decltype_native_t>>(
-            "sqlite3_column_decltype")
-        .asFunction();
-    sqlite3_column_type = sqlite
-        .lookup<NativeFunction<sqlite3_column_type_native_t>>(
-            "sqlite3_column_type")
-        .asFunction();
-    sqlite3_column_value = sqlite
-        .lookup<NativeFunction<sqlite3_column_value_native_t>>(
-            "sqlite3_column_value")
-        .asFunction();
-    sqlite3_column_double = sqlite
-        .lookup<NativeFunction<sqlite3_column_double_native_t>>(
-            "sqlite3_column_double")
-        .asFunction();
-    sqlite3_column_int = sqlite
-        .lookup<NativeFunction<sqlite3_column_int_native_t>>(
-            "sqlite3_column_int")
-        .asFunction();
-    sqlite3_column_text = sqlite
-        .lookup<NativeFunction<sqlite3_column_text_native_t>>(
-            "sqlite3_column_text")
-        .asFunction();
-  }
-}
-
-_SQLiteBindings _cachedBindings;
-_SQLiteBindings get bindings => _cachedBindings ??= _SQLiteBindings();
diff --git a/samples/ffi/sqlite/lib/src/bindings/constants.dart b/samples/ffi/sqlite/lib/src/bindings/constants.dart
deleted file mode 100644
index 71aa82e..0000000
--- a/samples/ffi/sqlite/lib/src/bindings/constants.dart
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Result Codes
-///
-/// Many SQLite functions return an integer result code from the set shown
-/// here in order to indicates success or failure.
-///
-/// New error codes may be added in future versions of SQLite.
-///
-/// See also: SQLITE_IOERR_READ | extended result codes,
-/// sqlite3_vtab_on_conflict() SQLITE_ROLLBACK | result codes.
-class Errors {
-  /// Successful result
-  static const int SQLITE_OK = 0;
-
-  /// Generic error
-  static const int SQLITE_ERROR = 1;
-
-  /// Internal logic error in SQLite
-  static const int SQLITE_INTERNAL = 2;
-
-  /// Access permission denied
-  static const int SQLITE_PERM = 3;
-
-  /// Callback routine requested an abort
-  static const int SQLITE_ABORT = 4;
-
-  /// The database file is locked
-  static const int SQLITE_BUSY = 5;
-
-  /// A table in the database is locked
-  static const int SQLITE_LOCKED = 6;
-
-  /// A malloc() failed
-  static const int SQLITE_NOMEM = 7;
-
-  /// Attempt to write a readonly database
-  static const int SQLITE_READONLY = 8;
-
-  /// Operation terminated by sqlite3_interrupt()
-  static const int SQLITE_INTERRUPT = 9;
-
-  /// Some kind of disk I/O error occurred
-  static const int SQLITE_IOERR = 10;
-
-  /// The database disk image is malformed
-  static const int SQLITE_CORRUPT = 11;
-
-  /// Unknown opcode in sqlite3_file_control()
-  static const int SQLITE_NOTFOUND = 12;
-
-  /// Insertion failed because database is full
-  static const int SQLITE_FULL = 13;
-
-  /// Unable to open the database file
-  static const int SQLITE_CANTOPEN = 14;
-
-  /// Database lock protocol error
-  static const int SQLITE_PROTOCOL = 15;
-
-  /// Internal use only
-  static const int SQLITE_EMPTY = 16;
-
-  /// The database schema changed
-  static const int SQLITE_SCHEMA = 17;
-
-  /// String or BLOB exceeds size limit
-  static const int SQLITE_TOOBIG = 18;
-
-  /// Abort due to constraint violation
-  static const int SQLITE_CONSTRAINT = 19;
-
-  /// Data type mismatch
-  static const int SQLITE_MISMATCH = 20;
-
-  /// Library used incorrectly
-  static const int SQLITE_MISUSE = 21;
-
-  /// Uses OS features not supported on host
-  static const int SQLITE_NOLFS = 22;
-
-  /// Authorization denied
-  static const int SQLITE_AUTH = 23;
-
-  /// Not used
-  static const int SQLITE_FORMAT = 24;
-
-  /// 2nd parameter to sqlite3_bind out of range
-  static const int SQLITE_RANGE = 25;
-
-  /// File opened that is not a database file
-  static const int SQLITE_NOTADB = 26;
-
-  /// Notifications from sqlite3_log()
-  static const int SQLITE_NOTICE = 27;
-
-  /// Warnings from sqlite3_log()
-  static const int SQLITE_WARNING = 28;
-
-  /// sqlite3_step() has another row ready
-  static const int SQLITE_ROW = 100;
-
-  /// sqlite3_step() has finished executing
-  static const int SQLITE_DONE = 101;
-}
-
-/// Flags For File Open Operations
-///
-/// These bit values are intended for use in the
-/// 3rd parameter to the [sqlite3_open_v2()] interface and
-/// in the 4th parameter to the [sqlite3_vfs.xOpen] method.
-class Flags {
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_READONLY = 0x00000001;
-
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_READWRITE = 0x00000002;
-
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_CREATE = 0x00000004;
-
-  /// VFS only
-  static const int SQLITE_OPEN_DELETEONCLOSE = 0x00000008;
-
-  /// VFS only
-  static const int SQLITE_OPEN_EXCLUSIVE = 0x00000010;
-
-  /// VFS only
-  static const int SQLITE_OPEN_AUTOPROXY = 0x00000020;
-
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_URI = 0x00000040;
-
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_MEMORY = 0x00000080;
-
-  /// VFS only
-  static const int SQLITE_OPEN_MAIN_DB = 0x00000100;
-
-  /// VFS only
-  static const int SQLITE_OPEN_TEMP_DB = 0x00000200;
-
-  /// VFS only
-  static const int SQLITE_OPEN_TRANSIENT_DB = 0x00000400;
-
-  /// VFS only
-  static const int SQLITE_OPEN_MAIN_JOURNAL = 0x00000800;
-
-  /// VFS only
-  static const int SQLITE_OPEN_TEMP_JOURNAL = 0x00001000;
-
-  /// VFS only
-  static const int SQLITE_OPEN_SUBJOURNAL = 0x00002000;
-
-  /// VFS only
-  static const int SQLITE_OPEN_MASTER_JOURNAL = 0x00004000;
-
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_NOMUTEX = 0x00008000;
-
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_FULLMUTEX = 0x00010000;
-
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_SHAREDCACHE = 0x00020000;
-
-  /// Ok for sqlite3_open_v2()
-  static const int SQLITE_OPEN_PRIVATECACHE = 0x00040000;
-
-  /// VFS only
-  static const int SQLITE_OPEN_WAL = 0x00080000;
-}
-
-class Types {
-  static const int SQLITE_INTEGER = 1;
-  static const int SQLITE_FLOAT = 2;
-  static const int SQLITE_TEXT = 3;
-  static const int SQLITE_BLOB = 4;
-  static const int SQLITE_NULL = 5;
-}
diff --git a/samples/ffi/sqlite/lib/src/bindings/signatures.dart b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
deleted file mode 100644
index 2f38dad..0000000
--- a/samples/ffi/sqlite/lib/src/bindings/signatures.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:ffi";
-
-import "package:ffi/ffi.dart";
-
-import "types.dart";
-
-typedef sqlite3_open_v2_native_t = Int32 Function(Pointer<Utf8> filename,
-    Pointer<Pointer<Database>> ppDb, Int32 flags, Pointer<Utf8> vfs);
-
-typedef sqlite3_close_v2_native_t = Int32 Function(Pointer<Database> database);
-
-typedef sqlite3_prepare_v2_native_t = Int32 Function(
-    Pointer<Database> database,
-    Pointer<Utf8> query,
-    Int32 nbytes,
-    Pointer<Pointer<Statement>> statementOut,
-    Pointer<Pointer<Utf8>> tail);
-
-typedef sqlite3_step_native_t = Int32 Function(Pointer<Statement> statement);
-
-typedef sqlite3_reset_native_t = Int32 Function(Pointer<Statement> statement);
-
-typedef sqlite3_finalize_native_t = Int32 Function(
-    Pointer<Statement> statement);
-
-typedef sqlite3_errstr_native_t = Pointer<Utf8> Function(Int32 error);
-
-typedef sqlite3_errmsg_native_t = Pointer<Utf8> Function(
-    Pointer<Database> database);
-
-typedef sqlite3_column_count_native_t = Int32 Function(
-    Pointer<Statement> statement);
-
-typedef sqlite3_column_name_native_t = Pointer<Utf8> Function(
-    Pointer<Statement> statement, Int32 columnIndex);
-
-typedef sqlite3_column_decltype_native_t = Pointer<Utf8> Function(
-    Pointer<Statement> statement, Int32 columnIndex);
-
-typedef sqlite3_column_type_native_t = Int32 Function(
-    Pointer<Statement> statement, Int32 columnIndex);
-
-typedef sqlite3_column_value_native_t = Pointer<Value> Function(
-    Pointer<Statement> statement, Int32 columnIndex);
-
-typedef sqlite3_column_double_native_t = Double Function(
-    Pointer<Statement> statement, Int32 columnIndex);
-
-typedef sqlite3_column_int_native_t = Int32 Function(
-    Pointer<Statement> statement, Int32 columnIndex);
-
-typedef sqlite3_column_text_native_t = Pointer<Utf8> Function(
-    Pointer<Statement> statement, Int32 columnIndex);
diff --git a/samples/ffi/sqlite/lib/src/bindings/types.dart b/samples/ffi/sqlite/lib/src/bindings/types.dart
deleted file mode 100644
index 494cdef..0000000
--- a/samples/ffi/sqlite/lib/src/bindings/types.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:ffi";
-
-/// Database Connection Handle
-///
-/// Each open SQLite database is represented by a pointer to an instance of
-/// the opaque structure named "sqlite3".  It is useful to think of an sqlite3
-/// pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
-/// [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
-/// is its destructor.  There are many other interfaces (such as
-/// [sqlite3_prepare_v2()], [sqlite3_create_function()], and
-/// [sqlite3_busy_timeout()] to name but three) that are methods on an
-class Database extends Struct {}
-
-/// SQL Statement Object
-///
-/// An instance of this object represents a single SQL statement.
-/// This object is variously known as a "prepared statement" or a
-/// "compiled SQL statement" or simply as a "statement".
-///
-/// The life of a statement object goes something like this:
-///
-/// <ol>
-/// <li> Create the object using [sqlite3_prepare_v2()] or a related
-///      function.
-/// <li> Bind values to [host parameters] using the sqlite3_bind_*()
-///      interfaces.
-/// <li> Run the SQL by calling [sqlite3_step()] one or more times.
-/// <li> Reset the statement using [sqlite3_reset()] then go back
-///      to step 2.  Do this zero or more times.
-/// <li> Destroy the object using [sqlite3_finalize()].
-/// </ol>
-///
-/// Refer to documentation on individual methods above for additional
-/// information.
-class Statement extends Struct {}
-
-/// Dynamically Typed Value Object
-///
-/// SQLite uses the sqlite3_value object to represent all values
-/// that can be stored in a database table. SQLite uses dynamic typing
-/// for the values it stores.  ^Values stored in sqlite3_value objects
-/// can be integers, floating point values, strings, BLOBs, or NULL.
-///
-/// An sqlite3_value object may be either "protected" or "unprotected".
-/// Some interfaces require a protected sqlite3_value.  Other interfaces
-/// will accept either a protected or an unprotected sqlite3_value.
-/// Every interface that accepts sqlite3_value arguments specifies
-/// whether or not it requires a protected sqlite3_value.
-///
-/// The terms "protected" and "unprotected" refer to whether or not
-/// a mutex is held.  An internal mutex is held for a protected
-/// sqlite3_value object but no mutex is held for an unprotected
-/// sqlite3_value object.  If SQLite is compiled to be single-threaded
-/// (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
-/// or if SQLite is run in one of reduced mutex modes
-/// [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
-/// then there is no distinction between protected and unprotected
-/// sqlite3_value objects and they can be used interchangeably.  However,
-/// for maximum code portability it is recommended that applications
-/// still make the distinction between protected and unprotected
-/// sqlite3_value objects even when not strictly required.
-///
-/// ^The sqlite3_value objects that are passed as parameters into the
-/// implementation of [application-defined SQL functions] are protected.
-/// ^The sqlite3_value object returned by
-/// [sqlite3_column_value()] is unprotected.
-/// Unprotected sqlite3_value objects may only be used with
-/// [sqlite3_result_value()] and [sqlite3_bind_value()].
-/// The [sqlite3_value_blob | sqlite3_value_type()] family of
-/// interfaces require protected sqlite3_value objects.
-class Value extends Struct {}
diff --git a/samples/ffi/sqlite/lib/src/database.dart b/samples/ffi/sqlite/lib/src/database.dart
index be2b7ef..ffbe710 100644
--- a/samples/ffi/sqlite/lib/src/database.dart
+++ b/samples/ffi/sqlite/lib/src/database.dart
@@ -7,13 +7,11 @@
 
 import "package:ffi/ffi.dart";
 
-import "bindings/bindings.dart";
-
-import "bindings/types.dart" as types;
-import "bindings/types.dart" hide Database;
-
-import "bindings/constants.dart";
+import "third_party/sqlite/sqlite3_bindings_generated.dart" as bindings;
 import "collections/closable_iterator.dart";
+import "ffi/dylib_utils.dart";
+
+final sqlite = bindings.SQLite(dlopenPlatformSpecific("sqlite3"));
 
 /// [Database] represents an open connection to a SQLite database.
 ///
@@ -21,26 +19,27 @@
 ///
 /// This database interacts with SQLite synchonously.
 class Database {
-  Pointer<types.Database> _database;
+  Pointer<bindings.sqlite3> _database;
   bool _open = false;
 
   /// Open a database located at the file [path].
   Database(String path,
-      [int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
-    Pointer<Pointer<types.Database>> dbOut = allocate();
-    final pathC = Utf8.toUtf8(path);
-    final int resultCode =
-        bindings.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
+      [int flags =
+          bindings.SQLITE_OPEN_READWRITE | bindings.SQLITE_OPEN_CREATE]) {
+    Pointer<Pointer<bindings.sqlite3>> dbOut = allocate();
+    final pathC = Utf8.toUtf8(path).cast<Int8>();
+    final int resultCode = sqlite.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
     _database = dbOut.value;
     free(dbOut);
     free(pathC);
 
-    if (resultCode == Errors.SQLITE_OK) {
+    if (resultCode == bindings.SQLITE_OK) {
       _open = true;
     } else {
       // Even if "open" fails, sqlite3 will still create a database object. We
       // can just destroy it.
       SQLiteException exception = _loadError(resultCode);
+      _open = true;
       close();
       throw exception;
     }
@@ -53,8 +52,8 @@
   /// avoid resource leaks.
   void close() {
     assert(_open);
-    final int resultCode = bindings.sqlite3_close_v2(_database);
-    if (resultCode == Errors.SQLITE_OK) {
+    final int resultCode = sqlite.sqlite3_close_v2(_database);
+    if (resultCode == bindings.SQLITE_OK) {
       _open = false;
     } else {
       throw _loadError(resultCode);
@@ -63,43 +62,44 @@
 
   /// Execute a query, discarding any returned rows.
   void execute(String query) {
-    Pointer<Pointer<Statement>> statementOut = allocate();
-    Pointer<Utf8> queryC = Utf8.toUtf8(query);
-    int resultCode = bindings.sqlite3_prepare_v2(
-        _database, queryC, -1, statementOut, nullptr);
-    Pointer<Statement> statement = statementOut.value;
+    Pointer<Pointer<bindings.sqlite3_stmt>> statementOut = allocate();
+    final queryC = Utf8.toUtf8(query).cast<Int8>();
+    int resultCode =
+        sqlite.sqlite3_prepare_v2(_database, queryC, -1, statementOut, nullptr);
+    Pointer<bindings.sqlite3_stmt> statement = statementOut.value;
     free(statementOut);
     free(queryC);
 
-    while (resultCode == Errors.SQLITE_ROW || resultCode == Errors.SQLITE_OK) {
-      resultCode = bindings.sqlite3_step(statement);
+    while (
+        resultCode == bindings.SQLITE_ROW || resultCode == bindings.SQLITE_OK) {
+      resultCode = sqlite.sqlite3_step(statement);
     }
-    bindings.sqlite3_finalize(statement);
-    if (resultCode != Errors.SQLITE_DONE) {
+    sqlite.sqlite3_finalize(statement);
+    if (resultCode != bindings.SQLITE_DONE) {
       throw _loadError(resultCode);
     }
   }
 
   /// Evaluate a query and return the resulting rows as an iterable.
   Result query(String query) {
-    Pointer<Pointer<Statement>> statementOut = allocate();
-    Pointer<Utf8> queryC = Utf8.toUtf8(query);
-    int resultCode = bindings.sqlite3_prepare_v2(
-        _database, queryC, -1, statementOut, nullptr);
-    Pointer<Statement> statement = statementOut.value;
+    Pointer<Pointer<bindings.sqlite3_stmt>> statementOut = allocate();
+    final queryC = Utf8.toUtf8(query).cast<Int8>();
+    int resultCode =
+        sqlite.sqlite3_prepare_v2(_database, queryC, -1, statementOut, nullptr);
+    Pointer<bindings.sqlite3_stmt> statement = statementOut.value;
     free(statementOut);
     free(queryC);
 
-    if (resultCode != Errors.SQLITE_OK) {
-      bindings.sqlite3_finalize(statement);
+    if (resultCode != bindings.SQLITE_OK) {
+      sqlite.sqlite3_finalize(statement);
       throw _loadError(resultCode);
     }
 
     Map<String, int> columnIndices = {};
-    int columnCount = bindings.sqlite3_column_count(statement);
+    int columnCount = sqlite.sqlite3_column_count(statement);
     for (int i = 0; i < columnCount; i++) {
       String columnName =
-          bindings.sqlite3_column_name(statement, i).ref.toString();
+          sqlite.sqlite3_column_name(statement, i).cast<Utf8>().ref.toString();
       columnIndices[columnName] = i;
     }
 
@@ -107,12 +107,13 @@
   }
 
   SQLiteException _loadError([int errorCode]) {
-    String errorMessage = bindings.sqlite3_errmsg(_database).ref.toString();
+    String errorMessage =
+        sqlite.sqlite3_errmsg(_database).cast<Utf8>().ref.toString();
     if (errorCode == null) {
       return SQLiteException(errorMessage);
     }
     String errorCodeExplanation =
-        bindings.sqlite3_errstr(errorCode).ref.toString();
+        sqlite.sqlite3_errstr(errorCode).cast<Utf8>().ref.toString();
     return SQLiteException(
         "$errorMessage (Code $errorCode: $errorCodeExplanation)");
   }
@@ -126,7 +127,7 @@
 class Result extends IterableBase<Row> implements ClosableIterable<Row> {
   final Database _database;
   final ClosableIterator<Row> _iterator;
-  final Pointer<Statement> _statement;
+  final Pointer<bindings.sqlite3_stmt> _statement;
   final Map<String, int> _columnIndices;
 
   Row _currentRow = null;
@@ -143,7 +144,7 @@
 }
 
 class _ResultIterator implements ClosableIterator<Row> {
-  final Pointer<Statement> _statement;
+  final Pointer<bindings.sqlite3_stmt> _statement;
   final Map<String, int> _columnIndices;
 
   Row _currentRow = null;
@@ -156,8 +157,8 @@
       throw SQLiteException("The result has already been closed.");
     }
     _currentRow?._setNotCurrent();
-    int stepResult = bindings.sqlite3_step(_statement);
-    if (stepResult == Errors.SQLITE_ROW) {
+    int stepResult = sqlite.sqlite3_step(_statement);
+    if (stepResult == bindings.SQLITE_ROW) {
       _currentRow = Row._(_statement, _columnIndices);
       return true;
     } else {
@@ -176,12 +177,12 @@
   void close() {
     _currentRow?._setNotCurrent();
     _closed = true;
-    bindings.sqlite3_finalize(_statement);
+    sqlite.sqlite3_finalize(_statement);
   }
 }
 
 class Row {
-  final Pointer<Statement> _statement;
+  final Pointer<bindings.sqlite3_stmt> _statement;
   final Map<String, int> _columnIndices;
 
   bool _isCurrentRow = true;
@@ -210,10 +211,11 @@
     Type dynamicType;
     if (convert == Convert.DynamicType) {
       dynamicType =
-          _typeFromCode(bindings.sqlite3_column_type(_statement, columnIndex));
+          _typeFromCode(sqlite.sqlite3_column_type(_statement, columnIndex));
     } else {
-      dynamicType = _typeFromText(bindings
+      dynamicType = _typeFromText(sqlite
           .sqlite3_column_decltype(_statement, columnIndex)
+          .cast<Utf8>()
           .ref
           .toString());
     }
@@ -240,7 +242,7 @@
   /// integer.
   int readColumnByIndexAsInt(int columnIndex) {
     _checkIsCurrentRow();
-    return bindings.sqlite3_column_int(_statement, columnIndex);
+    return sqlite.sqlite3_column_int(_statement, columnIndex);
   }
 
   /// Reads column [columnName] and converts to [Type.Text] if not text.
@@ -251,7 +253,11 @@
   /// Reads column [columnIndex] and converts to [Type.Text] if not text.
   String readColumnByIndexAsText(int columnIndex) {
     _checkIsCurrentRow();
-    return bindings.sqlite3_column_text(_statement, columnIndex).ref.toString();
+    return sqlite
+        .sqlite3_column_text(_statement, columnIndex)
+        .cast<Utf8>()
+        .ref
+        .toString();
   }
 
   void _checkIsCurrentRow() {
@@ -269,15 +275,15 @@
 
 Type _typeFromCode(int code) {
   switch (code) {
-    case Types.SQLITE_INTEGER:
+    case bindings.SQLITE_INTEGER:
       return Type.Integer;
-    case Types.SQLITE_FLOAT:
+    case bindings.SQLITE_FLOAT:
       return Type.Float;
-    case Types.SQLITE_TEXT:
+    case bindings.SQLITE_TEXT:
       return Type.Text;
-    case Types.SQLITE_BLOB:
+    case bindings.SQLITE_BLOB:
       return Type.Blob;
-    case Types.SQLITE_NULL:
+    case bindings.SQLITE_NULL:
       return Type.Null;
   }
   throw Exception("Unknown type [$code]");
diff --git a/samples/ffi/sqlite/lib/src/third_party/sqlite/sqlite3_bindings_generated.dart b/samples/ffi/sqlite/lib/src/third_party/sqlite/sqlite3_bindings_generated.dart
new file mode 100644
index 0000000..bfbd4c8
--- /dev/null
+++ b/samples/ffi/sqlite/lib/src/third_party/sqlite/sqlite3_bindings_generated.dart
@@ -0,0 +1,1968 @@
+// 2001 September 15
+//
+// The author disclaims copyright to this source code.  In place of
+// a legal notice, here is a blessing:
+//
+//    May you do good and not evil.
+//    May you find forgiveness for yourself and forgive others.
+//    May you share freely, never taking more than you give.
+
+import 'dart:ffi' as ffi;
+
+/// SQLite bindings.
+class SQLite {
+  /// Holds the Dynamic library.
+  final ffi.DynamicLibrary _dylib;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  SQLite(ffi.DynamicLibrary dynamicLibrary) : _dylib = dynamicLibrary;
+
+  int sqlite3_close_v2(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    _sqlite3_close_v2 ??=
+        _dylib.lookupFunction<_c_sqlite3_close_v2, _dart_sqlite3_close_v2>(
+            'sqlite3_close_v2');
+    return _sqlite3_close_v2(
+      arg0,
+    );
+  }
+
+  _dart_sqlite3_close_v2 _sqlite3_close_v2;
+
+  int sqlite3_open_v2(
+    ffi.Pointer<ffi.Int8> filename,
+    ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
+    int flags,
+    ffi.Pointer<ffi.Int8> zVfs,
+  ) {
+    _sqlite3_open_v2 ??=
+        _dylib.lookupFunction<_c_sqlite3_open_v2, _dart_sqlite3_open_v2>(
+            'sqlite3_open_v2');
+    return _sqlite3_open_v2(
+      filename,
+      ppDb,
+      flags,
+      zVfs,
+    );
+  }
+
+  _dart_sqlite3_open_v2 _sqlite3_open_v2;
+
+  ffi.Pointer<ffi.Int8> sqlite3_errmsg(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    _sqlite3_errmsg ??=
+        _dylib.lookupFunction<_c_sqlite3_errmsg, _dart_sqlite3_errmsg>(
+            'sqlite3_errmsg');
+    return _sqlite3_errmsg(
+      arg0,
+    );
+  }
+
+  _dart_sqlite3_errmsg _sqlite3_errmsg;
+
+  ffi.Pointer<ffi.Int8> sqlite3_errstr(
+    int arg0,
+  ) {
+    _sqlite3_errstr ??=
+        _dylib.lookupFunction<_c_sqlite3_errstr, _dart_sqlite3_errstr>(
+            'sqlite3_errstr');
+    return _sqlite3_errstr(
+      arg0,
+    );
+  }
+
+  _dart_sqlite3_errstr _sqlite3_errstr;
+
+  int sqlite3_prepare_v2(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Int8> zSql,
+    int nByte,
+    ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+    ffi.Pointer<ffi.Pointer<ffi.Int8>> pzTail,
+  ) {
+    _sqlite3_prepare_v2 ??=
+        _dylib.lookupFunction<_c_sqlite3_prepare_v2, _dart_sqlite3_prepare_v2>(
+            'sqlite3_prepare_v2');
+    return _sqlite3_prepare_v2(
+      db,
+      zSql,
+      nByte,
+      ppStmt,
+      pzTail,
+    );
+  }
+
+  _dart_sqlite3_prepare_v2 _sqlite3_prepare_v2;
+
+  /// CAPI3REF: Number Of Columns In A Result Set
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^Return the number of columns in the result set returned by the
+  /// [prepared statement]. ^If this routine returns 0, that means the
+  /// [prepared statement] returns no data (for example an [UPDATE]).
+  /// ^However, just because this routine returns a positive number does not
+  /// mean that one or more rows of data will be returned.  ^A SELECT statement
+  /// will always have a positive sqlite3_column_count() but depending on the
+  /// WHERE clause constraints and the table content, it might return no rows.
+  ///
+  /// See also: [sqlite3_data_count()]
+  int sqlite3_column_count(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    _sqlite3_column_count ??= _dylib.lookupFunction<_c_sqlite3_column_count,
+        _dart_sqlite3_column_count>('sqlite3_column_count');
+    return _sqlite3_column_count(
+      pStmt,
+    );
+  }
+
+  _dart_sqlite3_column_count _sqlite3_column_count;
+
+  /// CAPI3REF: Column Names In A Result Set
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^These routines return the name assigned to a particular column
+  /// in the result set of a [SELECT] statement.  ^The sqlite3_column_name()
+  /// interface returns a pointer to a zero-terminated UTF-8 string
+  /// and sqlite3_column_name16() returns a pointer to a zero-terminated
+  /// UTF-16 string.  ^The first parameter is the [prepared statement]
+  /// that implements the [SELECT] statement. ^The second parameter is the
+  /// column number.  ^The leftmost column is number 0.
+  ///
+  /// ^The returned string pointer is valid until either the [prepared statement]
+  /// is destroyed by [sqlite3_finalize()] or until the statement is automatically
+  /// reprepared by the first call to [sqlite3_step()] for a particular run
+  /// or until the next call to
+  /// sqlite3_column_name() or sqlite3_column_name16() on the same column.
+  ///
+  /// ^If sqlite3_malloc() fails during the processing of either routine
+  /// (for example during a conversion from UTF-8 to UTF-16) then a
+  /// NULL pointer is returned.
+  ///
+  /// ^The name of a result column is the value of the "AS" clause for
+  /// that column, if there is an AS clause.  If there is no AS clause
+  /// then the name of the column is unspecified and may change from
+  /// one release of SQLite to the next.
+  ffi.Pointer<ffi.Int8> sqlite3_column_name(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int N,
+  ) {
+    _sqlite3_column_name ??= _dylib.lookupFunction<_c_sqlite3_column_name,
+        _dart_sqlite3_column_name>('sqlite3_column_name');
+    return _sqlite3_column_name(
+      arg0,
+      N,
+    );
+  }
+
+  _dart_sqlite3_column_name _sqlite3_column_name;
+
+  /// CAPI3REF: Declared Datatype Of A Query Result
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^(The first parameter is a [prepared statement].
+  /// If this statement is a [SELECT] statement and the Nth column of the
+  /// returned result set of that [SELECT] is a table column (not an
+  /// expression or subquery) then the declared type of the table
+  /// column is returned.)^  ^If the Nth column of the result set is an
+  /// expression or subquery, then a NULL pointer is returned.
+  /// ^The returned string is always UTF-8 encoded.
+  ///
+  /// ^(For example, given the database schema:
+  ///
+  /// CREATE TABLE t1(c1 VARIANT);
+  ///
+  /// and the following statement to be compiled:
+  ///
+  /// SELECT c1 + 1, c1 FROM t1;
+  ///
+  /// this routine would return the string "VARIANT" for the second result
+  /// column (i==1), and a NULL pointer for the first result column (i==0).)^
+  ///
+  /// ^SQLite uses dynamic run-time typing.  ^So just because a column
+  /// is declared to contain a particular type does not mean that the
+  /// data stored in that column is of the declared type.  SQLite is
+  /// strongly typed, but the typing is dynamic not static.  ^Type
+  /// is associated with individual values, not with the containers
+  /// used to hold those values.
+  ffi.Pointer<ffi.Int8> sqlite3_column_decltype(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    _sqlite3_column_decltype ??= _dylib.lookupFunction<
+        _c_sqlite3_column_decltype,
+        _dart_sqlite3_column_decltype>('sqlite3_column_decltype');
+    return _sqlite3_column_decltype(
+      arg0,
+      arg1,
+    );
+  }
+
+  _dart_sqlite3_column_decltype _sqlite3_column_decltype;
+
+  /// CAPI3REF: Evaluate An SQL Statement
+  /// METHOD: sqlite3_stmt
+  ///
+  /// After a [prepared statement] has been prepared using any of
+  /// [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
+  /// or [sqlite3_prepare16_v3()] or one of the legacy
+  /// interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
+  /// must be called one or more times to evaluate the statement.
+  ///
+  /// The details of the behavior of the sqlite3_step() interface depend
+  /// on whether the statement was prepared using the newer "vX" interfaces
+  /// [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
+  /// [sqlite3_prepare16_v2()] or the older legacy
+  /// interfaces [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
+  /// new "vX" interface is recommended for new applications but the legacy
+  /// interface will continue to be supported.
+  ///
+  /// ^In the legacy interface, the return value will be either [SQLITE_BUSY],
+  /// [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
+  /// ^With the "v2" interface, any of the other [result codes] or
+  /// [extended result codes] might be returned as well.
+  ///
+  /// ^[SQLITE_BUSY] means that the database engine was unable to acquire the
+  /// database locks it needs to do its job.  ^If the statement is a [COMMIT]
+  /// or occurs outside of an explicit transaction, then you can retry the
+  /// statement.  If the statement is not a [COMMIT] and occurs within an
+  /// explicit transaction then you should rollback the transaction before
+  /// continuing.
+  ///
+  /// ^[SQLITE_DONE] means that the statement has finished executing
+  /// successfully.  sqlite3_step() should not be called again on this virtual
+  /// machine without first calling [sqlite3_reset()] to reset the virtual
+  /// machine back to its initial state.
+  ///
+  /// ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
+  /// is returned each time a new row of data is ready for processing by the
+  /// caller. The values may be accessed using the [column access functions].
+  /// sqlite3_step() is called again to retrieve the next row of data.
+  ///
+  /// ^[SQLITE_ERROR] means that a run-time error (such as a constraint
+  /// violation) has occurred.  sqlite3_step() should not be called again on
+  /// the VM. More information may be found by calling [sqlite3_errmsg()].
+  /// ^With the legacy interface, a more specific error code (for example,
+  /// [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
+  /// can be obtained by calling [sqlite3_reset()] on the
+  /// [prepared statement].  ^In the "v2" interface,
+  /// the more specific error code is returned directly by sqlite3_step().
+  ///
+  /// [SQLITE_MISUSE] means that the this routine was called inappropriately.
+  /// Perhaps it was called on a [prepared statement] that has
+  /// already been [sqlite3_finalize | finalized] or on one that had
+  /// previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
+  /// be the case that the same database connection is being used by two or
+  /// more threads at the same moment in time.
+  ///
+  /// For all versions of SQLite up to and including 3.6.23.1, a call to
+  /// [sqlite3_reset()] was required after sqlite3_step() returned anything
+  /// other than [SQLITE_ROW] before any subsequent invocation of
+  /// sqlite3_step().  Failure to reset the prepared statement using
+  /// [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
+  /// sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1],
+  /// sqlite3_step() began
+  /// calling [sqlite3_reset()] automatically in this circumstance rather
+  /// than returning [SQLITE_MISUSE].  This is not considered a compatibility
+  /// break because any application that ever receives an SQLITE_MISUSE error
+  /// is broken by definition.  The [SQLITE_OMIT_AUTORESET] compile-time option
+  /// can be used to restore the legacy behavior.
+  ///
+  /// <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
+  /// API always returns a generic error code, [SQLITE_ERROR], following any
+  /// error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
+  /// [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
+  /// specific [error codes] that better describes the error.
+  /// We admit that this is a goofy design.  The problem has been fixed
+  /// with the "v2" interface.  If you prepare all of your SQL statements
+  /// using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
+  /// or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
+  /// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
+  /// then the more specific [error codes] are returned directly
+  /// by sqlite3_step().  The use of the "vX" interfaces is recommended.
+  int sqlite3_step(
+    ffi.Pointer<sqlite3_stmt> arg0,
+  ) {
+    _sqlite3_step ??= _dylib
+        .lookupFunction<_c_sqlite3_step, _dart_sqlite3_step>('sqlite3_step');
+    return _sqlite3_step(
+      arg0,
+    );
+  }
+
+  _dart_sqlite3_step _sqlite3_step;
+
+  int sqlite3_column_int(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    _sqlite3_column_int ??=
+        _dylib.lookupFunction<_c_sqlite3_column_int, _dart_sqlite3_column_int>(
+            'sqlite3_column_int');
+    return _sqlite3_column_int(
+      arg0,
+      iCol,
+    );
+  }
+
+  _dart_sqlite3_column_int _sqlite3_column_int;
+
+  ffi.Pointer<ffi.Uint8> sqlite3_column_text(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    _sqlite3_column_text ??= _dylib.lookupFunction<_c_sqlite3_column_text,
+        _dart_sqlite3_column_text>('sqlite3_column_text');
+    return _sqlite3_column_text(
+      arg0,
+      iCol,
+    );
+  }
+
+  _dart_sqlite3_column_text _sqlite3_column_text;
+
+  int sqlite3_column_type(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    _sqlite3_column_type ??= _dylib.lookupFunction<_c_sqlite3_column_type,
+        _dart_sqlite3_column_type>('sqlite3_column_type');
+    return _sqlite3_column_type(
+      arg0,
+      iCol,
+    );
+  }
+
+  _dart_sqlite3_column_type _sqlite3_column_type;
+
+  /// CAPI3REF: Destroy A Prepared Statement Object
+  /// DESTRUCTOR: sqlite3_stmt
+  ///
+  /// ^The sqlite3_finalize() function is called to delete a [prepared statement].
+  /// ^If the most recent evaluation of the statement encountered no errors
+  /// or if the statement is never been evaluated, then sqlite3_finalize() returns
+  /// SQLITE_OK.  ^If the most recent evaluation of statement S failed, then
+  /// sqlite3_finalize(S) returns the appropriate [error code] or
+  /// [extended error code].
+  ///
+  /// ^The sqlite3_finalize(S) routine can be called at any point during
+  /// the life cycle of [prepared statement] S:
+  /// before statement S is ever evaluated, after
+  /// one or more calls to [sqlite3_reset()], or after any call
+  /// to [sqlite3_step()] regardless of whether or not the statement has
+  /// completed execution.
+  ///
+  /// ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
+  ///
+  /// The application must finalize every [prepared statement] in order to avoid
+  /// resource leaks.  It is a grievous error for the application to try to use
+  /// a prepared statement after it has been finalized.  Any use of a prepared
+  /// statement after it has been finalized can result in undefined and
+  /// undesirable behavior such as segfaults and heap corruption.
+  int sqlite3_finalize(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    _sqlite3_finalize ??=
+        _dylib.lookupFunction<_c_sqlite3_finalize, _dart_sqlite3_finalize>(
+            'sqlite3_finalize');
+    return _sqlite3_finalize(
+      pStmt,
+    );
+  }
+
+  _dart_sqlite3_finalize _sqlite3_finalize;
+}
+
+class sqlite3 extends ffi.Struct {}
+
+class sqlite3_file extends ffi.Struct {}
+
+class sqlite3_io_methods extends ffi.Struct {
+  @ffi.Int32()
+  int iVersion;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_1>> xClose;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_2>> xRead;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_3>> xWrite;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_4>> xTruncate;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_5>> xSync;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_6>> xFileSize;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_7>> xLock;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_8>> xUnlock;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_9>> xCheckReservedLock;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_10>> xFileControl;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_11>> xSectorSize;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_12>> xDeviceCharacteristics;
+
+  /// Methods above are valid for version 1
+  ffi.Pointer<ffi.NativeFunction<_typedefC_13>> xShmMap;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_14>> xShmLock;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_15>> xShmBarrier;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_16>> xShmUnmap;
+
+  /// Methods above are valid for version 2
+  ffi.Pointer<ffi.NativeFunction<_typedefC_17>> xFetch;
+
+  ffi.Pointer<ffi.NativeFunction<_typedefC_18>> xUnfetch;
+}
+
+class sqlite3_mutex extends ffi.Struct {}
+
+class sqlite3_api_routines extends ffi.Struct {}
+
+class sqlite3_vfs extends ffi.Struct {}
+
+class sqlite3_mem_methods extends ffi.Struct {}
+
+class sqlite3_stmt extends ffi.Struct {}
+
+class sqlite3_value extends ffi.Struct {}
+
+class sqlite3_context extends ffi.Struct {}
+
+/// CAPI3REF: Virtual Table Instance Object
+/// KEYWORDS: sqlite3_vtab
+///
+/// Every [virtual table module] implementation uses a subclass
+/// of this object to describe a particular instance
+/// of the [virtual table].  Each subclass will
+/// be tailored to the specific needs of the module implementation.
+/// The purpose of this superclass is to define certain fields that are
+/// common to all module implementations.
+///
+/// ^Virtual tables methods can set an error message by assigning a
+/// string obtained from [sqlite3_mprintf()] to zErrMsg.  The method should
+/// take care that any prior string is freed by a call to [sqlite3_free()]
+/// prior to assigning a new string to zErrMsg.  ^After the error message
+/// is delivered up to the client application, the string will be automatically
+/// freed by sqlite3_free() and the zErrMsg field will be zeroed.
+class sqlite3_vtab extends ffi.Struct {}
+
+/// CAPI3REF: Virtual Table Indexing Information
+/// KEYWORDS: sqlite3_index_info
+///
+/// The sqlite3_index_info structure and its substructures is used as part
+/// of the [virtual table] interface to
+/// pass information into and receive the reply from the [xBestIndex]
+/// method of a [virtual table module].  The fields under **Inputs** are the
+/// inputs to xBestIndex and are read-only.  xBestIndex inserts its
+/// results into the **Outputs** fields.
+///
+/// ^(The aConstraint[] array records WHERE clause constraints of the form:
+///
+/// <blockquote>column OP expr</blockquote>
+///
+/// where OP is =, &lt;, &lt;=, &gt;, or &gt;=.)^  ^(The particular operator is
+/// stored in aConstraint[].op using one of the
+/// [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^
+/// ^(The index of the column is stored in
+/// aConstraint[].iColumn.)^  ^(aConstraint[].usable is TRUE if the
+/// expr on the right-hand side can be evaluated (and thus the constraint
+/// is usable) and false if it cannot.)^
+///
+/// ^The optimizer automatically inverts terms of the form "expr OP column"
+/// and makes other simplifications to the WHERE clause in an attempt to
+/// get as many WHERE clause terms into the form shown above as possible.
+/// ^The aConstraint[] array only reports WHERE clause terms that are
+/// relevant to the particular virtual table being queried.
+///
+/// ^Information about the ORDER BY clause is stored in aOrderBy[].
+/// ^Each term of aOrderBy records a column of the ORDER BY clause.
+///
+/// The colUsed field indicates which columns of the virtual table may be
+/// required by the current scan. Virtual table columns are numbered from
+/// zero in the order in which they appear within the CREATE TABLE statement
+/// passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
+/// the corresponding bit is set within the colUsed mask if the column may be
+/// required by SQLite. If the table has at least 64 columns and any column
+/// to the right of the first 63 is required, then bit 63 of colUsed is also
+/// set. In other words, column iCol may be required if the expression
+/// (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to
+/// non-zero.
+///
+/// The [xBestIndex] method must fill aConstraintUsage[] with information
+/// about what parameters to pass to xFilter.  ^If argvIndex>0 then
+/// the right-hand side of the corresponding aConstraint[] is evaluated
+/// and becomes the argvIndex-th entry in argv.  ^(If aConstraintUsage[].omit
+/// is true, then the constraint is assumed to be fully handled by the
+/// virtual table and might not be checked again by the byte code.)^ ^(The
+/// aConstraintUsage[].omit flag is an optimization hint. When the omit flag
+/// is left in its default setting of false, the constraint will always be
+/// checked separately in byte code.  If the omit flag is change to true, then
+/// the constraint may or may not be checked in byte code.  In other words,
+/// when the omit flag is true there is no guarantee that the constraint will
+/// not be checked again using byte code.)^
+///
+/// ^The idxNum and idxPtr values are recorded and passed into the
+/// [xFilter] method.
+/// ^[sqlite3_free()] is used to free idxPtr if and only if
+/// needToFreeIdxPtr is true.
+///
+/// ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
+/// the correct order to satisfy the ORDER BY clause so that no separate
+/// sorting step is required.
+///
+/// ^The estimatedCost value is an estimate of the cost of a particular
+/// strategy. A cost of N indicates that the cost of the strategy is similar
+/// to a linear scan of an SQLite table with N rows. A cost of log(N)
+/// indicates that the expense of the operation is similar to that of a
+/// binary search on a unique indexed field of an SQLite table with N rows.
+///
+/// ^The estimatedRows value is an estimate of the number of rows that
+/// will be returned by the strategy.
+///
+/// The xBestIndex method may optionally populate the idxFlags field with a
+/// mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
+/// SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
+/// assumes that the strategy may visit at most one row.
+///
+/// Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
+/// SQLite also assumes that if a call to the xUpdate() method is made as
+/// part of the same statement to delete or update a virtual table row and the
+/// implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
+/// any database changes. In other words, if the xUpdate() returns
+/// SQLITE_CONSTRAINT, the database contents must be exactly as they were
+/// before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
+/// set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
+/// the xUpdate method are automatically rolled back by SQLite.
+///
+/// IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+/// structure for SQLite [version 3.8.2] ([dateof:3.8.2]).
+/// If a virtual table extension is
+/// used with an SQLite version earlier than 3.8.2, the results of attempting
+/// to read or write the estimatedRows field are undefined (but are likely
+/// to include crashing the application). The estimatedRows field should
+/// therefore only be used if [sqlite3_libversion_number()] returns a
+/// value greater than or equal to 3008002. Similarly, the idxFlags field
+/// was added for [version 3.9.0] ([dateof:3.9.0]).
+/// It may therefore only be used if
+/// sqlite3_libversion_number() returns a value greater than or equal to
+/// 3009000.
+class sqlite3_index_info extends ffi.Struct {}
+
+/// CAPI3REF: Virtual Table Cursor Object
+/// KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
+///
+/// Every [virtual table module] implementation uses a subclass of the
+/// following structure to describe cursors that point into the
+/// [virtual table] and are used
+/// to loop through the virtual table.  Cursors are created using the
+/// [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
+/// by the [sqlite3_module.xClose | xClose] method.  Cursors are used
+/// by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
+/// of the module.  Each module implementation will define
+/// the content of a cursor structure to suit its own needs.
+///
+/// This superclass exists in order to define fields of the cursor that
+/// are common to all implementations.
+class sqlite3_vtab_cursor extends ffi.Struct {}
+
+/// CAPI3REF: Virtual Table Object
+/// KEYWORDS: sqlite3_module {virtual table module}
+///
+/// This structure, sometimes called a "virtual table module",
+/// defines the implementation of a [virtual table].
+/// This structure consists mostly of methods for the module.
+///
+/// ^A virtual table module is created by filling in a persistent
+/// instance of this structure and passing a pointer to that instance
+/// to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
+/// ^The registration remains valid until it is replaced by a different
+/// module or until the [database connection] closes.  The content
+/// of this structure must not change while it is registered with
+/// any database connection.
+class sqlite3_module extends ffi.Struct {}
+
+class sqlite3_blob extends ffi.Struct {}
+
+class sqlite3_mutex_methods extends ffi.Struct {}
+
+class sqlite3_str extends ffi.Struct {}
+
+class sqlite3_pcache extends ffi.Struct {}
+
+class sqlite3_pcache_page extends ffi.Struct {}
+
+class sqlite3_pcache_methods2 extends ffi.Struct {}
+
+class sqlite3_pcache_methods extends ffi.Struct {}
+
+class sqlite3_backup extends ffi.Struct {}
+
+/// CAPI3REF: Database Snapshot
+/// KEYWORDS: {snapshot} {sqlite3_snapshot}
+///
+/// An instance of the snapshot object records the state of a [WAL mode]
+/// database for some specific point in history.
+///
+/// In [WAL mode], multiple [database connections] that are open on the
+/// same database file can each be reading a different historical version
+/// of the database file.  When a [database connection] begins a read
+/// transaction, that connection sees an unchanging copy of the database
+/// as it existed for the point in time when the transaction first started.
+/// Subsequent changes to the database from other connections are not seen
+/// by the reader until a new read transaction is started.
+///
+/// The sqlite3_snapshot object records state information about an historical
+/// version of the database file so that it is possible to later open a new read
+/// transaction that sees that historical version of the database rather than
+/// the most recent version.
+class sqlite3_snapshot extends ffi.Struct {}
+
+/// A pointer to a structure of the following type is passed as the first
+/// argument to callbacks registered using rtree_geometry_callback().
+class sqlite3_rtree_geometry extends ffi.Struct {}
+
+/// A pointer to a structure of the following type is passed as the
+/// argument to scored geometry callback registered using
+/// sqlite3_rtree_query_callback().
+///
+/// Note that the first 5 fields of this structure are identical to
+/// sqlite3_rtree_geometry.  This structure is a subclass of
+/// sqlite3_rtree_geometry.
+class sqlite3_rtree_query_info extends ffi.Struct {}
+
+/// EXTENSION API FUNCTIONS
+///
+/// xUserData(pFts):
+/// Return a copy of the context pointer the extension function was
+/// registered with.
+///
+/// xColumnTotalSize(pFts, iCol, pnToken):
+/// If parameter iCol is less than zero, set output variable *pnToken
+/// to the total number of tokens in the FTS5 table. Or, if iCol is
+/// non-negative but less than the number of columns in the table, return
+/// the total number of tokens in column iCol, considering all rows in
+/// the FTS5 table.
+///
+/// If parameter iCol is greater than or equal to the number of columns
+/// in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+/// an OOM condition or IO error), an appropriate SQLite error code is
+/// returned.
+///
+/// xColumnCount(pFts):
+/// Return the number of columns in the table.
+///
+/// xColumnSize(pFts, iCol, pnToken):
+/// If parameter iCol is less than zero, set output variable *pnToken
+/// to the total number of tokens in the current row. Or, if iCol is
+/// non-negative but less than the number of columns in the table, set
+/// *pnToken to the number of tokens in column iCol of the current row.
+///
+/// If parameter iCol is greater than or equal to the number of columns
+/// in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+/// an OOM condition or IO error), an appropriate SQLite error code is
+/// returned.
+///
+/// This function may be quite inefficient if used with an FTS5 table
+/// created with the "columnsize=0" option.
+///
+/// xColumnText:
+/// This function attempts to retrieve the text of column iCol of the
+/// current document. If successful, (*pz) is set to point to a buffer
+/// containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+/// (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+/// if an error occurs, an SQLite error code is returned and the final values
+/// of (*pz) and (*pn) are undefined.
+///
+/// xPhraseCount:
+/// Returns the number of phrases in the current query expression.
+///
+/// xPhraseSize:
+/// Returns the number of tokens in phrase iPhrase of the query. Phrases
+/// are numbered starting from zero.
+///
+/// xInstCount:
+/// Set *pnInst to the total number of occurrences of all phrases within
+/// the query within the current row. Return SQLITE_OK if successful, or
+/// an error code (i.e. SQLITE_NOMEM) if an error occurs.
+///
+/// This API can be quite slow if used with an FTS5 table created with the
+/// "detail=none" or "detail=column" option. If the FTS5 table is created
+/// with either "detail=none" or "detail=column" and "content=" option
+/// (i.e. if it is a contentless table), then this API always returns 0.
+///
+/// xInst:
+/// Query for the details of phrase match iIdx within the current row.
+/// Phrase matches are numbered starting from zero, so the iIdx argument
+/// should be greater than or equal to zero and smaller than the value
+/// output by xInstCount().
+///
+/// Usually, output parameter *piPhrase is set to the phrase number, *piCol
+/// to the column in which it occurs and *piOff the token offset of the
+/// first token of the phrase. Returns SQLITE_OK if successful, or an error
+/// code (i.e. SQLITE_NOMEM) if an error occurs.
+///
+/// This API can be quite slow if used with an FTS5 table created with the
+/// "detail=none" or "detail=column" option.
+///
+/// xRowid:
+/// Returns the rowid of the current row.
+///
+/// xTokenize:
+/// Tokenize text using the tokenizer belonging to the FTS5 table.
+///
+/// xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+/// This API function is used to query the FTS table for phrase iPhrase
+/// of the current query. Specifically, a query equivalent to:
+///
+/// ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+///
+/// with $p set to a phrase equivalent to the phrase iPhrase of the
+/// current query is executed. Any column filter that applies to
+/// phrase iPhrase of the current query is included in $p. For each
+/// row visited, the callback function passed as the fourth argument
+/// is invoked. The context and API objects passed to the callback
+/// function may be used to access the properties of each matched row.
+/// Invoking Api.xUserData() returns a copy of the pointer passed as
+/// the third argument to pUserData.
+///
+/// If the callback function returns any value other than SQLITE_OK, the
+/// query is abandoned and the xQueryPhrase function returns immediately.
+/// If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+/// Otherwise, the error code is propagated upwards.
+///
+/// If the query runs to completion without incident, SQLITE_OK is returned.
+/// Or, if some error occurs before the query completes or is aborted by
+/// the callback, an SQLite error code is returned.
+///
+///
+/// xSetAuxdata(pFts5, pAux, xDelete)
+///
+/// Save the pointer passed as the second argument as the extension function's
+/// "auxiliary data". The pointer may then be retrieved by the current or any
+/// future invocation of the same fts5 extension function made as part of
+/// the same MATCH query using the xGetAuxdata() API.
+///
+/// Each extension function is allocated a single auxiliary data slot for
+/// each FTS query (MATCH expression). If the extension function is invoked
+/// more than once for a single FTS query, then all invocations share a
+/// single auxiliary data context.
+///
+/// If there is already an auxiliary data pointer when this function is
+/// invoked, then it is replaced by the new pointer. If an xDelete callback
+/// was specified along with the original pointer, it is invoked at this
+/// point.
+///
+/// The xDelete callback, if one is specified, is also invoked on the
+/// auxiliary data pointer after the FTS5 query has finished.
+///
+/// If an error (e.g. an OOM condition) occurs within this function,
+/// the auxiliary data is set to NULL and an error code returned. If the
+/// xDelete parameter was not NULL, it is invoked on the auxiliary data
+/// pointer before returning.
+///
+///
+/// xGetAuxdata(pFts5, bClear)
+///
+/// Returns the current auxiliary data pointer for the fts5 extension
+/// function. See the xSetAuxdata() method for details.
+///
+/// If the bClear argument is non-zero, then the auxiliary data is cleared
+/// (set to NULL) before this function returns. In this case the xDelete,
+/// if any, is not invoked.
+///
+///
+/// xRowCount(pFts5, pnRow)
+///
+/// This function is used to retrieve the total number of rows in the table.
+/// In other words, the same value that would be returned by:
+///
+/// SELECT count(*) FROM ftstable;
+///
+/// xPhraseFirst()
+/// This function is used, along with type Fts5PhraseIter and the xPhraseNext
+/// method, to iterate through all instances of a single query phrase within
+/// the current row. This is the same information as is accessible via the
+/// xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+/// to use, this API may be faster under some circumstances. To iterate
+/// through instances of phrase iPhrase, use the following code:
+///
+/// Fts5PhraseIter iter;
+/// int iCol, iOff;
+/// for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+/// iCol>=0;
+/// pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+/// ){
+/// // An instance of phrase iPhrase at offset iOff of column iCol
+/// }
+///
+/// The Fts5PhraseIter structure is defined above. Applications should not
+/// modify this structure directly - it should only be used as shown above
+/// with the xPhraseFirst() and xPhraseNext() API methods (and by
+/// xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
+///
+/// This API can be quite slow if used with an FTS5 table created with the
+/// "detail=none" or "detail=column" option. If the FTS5 table is created
+/// with either "detail=none" or "detail=column" and "content=" option
+/// (i.e. if it is a contentless table), then this API always iterates
+/// through an empty set (all calls to xPhraseFirst() set iCol to -1).
+///
+/// xPhraseNext()
+/// See xPhraseFirst above.
+///
+/// xPhraseFirstColumn()
+/// This function and xPhraseNextColumn() are similar to the xPhraseFirst()
+/// and xPhraseNext() APIs described above. The difference is that instead
+/// of iterating through all instances of a phrase in the current row, these
+/// APIs are used to iterate through the set of columns in the current row
+/// that contain one or more instances of a specified phrase. For example:
+///
+/// Fts5PhraseIter iter;
+/// int iCol;
+/// for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
+/// iCol>=0;
+/// pApi->xPhraseNextColumn(pFts, &iter, &iCol)
+/// ){
+/// // Column iCol contains at least one instance of phrase iPhrase
+/// }
+///
+/// This API can be quite slow if used with an FTS5 table created with the
+/// "detail=none" option. If the FTS5 table is created with either
+/// "detail=none" "content=" option (i.e. if it is a contentless table),
+/// then this API always iterates through an empty set (all calls to
+/// xPhraseFirstColumn() set iCol to -1).
+///
+/// The information accessed using this API and its companion
+/// xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
+/// (or xInst/xInstCount). The chief advantage of this API is that it is
+/// significantly more efficient than those alternatives when used with
+/// "detail=column" tables.
+///
+/// xPhraseNextColumn()
+/// See xPhraseFirstColumn above.
+class Fts5ExtensionApi extends ffi.Struct {}
+
+class Fts5Context extends ffi.Struct {}
+
+class Fts5PhraseIter extends ffi.Struct {}
+
+class Fts5Tokenizer extends ffi.Struct {}
+
+class fts5_tokenizer extends ffi.Struct {}
+
+class fts5_api extends ffi.Struct {}
+
+const String SQLITE_VERSION = '3.32.3';
+
+const int SQLITE_VERSION_NUMBER = 3032003;
+
+const String SQLITE_SOURCE_ID =
+    '2020-06-18 14:00:33 7ebdfa80be8e8e73324b8d66b3460222eb74c7e9dfd655b48d6ca7e1933cc8fd';
+
+const int SQLITE_OK = 0;
+
+const int SQLITE_ERROR = 1;
+
+const int SQLITE_INTERNAL = 2;
+
+const int SQLITE_PERM = 3;
+
+const int SQLITE_ABORT = 4;
+
+const int SQLITE_BUSY = 5;
+
+const int SQLITE_LOCKED = 6;
+
+const int SQLITE_NOMEM = 7;
+
+const int SQLITE_READONLY = 8;
+
+const int SQLITE_INTERRUPT = 9;
+
+const int SQLITE_IOERR = 10;
+
+const int SQLITE_CORRUPT = 11;
+
+const int SQLITE_NOTFOUND = 12;
+
+const int SQLITE_FULL = 13;
+
+const int SQLITE_CANTOPEN = 14;
+
+const int SQLITE_PROTOCOL = 15;
+
+const int SQLITE_EMPTY = 16;
+
+const int SQLITE_SCHEMA = 17;
+
+const int SQLITE_TOOBIG = 18;
+
+const int SQLITE_CONSTRAINT = 19;
+
+const int SQLITE_MISMATCH = 20;
+
+const int SQLITE_MISUSE = 21;
+
+const int SQLITE_NOLFS = 22;
+
+const int SQLITE_AUTH = 23;
+
+const int SQLITE_FORMAT = 24;
+
+const int SQLITE_RANGE = 25;
+
+const int SQLITE_NOTADB = 26;
+
+const int SQLITE_NOTICE = 27;
+
+const int SQLITE_WARNING = 28;
+
+const int SQLITE_ROW = 100;
+
+const int SQLITE_DONE = 101;
+
+const int SQLITE_ERROR_MISSING_COLLSEQ = 257;
+
+const int SQLITE_ERROR_RETRY = 513;
+
+const int SQLITE_ERROR_SNAPSHOT = 769;
+
+const int SQLITE_IOERR_READ = 266;
+
+const int SQLITE_IOERR_SHORT_READ = 522;
+
+const int SQLITE_IOERR_WRITE = 778;
+
+const int SQLITE_IOERR_FSYNC = 1034;
+
+const int SQLITE_IOERR_DIR_FSYNC = 1290;
+
+const int SQLITE_IOERR_TRUNCATE = 1546;
+
+const int SQLITE_IOERR_FSTAT = 1802;
+
+const int SQLITE_IOERR_UNLOCK = 2058;
+
+const int SQLITE_IOERR_RDLOCK = 2314;
+
+const int SQLITE_IOERR_DELETE = 2570;
+
+const int SQLITE_IOERR_BLOCKED = 2826;
+
+const int SQLITE_IOERR_NOMEM = 3082;
+
+const int SQLITE_IOERR_ACCESS = 3338;
+
+const int SQLITE_IOERR_CHECKRESERVEDLOCK = 3594;
+
+const int SQLITE_IOERR_LOCK = 3850;
+
+const int SQLITE_IOERR_CLOSE = 4106;
+
+const int SQLITE_IOERR_DIR_CLOSE = 4362;
+
+const int SQLITE_IOERR_SHMOPEN = 4618;
+
+const int SQLITE_IOERR_SHMSIZE = 4874;
+
+const int SQLITE_IOERR_SHMLOCK = 5130;
+
+const int SQLITE_IOERR_SHMMAP = 5386;
+
+const int SQLITE_IOERR_SEEK = 5642;
+
+const int SQLITE_IOERR_DELETE_NOENT = 5898;
+
+const int SQLITE_IOERR_MMAP = 6154;
+
+const int SQLITE_IOERR_GETTEMPPATH = 6410;
+
+const int SQLITE_IOERR_CONVPATH = 6666;
+
+const int SQLITE_IOERR_VNODE = 6922;
+
+const int SQLITE_IOERR_AUTH = 7178;
+
+const int SQLITE_IOERR_BEGIN_ATOMIC = 7434;
+
+const int SQLITE_IOERR_COMMIT_ATOMIC = 7690;
+
+const int SQLITE_IOERR_ROLLBACK_ATOMIC = 7946;
+
+const int SQLITE_IOERR_DATA = 8202;
+
+const int SQLITE_LOCKED_SHAREDCACHE = 262;
+
+const int SQLITE_LOCKED_VTAB = 518;
+
+const int SQLITE_BUSY_RECOVERY = 261;
+
+const int SQLITE_BUSY_SNAPSHOT = 517;
+
+const int SQLITE_BUSY_TIMEOUT = 773;
+
+const int SQLITE_CANTOPEN_NOTEMPDIR = 270;
+
+const int SQLITE_CANTOPEN_ISDIR = 526;
+
+const int SQLITE_CANTOPEN_FULLPATH = 782;
+
+const int SQLITE_CANTOPEN_CONVPATH = 1038;
+
+const int SQLITE_CANTOPEN_DIRTYWAL = 1294;
+
+const int SQLITE_CANTOPEN_SYMLINK = 1550;
+
+const int SQLITE_CORRUPT_VTAB = 267;
+
+const int SQLITE_CORRUPT_SEQUENCE = 523;
+
+const int SQLITE_CORRUPT_INDEX = 779;
+
+const int SQLITE_READONLY_RECOVERY = 264;
+
+const int SQLITE_READONLY_CANTLOCK = 520;
+
+const int SQLITE_READONLY_ROLLBACK = 776;
+
+const int SQLITE_READONLY_DBMOVED = 1032;
+
+const int SQLITE_READONLY_CANTINIT = 1288;
+
+const int SQLITE_READONLY_DIRECTORY = 1544;
+
+const int SQLITE_ABORT_ROLLBACK = 516;
+
+const int SQLITE_CONSTRAINT_CHECK = 275;
+
+const int SQLITE_CONSTRAINT_COMMITHOOK = 531;
+
+const int SQLITE_CONSTRAINT_FOREIGNKEY = 787;
+
+const int SQLITE_CONSTRAINT_FUNCTION = 1043;
+
+const int SQLITE_CONSTRAINT_NOTNULL = 1299;
+
+const int SQLITE_CONSTRAINT_PRIMARYKEY = 1555;
+
+const int SQLITE_CONSTRAINT_TRIGGER = 1811;
+
+const int SQLITE_CONSTRAINT_UNIQUE = 2067;
+
+const int SQLITE_CONSTRAINT_VTAB = 2323;
+
+const int SQLITE_CONSTRAINT_ROWID = 2579;
+
+const int SQLITE_CONSTRAINT_PINNED = 2835;
+
+const int SQLITE_NOTICE_RECOVER_WAL = 283;
+
+const int SQLITE_NOTICE_RECOVER_ROLLBACK = 539;
+
+const int SQLITE_WARNING_AUTOINDEX = 284;
+
+const int SQLITE_AUTH_USER = 279;
+
+const int SQLITE_OK_LOAD_PERMANENTLY = 256;
+
+const int SQLITE_OK_SYMLINK = 512;
+
+const int SQLITE_OPEN_READONLY = 1;
+
+const int SQLITE_OPEN_READWRITE = 2;
+
+const int SQLITE_OPEN_CREATE = 4;
+
+const int SQLITE_OPEN_DELETEONCLOSE = 8;
+
+const int SQLITE_OPEN_EXCLUSIVE = 16;
+
+const int SQLITE_OPEN_AUTOPROXY = 32;
+
+const int SQLITE_OPEN_URI = 64;
+
+const int SQLITE_OPEN_MEMORY = 128;
+
+const int SQLITE_OPEN_MAIN_DB = 256;
+
+const int SQLITE_OPEN_TEMP_DB = 512;
+
+const int SQLITE_OPEN_TRANSIENT_DB = 1024;
+
+const int SQLITE_OPEN_MAIN_JOURNAL = 2048;
+
+const int SQLITE_OPEN_TEMP_JOURNAL = 4096;
+
+const int SQLITE_OPEN_SUBJOURNAL = 8192;
+
+const int SQLITE_OPEN_MASTER_JOURNAL = 16384;
+
+const int SQLITE_OPEN_NOMUTEX = 32768;
+
+const int SQLITE_OPEN_FULLMUTEX = 65536;
+
+const int SQLITE_OPEN_SHAREDCACHE = 131072;
+
+const int SQLITE_OPEN_PRIVATECACHE = 262144;
+
+const int SQLITE_OPEN_WAL = 524288;
+
+const int SQLITE_OPEN_NOFOLLOW = 16777216;
+
+const int SQLITE_IOCAP_ATOMIC = 1;
+
+const int SQLITE_IOCAP_ATOMIC512 = 2;
+
+const int SQLITE_IOCAP_ATOMIC1K = 4;
+
+const int SQLITE_IOCAP_ATOMIC2K = 8;
+
+const int SQLITE_IOCAP_ATOMIC4K = 16;
+
+const int SQLITE_IOCAP_ATOMIC8K = 32;
+
+const int SQLITE_IOCAP_ATOMIC16K = 64;
+
+const int SQLITE_IOCAP_ATOMIC32K = 128;
+
+const int SQLITE_IOCAP_ATOMIC64K = 256;
+
+const int SQLITE_IOCAP_SAFE_APPEND = 512;
+
+const int SQLITE_IOCAP_SEQUENTIAL = 1024;
+
+const int SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN = 2048;
+
+const int SQLITE_IOCAP_POWERSAFE_OVERWRITE = 4096;
+
+const int SQLITE_IOCAP_IMMUTABLE = 8192;
+
+const int SQLITE_IOCAP_BATCH_ATOMIC = 16384;
+
+const int SQLITE_LOCK_NONE = 0;
+
+const int SQLITE_LOCK_SHARED = 1;
+
+const int SQLITE_LOCK_RESERVED = 2;
+
+const int SQLITE_LOCK_PENDING = 3;
+
+const int SQLITE_LOCK_EXCLUSIVE = 4;
+
+const int SQLITE_SYNC_NORMAL = 2;
+
+const int SQLITE_SYNC_FULL = 3;
+
+const int SQLITE_SYNC_DATAONLY = 16;
+
+const int SQLITE_FCNTL_LOCKSTATE = 1;
+
+const int SQLITE_FCNTL_GET_LOCKPROXYFILE = 2;
+
+const int SQLITE_FCNTL_SET_LOCKPROXYFILE = 3;
+
+const int SQLITE_FCNTL_LAST_ERRNO = 4;
+
+const int SQLITE_FCNTL_SIZE_HINT = 5;
+
+const int SQLITE_FCNTL_CHUNK_SIZE = 6;
+
+const int SQLITE_FCNTL_FILE_POINTER = 7;
+
+const int SQLITE_FCNTL_SYNC_OMITTED = 8;
+
+const int SQLITE_FCNTL_WIN32_AV_RETRY = 9;
+
+const int SQLITE_FCNTL_PERSIST_WAL = 10;
+
+const int SQLITE_FCNTL_OVERWRITE = 11;
+
+const int SQLITE_FCNTL_VFSNAME = 12;
+
+const int SQLITE_FCNTL_POWERSAFE_OVERWRITE = 13;
+
+const int SQLITE_FCNTL_PRAGMA = 14;
+
+const int SQLITE_FCNTL_BUSYHANDLER = 15;
+
+const int SQLITE_FCNTL_TEMPFILENAME = 16;
+
+const int SQLITE_FCNTL_MMAP_SIZE = 18;
+
+const int SQLITE_FCNTL_TRACE = 19;
+
+const int SQLITE_FCNTL_HAS_MOVED = 20;
+
+const int SQLITE_FCNTL_SYNC = 21;
+
+const int SQLITE_FCNTL_COMMIT_PHASETWO = 22;
+
+const int SQLITE_FCNTL_WIN32_SET_HANDLE = 23;
+
+const int SQLITE_FCNTL_WAL_BLOCK = 24;
+
+const int SQLITE_FCNTL_ZIPVFS = 25;
+
+const int SQLITE_FCNTL_RBU = 26;
+
+const int SQLITE_FCNTL_VFS_POINTER = 27;
+
+const int SQLITE_FCNTL_JOURNAL_POINTER = 28;
+
+const int SQLITE_FCNTL_WIN32_GET_HANDLE = 29;
+
+const int SQLITE_FCNTL_PDB = 30;
+
+const int SQLITE_FCNTL_BEGIN_ATOMIC_WRITE = 31;
+
+const int SQLITE_FCNTL_COMMIT_ATOMIC_WRITE = 32;
+
+const int SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE = 33;
+
+const int SQLITE_FCNTL_LOCK_TIMEOUT = 34;
+
+const int SQLITE_FCNTL_DATA_VERSION = 35;
+
+const int SQLITE_FCNTL_SIZE_LIMIT = 36;
+
+const int SQLITE_FCNTL_CKPT_DONE = 37;
+
+const int SQLITE_FCNTL_RESERVE_BYTES = 38;
+
+const int SQLITE_FCNTL_CKPT_START = 39;
+
+const int SQLITE_GET_LOCKPROXYFILE = 2;
+
+const int SQLITE_SET_LOCKPROXYFILE = 3;
+
+const int SQLITE_LAST_ERRNO = 4;
+
+const int SQLITE_ACCESS_EXISTS = 0;
+
+const int SQLITE_ACCESS_READWRITE = 1;
+
+const int SQLITE_ACCESS_READ = 2;
+
+const int SQLITE_SHM_UNLOCK = 1;
+
+const int SQLITE_SHM_LOCK = 2;
+
+const int SQLITE_SHM_SHARED = 4;
+
+const int SQLITE_SHM_EXCLUSIVE = 8;
+
+const int SQLITE_SHM_NLOCK = 8;
+
+const int SQLITE_CONFIG_SINGLETHREAD = 1;
+
+const int SQLITE_CONFIG_MULTITHREAD = 2;
+
+const int SQLITE_CONFIG_SERIALIZED = 3;
+
+const int SQLITE_CONFIG_MALLOC = 4;
+
+const int SQLITE_CONFIG_GETMALLOC = 5;
+
+const int SQLITE_CONFIG_SCRATCH = 6;
+
+const int SQLITE_CONFIG_PAGECACHE = 7;
+
+const int SQLITE_CONFIG_HEAP = 8;
+
+const int SQLITE_CONFIG_MEMSTATUS = 9;
+
+const int SQLITE_CONFIG_MUTEX = 10;
+
+const int SQLITE_CONFIG_GETMUTEX = 11;
+
+const int SQLITE_CONFIG_LOOKASIDE = 13;
+
+const int SQLITE_CONFIG_PCACHE = 14;
+
+const int SQLITE_CONFIG_GETPCACHE = 15;
+
+const int SQLITE_CONFIG_LOG = 16;
+
+const int SQLITE_CONFIG_URI = 17;
+
+const int SQLITE_CONFIG_PCACHE2 = 18;
+
+const int SQLITE_CONFIG_GETPCACHE2 = 19;
+
+const int SQLITE_CONFIG_COVERING_INDEX_SCAN = 20;
+
+const int SQLITE_CONFIG_SQLLOG = 21;
+
+const int SQLITE_CONFIG_MMAP_SIZE = 22;
+
+const int SQLITE_CONFIG_WIN32_HEAPSIZE = 23;
+
+const int SQLITE_CONFIG_PCACHE_HDRSZ = 24;
+
+const int SQLITE_CONFIG_PMASZ = 25;
+
+const int SQLITE_CONFIG_STMTJRNL_SPILL = 26;
+
+const int SQLITE_CONFIG_SMALL_MALLOC = 27;
+
+const int SQLITE_CONFIG_SORTERREF_SIZE = 28;
+
+const int SQLITE_CONFIG_MEMDB_MAXSIZE = 29;
+
+const int SQLITE_DBCONFIG_MAINDBNAME = 1000;
+
+const int SQLITE_DBCONFIG_LOOKASIDE = 1001;
+
+const int SQLITE_DBCONFIG_ENABLE_FKEY = 1002;
+
+const int SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003;
+
+const int SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER = 1004;
+
+const int SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION = 1005;
+
+const int SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE = 1006;
+
+const int SQLITE_DBCONFIG_ENABLE_QPSG = 1007;
+
+const int SQLITE_DBCONFIG_TRIGGER_EQP = 1008;
+
+const int SQLITE_DBCONFIG_RESET_DATABASE = 1009;
+
+const int SQLITE_DBCONFIG_DEFENSIVE = 1010;
+
+const int SQLITE_DBCONFIG_WRITABLE_SCHEMA = 1011;
+
+const int SQLITE_DBCONFIG_LEGACY_ALTER_TABLE = 1012;
+
+const int SQLITE_DBCONFIG_DQS_DML = 1013;
+
+const int SQLITE_DBCONFIG_DQS_DDL = 1014;
+
+const int SQLITE_DBCONFIG_ENABLE_VIEW = 1015;
+
+const int SQLITE_DBCONFIG_LEGACY_FILE_FORMAT = 1016;
+
+const int SQLITE_DBCONFIG_TRUSTED_SCHEMA = 1017;
+
+const int SQLITE_DBCONFIG_MAX = 1017;
+
+const int SQLITE_DENY = 1;
+
+const int SQLITE_IGNORE = 2;
+
+const int SQLITE_CREATE_INDEX = 1;
+
+const int SQLITE_CREATE_TABLE = 2;
+
+const int SQLITE_CREATE_TEMP_INDEX = 3;
+
+const int SQLITE_CREATE_TEMP_TABLE = 4;
+
+const int SQLITE_CREATE_TEMP_TRIGGER = 5;
+
+const int SQLITE_CREATE_TEMP_VIEW = 6;
+
+const int SQLITE_CREATE_TRIGGER = 7;
+
+const int SQLITE_CREATE_VIEW = 8;
+
+const int SQLITE_DELETE = 9;
+
+const int SQLITE_DROP_INDEX = 10;
+
+const int SQLITE_DROP_TABLE = 11;
+
+const int SQLITE_DROP_TEMP_INDEX = 12;
+
+const int SQLITE_DROP_TEMP_TABLE = 13;
+
+const int SQLITE_DROP_TEMP_TRIGGER = 14;
+
+const int SQLITE_DROP_TEMP_VIEW = 15;
+
+const int SQLITE_DROP_TRIGGER = 16;
+
+const int SQLITE_DROP_VIEW = 17;
+
+const int SQLITE_INSERT = 18;
+
+const int SQLITE_PRAGMA = 19;
+
+const int SQLITE_READ = 20;
+
+const int SQLITE_SELECT = 21;
+
+const int SQLITE_TRANSACTION = 22;
+
+const int SQLITE_UPDATE = 23;
+
+const int SQLITE_ATTACH = 24;
+
+const int SQLITE_DETACH = 25;
+
+const int SQLITE_ALTER_TABLE = 26;
+
+const int SQLITE_REINDEX = 27;
+
+const int SQLITE_ANALYZE = 28;
+
+const int SQLITE_CREATE_VTABLE = 29;
+
+const int SQLITE_DROP_VTABLE = 30;
+
+const int SQLITE_FUNCTION = 31;
+
+const int SQLITE_SAVEPOINT = 32;
+
+const int SQLITE_COPY = 0;
+
+const int SQLITE_RECURSIVE = 33;
+
+const int SQLITE_TRACE_STMT = 1;
+
+const int SQLITE_TRACE_PROFILE = 2;
+
+const int SQLITE_TRACE_ROW = 4;
+
+const int SQLITE_TRACE_CLOSE = 8;
+
+const int SQLITE_LIMIT_LENGTH = 0;
+
+const int SQLITE_LIMIT_SQL_LENGTH = 1;
+
+const int SQLITE_LIMIT_COLUMN = 2;
+
+const int SQLITE_LIMIT_EXPR_DEPTH = 3;
+
+const int SQLITE_LIMIT_COMPOUND_SELECT = 4;
+
+const int SQLITE_LIMIT_VDBE_OP = 5;
+
+const int SQLITE_LIMIT_FUNCTION_ARG = 6;
+
+const int SQLITE_LIMIT_ATTACHED = 7;
+
+const int SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8;
+
+const int SQLITE_LIMIT_VARIABLE_NUMBER = 9;
+
+const int SQLITE_LIMIT_TRIGGER_DEPTH = 10;
+
+const int SQLITE_LIMIT_WORKER_THREADS = 11;
+
+const int SQLITE_PREPARE_PERSISTENT = 1;
+
+const int SQLITE_PREPARE_NORMALIZE = 2;
+
+const int SQLITE_PREPARE_NO_VTAB = 4;
+
+const int SQLITE_INTEGER = 1;
+
+const int SQLITE_FLOAT = 2;
+
+const int SQLITE_BLOB = 4;
+
+const int SQLITE_NULL = 5;
+
+const int SQLITE_TEXT = 3;
+
+const int SQLITE3_TEXT = 3;
+
+const int SQLITE_UTF8 = 1;
+
+const int SQLITE_UTF16LE = 2;
+
+const int SQLITE_UTF16BE = 3;
+
+const int SQLITE_UTF16 = 4;
+
+const int SQLITE_ANY = 5;
+
+const int SQLITE_UTF16_ALIGNED = 8;
+
+const int SQLITE_DETERMINISTIC = 2048;
+
+const int SQLITE_DIRECTONLY = 524288;
+
+const int SQLITE_SUBTYPE = 1048576;
+
+const int SQLITE_INNOCUOUS = 2097152;
+
+const int SQLITE_WIN32_DATA_DIRECTORY_TYPE = 1;
+
+const int SQLITE_WIN32_TEMP_DIRECTORY_TYPE = 2;
+
+const int SQLITE_INDEX_SCAN_UNIQUE = 1;
+
+const int SQLITE_INDEX_CONSTRAINT_EQ = 2;
+
+const int SQLITE_INDEX_CONSTRAINT_GT = 4;
+
+const int SQLITE_INDEX_CONSTRAINT_LE = 8;
+
+const int SQLITE_INDEX_CONSTRAINT_LT = 16;
+
+const int SQLITE_INDEX_CONSTRAINT_GE = 32;
+
+const int SQLITE_INDEX_CONSTRAINT_MATCH = 64;
+
+const int SQLITE_INDEX_CONSTRAINT_LIKE = 65;
+
+const int SQLITE_INDEX_CONSTRAINT_GLOB = 66;
+
+const int SQLITE_INDEX_CONSTRAINT_REGEXP = 67;
+
+const int SQLITE_INDEX_CONSTRAINT_NE = 68;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNOT = 69;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNOTNULL = 70;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNULL = 71;
+
+const int SQLITE_INDEX_CONSTRAINT_IS = 72;
+
+const int SQLITE_INDEX_CONSTRAINT_FUNCTION = 150;
+
+const int SQLITE_MUTEX_FAST = 0;
+
+const int SQLITE_MUTEX_RECURSIVE = 1;
+
+const int SQLITE_MUTEX_STATIC_MASTER = 2;
+
+const int SQLITE_MUTEX_STATIC_MEM = 3;
+
+const int SQLITE_MUTEX_STATIC_MEM2 = 4;
+
+const int SQLITE_MUTEX_STATIC_OPEN = 4;
+
+const int SQLITE_MUTEX_STATIC_PRNG = 5;
+
+const int SQLITE_MUTEX_STATIC_LRU = 6;
+
+const int SQLITE_MUTEX_STATIC_LRU2 = 7;
+
+const int SQLITE_MUTEX_STATIC_PMEM = 7;
+
+const int SQLITE_MUTEX_STATIC_APP1 = 8;
+
+const int SQLITE_MUTEX_STATIC_APP2 = 9;
+
+const int SQLITE_MUTEX_STATIC_APP3 = 10;
+
+const int SQLITE_MUTEX_STATIC_VFS1 = 11;
+
+const int SQLITE_MUTEX_STATIC_VFS2 = 12;
+
+const int SQLITE_MUTEX_STATIC_VFS3 = 13;
+
+const int SQLITE_TESTCTRL_FIRST = 5;
+
+const int SQLITE_TESTCTRL_PRNG_SAVE = 5;
+
+const int SQLITE_TESTCTRL_PRNG_RESTORE = 6;
+
+const int SQLITE_TESTCTRL_PRNG_RESET = 7;
+
+const int SQLITE_TESTCTRL_BITVEC_TEST = 8;
+
+const int SQLITE_TESTCTRL_FAULT_INSTALL = 9;
+
+const int SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS = 10;
+
+const int SQLITE_TESTCTRL_PENDING_BYTE = 11;
+
+const int SQLITE_TESTCTRL_ASSERT = 12;
+
+const int SQLITE_TESTCTRL_ALWAYS = 13;
+
+const int SQLITE_TESTCTRL_RESERVE = 14;
+
+const int SQLITE_TESTCTRL_OPTIMIZATIONS = 15;
+
+const int SQLITE_TESTCTRL_ISKEYWORD = 16;
+
+const int SQLITE_TESTCTRL_SCRATCHMALLOC = 17;
+
+const int SQLITE_TESTCTRL_INTERNAL_FUNCTIONS = 17;
+
+const int SQLITE_TESTCTRL_LOCALTIME_FAULT = 18;
+
+const int SQLITE_TESTCTRL_EXPLAIN_STMT = 19;
+
+const int SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD = 19;
+
+const int SQLITE_TESTCTRL_NEVER_CORRUPT = 20;
+
+const int SQLITE_TESTCTRL_VDBE_COVERAGE = 21;
+
+const int SQLITE_TESTCTRL_BYTEORDER = 22;
+
+const int SQLITE_TESTCTRL_ISINIT = 23;
+
+const int SQLITE_TESTCTRL_SORTER_MMAP = 24;
+
+const int SQLITE_TESTCTRL_IMPOSTER = 25;
+
+const int SQLITE_TESTCTRL_PARSER_COVERAGE = 26;
+
+const int SQLITE_TESTCTRL_RESULT_INTREAL = 27;
+
+const int SQLITE_TESTCTRL_PRNG_SEED = 28;
+
+const int SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS = 29;
+
+const int SQLITE_TESTCTRL_LAST = 29;
+
+const int SQLITE_STATUS_MEMORY_USED = 0;
+
+const int SQLITE_STATUS_PAGECACHE_USED = 1;
+
+const int SQLITE_STATUS_PAGECACHE_OVERFLOW = 2;
+
+const int SQLITE_STATUS_SCRATCH_USED = 3;
+
+const int SQLITE_STATUS_SCRATCH_OVERFLOW = 4;
+
+const int SQLITE_STATUS_MALLOC_SIZE = 5;
+
+const int SQLITE_STATUS_PARSER_STACK = 6;
+
+const int SQLITE_STATUS_PAGECACHE_SIZE = 7;
+
+const int SQLITE_STATUS_SCRATCH_SIZE = 8;
+
+const int SQLITE_STATUS_MALLOC_COUNT = 9;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_USED = 0;
+
+const int SQLITE_DBSTATUS_CACHE_USED = 1;
+
+const int SQLITE_DBSTATUS_SCHEMA_USED = 2;
+
+const int SQLITE_DBSTATUS_STMT_USED = 3;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_HIT = 4;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE = 5;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL = 6;
+
+const int SQLITE_DBSTATUS_CACHE_HIT = 7;
+
+const int SQLITE_DBSTATUS_CACHE_MISS = 8;
+
+const int SQLITE_DBSTATUS_CACHE_WRITE = 9;
+
+const int SQLITE_DBSTATUS_DEFERRED_FKS = 10;
+
+const int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11;
+
+const int SQLITE_DBSTATUS_CACHE_SPILL = 12;
+
+const int SQLITE_DBSTATUS_MAX = 12;
+
+const int SQLITE_STMTSTATUS_FULLSCAN_STEP = 1;
+
+const int SQLITE_STMTSTATUS_SORT = 2;
+
+const int SQLITE_STMTSTATUS_AUTOINDEX = 3;
+
+const int SQLITE_STMTSTATUS_VM_STEP = 4;
+
+const int SQLITE_STMTSTATUS_REPREPARE = 5;
+
+const int SQLITE_STMTSTATUS_RUN = 6;
+
+const int SQLITE_STMTSTATUS_MEMUSED = 99;
+
+const int SQLITE_CHECKPOINT_PASSIVE = 0;
+
+const int SQLITE_CHECKPOINT_FULL = 1;
+
+const int SQLITE_CHECKPOINT_RESTART = 2;
+
+const int SQLITE_CHECKPOINT_TRUNCATE = 3;
+
+const int SQLITE_VTAB_CONSTRAINT_SUPPORT = 1;
+
+const int SQLITE_VTAB_INNOCUOUS = 2;
+
+const int SQLITE_VTAB_DIRECTONLY = 3;
+
+const int SQLITE_ROLLBACK = 1;
+
+const int SQLITE_FAIL = 3;
+
+const int SQLITE_REPLACE = 5;
+
+const int SQLITE_SCANSTAT_NLOOP = 0;
+
+const int SQLITE_SCANSTAT_NVISIT = 1;
+
+const int SQLITE_SCANSTAT_EST = 2;
+
+const int SQLITE_SCANSTAT_NAME = 3;
+
+const int SQLITE_SCANSTAT_EXPLAIN = 4;
+
+const int SQLITE_SCANSTAT_SELECTID = 5;
+
+const int SQLITE_SERIALIZE_NOCOPY = 1;
+
+const int SQLITE_DESERIALIZE_FREEONCLOSE = 1;
+
+const int SQLITE_DESERIALIZE_RESIZEABLE = 2;
+
+const int SQLITE_DESERIALIZE_READONLY = 4;
+
+const int NOT_WITHIN = 0;
+
+const int PARTLY_WITHIN = 1;
+
+const int FULLY_WITHIN = 2;
+
+const int FTS5_TOKENIZE_QUERY = 1;
+
+const int FTS5_TOKENIZE_PREFIX = 2;
+
+const int FTS5_TOKENIZE_DOCUMENT = 4;
+
+const int FTS5_TOKENIZE_AUX = 8;
+
+const int FTS5_TOKEN_COLOCATED = 1;
+
+typedef _c_sqlite3_close_v2 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3> arg0,
+);
+
+typedef _dart_sqlite3_close_v2 = int Function(
+  ffi.Pointer<sqlite3> arg0,
+);
+
+typedef _c_sqlite3_open_v2 = ffi.Int32 Function(
+  ffi.Pointer<ffi.Int8> filename,
+  ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
+  ffi.Int32 flags,
+  ffi.Pointer<ffi.Int8> zVfs,
+);
+
+typedef _dart_sqlite3_open_v2 = int Function(
+  ffi.Pointer<ffi.Int8> filename,
+  ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
+  int flags,
+  ffi.Pointer<ffi.Int8> zVfs,
+);
+
+typedef _c_sqlite3_errmsg = ffi.Pointer<ffi.Int8> Function(
+  ffi.Pointer<sqlite3> arg0,
+);
+
+typedef _dart_sqlite3_errmsg = ffi.Pointer<ffi.Int8> Function(
+  ffi.Pointer<sqlite3> arg0,
+);
+
+typedef _c_sqlite3_errstr = ffi.Pointer<ffi.Int8> Function(
+  ffi.Int32 arg0,
+);
+
+typedef _dart_sqlite3_errstr = ffi.Pointer<ffi.Int8> Function(
+  int arg0,
+);
+
+typedef _c_sqlite3_prepare_v2 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3> db,
+  ffi.Pointer<ffi.Int8> zSql,
+  ffi.Int32 nByte,
+  ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+  ffi.Pointer<ffi.Pointer<ffi.Int8>> pzTail,
+);
+
+typedef _dart_sqlite3_prepare_v2 = int Function(
+  ffi.Pointer<sqlite3> db,
+  ffi.Pointer<ffi.Int8> zSql,
+  int nByte,
+  ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+  ffi.Pointer<ffi.Pointer<ffi.Int8>> pzTail,
+);
+
+typedef _c_sqlite3_column_count = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_stmt> pStmt,
+);
+
+typedef _dart_sqlite3_column_count = int Function(
+  ffi.Pointer<sqlite3_stmt> pStmt,
+);
+
+typedef _c_sqlite3_column_name = ffi.Pointer<ffi.Int8> Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  ffi.Int32 N,
+);
+
+typedef _dart_sqlite3_column_name = ffi.Pointer<ffi.Int8> Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  int N,
+);
+
+typedef _c_sqlite3_column_decltype = ffi.Pointer<ffi.Int8> Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  ffi.Int32 arg1,
+);
+
+typedef _dart_sqlite3_column_decltype = ffi.Pointer<ffi.Int8> Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  int arg1,
+);
+
+typedef _c_sqlite3_step = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+);
+
+typedef _dart_sqlite3_step = int Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+);
+
+typedef _c_sqlite3_column_int = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  ffi.Int32 iCol,
+);
+
+typedef _dart_sqlite3_column_int = int Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  int iCol,
+);
+
+typedef _c_sqlite3_column_text = ffi.Pointer<ffi.Uint8> Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  ffi.Int32 iCol,
+);
+
+typedef _dart_sqlite3_column_text = ffi.Pointer<ffi.Uint8> Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  int iCol,
+);
+
+typedef _c_sqlite3_column_type = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  ffi.Int32 iCol,
+);
+
+typedef _dart_sqlite3_column_type = int Function(
+  ffi.Pointer<sqlite3_stmt> arg0,
+  int iCol,
+);
+
+typedef _c_sqlite3_finalize = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_stmt> pStmt,
+);
+
+typedef _dart_sqlite3_finalize = int Function(
+  ffi.Pointer<sqlite3_stmt> pStmt,
+);
+
+typedef _typedefC_1 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+);
+
+typedef _typedefC_2 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Pointer<ffi.Void>,
+  ffi.Int32,
+  ffi.Int64,
+);
+
+typedef _typedefC_3 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Pointer<ffi.Void>,
+  ffi.Int32,
+  ffi.Int64,
+);
+
+typedef _typedefC_4 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int64,
+);
+
+typedef _typedefC_5 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int32,
+);
+
+typedef _typedefC_6 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Pointer<ffi.Int64>,
+);
+
+typedef _typedefC_7 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int32,
+);
+
+typedef _typedefC_8 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int32,
+);
+
+typedef _typedefC_9 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Pointer<ffi.Int32>,
+);
+
+typedef _typedefC_10 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int32,
+  ffi.Pointer<ffi.Void>,
+);
+
+typedef _typedefC_11 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+);
+
+typedef _typedefC_12 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+);
+
+typedef _typedefC_13 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int32,
+  ffi.Int32,
+  ffi.Int32,
+  ffi.Pointer<ffi.Pointer<ffi.Void>>,
+);
+
+typedef _typedefC_14 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int32,
+  ffi.Int32,
+  ffi.Int32,
+);
+
+typedef _typedefC_15 = ffi.Void Function(
+  ffi.Pointer<sqlite3_file>,
+);
+
+typedef _typedefC_16 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int32,
+);
+
+typedef _typedefC_17 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int64,
+  ffi.Int32,
+  ffi.Pointer<ffi.Pointer<ffi.Void>>,
+);
+
+typedef _typedefC_18 = ffi.Int32 Function(
+  ffi.Pointer<sqlite3_file>,
+  ffi.Int64,
+  ffi.Pointer<ffi.Void>,
+);
diff --git a/samples/ffi/sqlite/pubspec.yaml b/samples/ffi/sqlite/pubspec.yaml
index dcc5d40..b70a25a 100644
--- a/samples/ffi/sqlite/pubspec.yaml
+++ b/samples/ffi/sqlite/pubspec.yaml
@@ -1,11 +1,55 @@
 name: sqlite3
+
 version: 0.0.1
+
 description: >-
   Sqlite3 wrapper. Demo for dart:ffi.
+
 author: Daco Harkes <dacoharkes@google.com>, Samir Jindel <sjindel@google.com>
+
 environment:
   sdk: '>=2.1.0 <3.0.0'
+
 dependencies:
   ffi: ^0.1.3
+
 dev_dependencies:
   test: ^1.5.3
+  ffigen: ^0.2.0
+
+ffigen:
+  name: SQLite
+  description: SQLite bindings.
+  output: 'lib/src/third_party/sqlite/sqlite3_bindings_generated.dart'
+  headers:
+    entry-points:
+      - '/usr/include/sqlite3.h'
+    include-directives:
+      - '**sqlite3.h'
+  functions:
+    include:
+      - sqlite3_close_v2
+      - sqlite3_column_count
+      - sqlite3_column_decltype
+      - sqlite3_column_int
+      - sqlite3_column_name
+      - sqlite3_column_text
+      - sqlite3_column_type
+      - sqlite3_errmsg
+      - sqlite3_errstr
+      - sqlite3_finalize
+      - sqlite3_open_v2
+      - sqlite3_prepare_v2
+      - sqlite3_step
+  comments:
+    style: any
+    length: full
+  preamble: |
+    // 2001 September 15
+    //
+    // The author disclaims copyright to this source code.  In place of
+    // a legal notice, here is a blessing:
+    //
+    //    May you do good and not evil.
+    //    May you find forgiveness for yourself and forgive others.
+    //    May you share freely, never taking more than you give.
diff --git a/samples/ffi/sqlite/test/sqlite_test.dart b/samples/ffi/sqlite/test/sqlite_test.dart
index 7bef552..7b36917 100644
--- a/samples/ffi/sqlite/test/sqlite_test.dart
+++ b/samples/ffi/sqlite/test/sqlite_test.dart
@@ -13,6 +13,7 @@
 import '../lib/sqlite.dart';
 
 void main() {
+  assert(Platform.script.hasAbsolutePath); // `pub run test` is broken.
   final dbPath = Platform.script.resolve("test.db").path;
   test("sqlite integration test", () {
     Database d = Database(dbPath);
@@ -166,6 +167,7 @@
     r.close();
     d.close();
   });
+
   test("Utf8 unit test", () {
     final String test = 'Hasta Mañana';
     final medium = Utf8.toUtf8(test);
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 6740112..68ce685 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -54,30 +54,6 @@
 LibTest/collection/ListMixin/*: Skip # Not migrated to NNBD
 LibTest/core/CyclicInitializationError/*: Skip # Not migrated to NNBD
 LibTest/core/int/*: Skip # Not migrated to NNBD
-LibTest/convert/AsciiCodec/*: Skip # Not migrated to NNBD
-LibTest/convert/AsciiDecoder/*: Skip # Not migrated to NNBD
-LibTest/convert/AsciiEncoder/*: Skip # Not migrated to NNBD
-LibTest/convert/Base64Codec/*: Skip # Not migrated to NNBD
-LibTest/convert/Base64Decoder/*: Skip # Not migrated to NNBD
-LibTest/convert/Base64Encoder/*: Skip # Not migrated to NNBD
-LibTest/convert/ByteConversionSink/*: Skip # Not migrated to NNBD
-LibTest/convert/ChunkedConversionSink/*: Skip # Not migrated to NNBD
-LibTest/convert/ClosableStringSink/*: Skip # Not migrated to NNBD
-LibTest/convert/Encoding/*: Skip # Not migrated to NNBD
-LibTest/convert/HtmlEscape/*: Skip # Not migrated to NNBD
-LibTest/convert/HtmlEscapeMode/*: Skip # Not migrated to NNBD
-LibTest/convert/JsonCodec/*: Skip # Not migrated to NNBD
-LibTest/convert/JsonDecoder/*: Skip # Not migrated to NNBD
-LibTest/convert/JsonEncoder/*: Skip # Not migrated to NNBD
-LibTest/convert/JsonUtf8Encoder/*: Skip # Not migrated to NNBD
-LibTest/convert/Latin1Codec/*: Skip # Not migrated to NNBD
-LibTest/convert/Latin1Decoder/*: Skip # Not migrated to NNBD
-LibTest/convert/Latin1Encoder/*: Skip # Not migrated to NNBD
-LibTest/convert/LineSplitter/*: Skip # Not migrated to NNBD
-LibTest/convert/StringConversionSink/*: Skip # Not migrated to NNBD
-LibTest/convert/Utf8Codec/*: Skip # Not migrated to NNBD
-LibTest/convert/Utf8Decoder/*: Skip # Not migrated to NNBD
-LibTest/convert/Utf8Encoder/*: Skip # Not migrated to NNBD
 LibTest/html/CanvasRenderingContext2D/*: Skip # Not migrated to NNBD
 LibTest/html/Document/*: Skip # Not migrated to NNBD
 LibTest/html/Element/*: Skip # Not migrated to NNBD
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 0bd8a83..ced573a 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -13,5 +13,6 @@
 !unittest.tar.gz.sha1
 !update.sh
 !/wasmer
+!/sqlite
 # but ignore a subfolder of tcmalloc (some client ignores /tcmalloc/.gitignore)
 /tcmalloc/gperftools
diff --git a/third_party/sqlite/LICENSE.md b/third_party/sqlite/LICENSE.md
new file mode 100644
index 0000000..f677190
--- /dev/null
+++ b/third_party/sqlite/LICENSE.md
@@ -0,0 +1,9 @@
+The author disclaims copyright to this source code.  In place of
+a legal notice, here is a blessing:
+
+  *   May you do good and not evil.
+  *   May you find forgiveness for yourself and forgive others.
+  *   May you share freely, never taking more than you give.
+
+Files generated from sqlite source files are in
+samples/ffi/sqlite/lib/src/third_party/sqlite.
diff --git a/tools/VERSION b/tools/VERSION
index e7d799b..5d4c061 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 11
+PRERELEASE 12
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/flutter/compile_flutter.sh b/tools/bots/flutter/compile_flutter.sh
index 192e3a1..5f27241 100755
--- a/tools/bots/flutter/compile_flutter.sh
+++ b/tools/bots/flutter/compile_flutter.sh
@@ -8,6 +8,7 @@
 set -e
 
 prepareOnly=false
+leakTest=false
 
 REMAINING_ARGS=()
 while [[ $# -gt 0 ]]; do
@@ -16,6 +17,10 @@
       prepareOnly=true
       shift
       ;;
+    --leakTest|--leak-test|--leak_test)
+      leakTest=true
+      shift
+      ;;
     *)
       REMAINING_ARGS+=("$1")
       shift
@@ -27,6 +32,8 @@
 
 if $prepareOnly; then
   echo "Will prepare only!"
+elif $leakTest; then
+  echo "Will run leak test"
 fi
 
 checkout=$(pwd)
@@ -106,6 +113,11 @@
   echo "Preparations complete!"
   echo "Flutter is now in $tmpdir/flutter and the patched sdk in $tmpdir/flutter_patched_sdk"
   echo "You can run the test with $dart --enable-asserts pkg/frontend_server/test/frontend_server_flutter.dart --flutterDir=$tmpdir/flutter --flutterPlatformDir=$tmpdir/flutter_patched_sdk"
+elif $leakTest; then
+  $dart \
+      --enable-asserts \
+      pkg/front_end/test/flutter_gallery_leak_tester.dart \
+      --path=$tmpdir
 else
   $dart \
       --enable-asserts \
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 556782f..0ae5512 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -3439,6 +3439,32 @@
     },
     {
       "builders": [
+        "frontend-weekly"
+      ],
+      "meta": {
+        "description": "This configuration is used for running slow frontend tests for instance weekly."
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": [
+            "--mode=release",
+            "--arch=x64",
+            "create_sdk"
+          ]
+        },
+        {
+          "name": "run tests",
+          "script": "tools/bots/flutter/compile_flutter.sh",
+          "arguments": [
+            "--leakTest"
+          ]
+        }
+      ]
+    },
+    {
+      "builders": [
         "fuzz-linux"
       ],
       "meta": {
diff --git a/tools/bots/update_blamelists.dart b/tools/bots/update_blamelists.dart
index 3fb3c9d..ff795ff 100644
--- a/tools/bots/update_blamelists.dart
+++ b/tools/bots/update_blamelists.dart
@@ -159,11 +159,7 @@
     ..addOption('results',
         abbr: 'r',
         help: 'path to a file containing the test results (required)')
-    ..addFlag('staging',
-        abbr: 's',
-        help: 'use staging database',
-        defaultsTo: true,
-        negatable: true);
+    ..addFlag('staging', abbr: 's', help: 'use staging database');
   var options = parser.parse(arguments);
   if (options.rest.isNotEmpty ||
       options['results'] == null ||