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 =, <, <=, >, or >=.)^ ^(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 ||