mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
Migration: Add IndexExpression support to FixBuilder.
Change-Id: I870047d12304c70cfe89e64d4864cc1809b7e4ac Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121408 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
This commit is contained in:
parent
5594981c2a
commit
1e3cbd4344
2 changed files with 273 additions and 0 deletions
|
@ -179,6 +179,34 @@ abstract class FixBuilder extends GeneralizingAstVisitor<DartType> {
|
|||
? writeType
|
||||
: _computeMigratedType(auxiliaryElements.staticElement);
|
||||
return AssignmentTargetInfo(isCompound ? readType : null, writeType);
|
||||
} else if (node is IndexExpression) {
|
||||
var targetType =
|
||||
visitSubexpression(node.target, _typeProvider.objectType);
|
||||
var writeElement = node.staticElement;
|
||||
DartType indexContext;
|
||||
DartType writeType;
|
||||
DartType readType;
|
||||
if (writeElement == null) {
|
||||
indexContext = UnknownInferredType.instance;
|
||||
writeType = _typeProvider.dynamicType;
|
||||
readType = isCompound ? _typeProvider.dynamicType : null;
|
||||
} else {
|
||||
var writerType =
|
||||
_computeMigratedType(writeElement, targetType: targetType)
|
||||
as FunctionType;
|
||||
writeType = writerType.parameters[1].type;
|
||||
if (isCompound) {
|
||||
var readerType = _computeMigratedType(
|
||||
node.auxiliaryElements.staticElement,
|
||||
targetType: targetType) as FunctionType;
|
||||
readType = readerType.returnType;
|
||||
indexContext = readerType.parameters[0].type;
|
||||
} else {
|
||||
indexContext = writerType.parameters[0].type;
|
||||
}
|
||||
}
|
||||
visitSubexpression(node.index, indexContext);
|
||||
return AssignmentTargetInfo(readType, writeType);
|
||||
} else {
|
||||
throw UnimplementedError('TODO(paulberry)');
|
||||
}
|
||||
|
@ -276,6 +304,28 @@ abstract class FixBuilder extends GeneralizingAstVisitor<DartType> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitIndexExpression(IndexExpression node) {
|
||||
var target = node.target;
|
||||
var staticElement = node.staticElement;
|
||||
var index = node.index;
|
||||
var targetType = visitSubexpression(target, _typeProvider.objectType);
|
||||
DartType contextType;
|
||||
DartType returnType;
|
||||
if (staticElement == null) {
|
||||
contextType = _typeProvider.dynamicType;
|
||||
returnType = _typeProvider.dynamicType;
|
||||
} else {
|
||||
var methodType =
|
||||
_computeMigratedType(staticElement, targetType: targetType)
|
||||
as FunctionType;
|
||||
contextType = methodType.parameters[0].type;
|
||||
returnType = methodType.returnType;
|
||||
}
|
||||
visitSubexpression(index, contextType);
|
||||
return returnType;
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitListLiteral(ListLiteral node) {
|
||||
DartType contextType;
|
||||
|
|
|
@ -236,6 +236,158 @@ _f(bool/*?*/ x, bool/*?*/ y) => x != null && (x = y) != null;
|
|||
visitSubexpression(findNode.binary('&&'), 'bool');
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_compound_dynamic() async {
|
||||
await analyze('''
|
||||
_f(dynamic d, int/*?*/ i) => d[i] += 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('d[i]'), 'dynamic', 'dynamic');
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_compound_simple() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String s) => 1;
|
||||
void operator[]=(String s, num n) {}
|
||||
}
|
||||
_f(_C c) => c['foo'] += 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), 'int', 'num');
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_compound_simple_check_lhs() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String s) => 1;
|
||||
void operator[]=(String s, num n) {}
|
||||
}
|
||||
_f(_C/*?*/ c) => c['foo'] += 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), 'int', 'num',
|
||||
nullChecked: {findNode.simple('c[')});
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_compound_simple_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String/*!*/ s) => 1;
|
||||
void operator[]=(String/*?*/ s, num n) {}
|
||||
}
|
||||
_f(_C c, String/*?*/ s) => c[s] += 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), 'int', 'num',
|
||||
nullChecked: {findNode.simple('s]')});
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_compound_substituted() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
void operator[]=(U u, T t) {}
|
||||
}
|
||||
_f(_C<int, String> c) => c['foo'] += 1;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), 'int', 'int');
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_compound_substituted_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
void operator[]=(U/*?*/ u, T t) {}
|
||||
}
|
||||
_f(_C<int, String/*!*/> c, String/*?*/ s) => c[s] += 1;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), 'int', 'int',
|
||||
nullChecked: {findNode.simple('s]')});
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_compound_substituted_no_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
void operator[]=(U u, T t) {}
|
||||
}
|
||||
_f(_C<int, String/*?*/> c, String/*?*/ s) => c[s] += 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), 'int', 'int');
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_dynamic() async {
|
||||
await analyze('''
|
||||
_f(dynamic d, int/*?*/ i) => d[i] = 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('d[i]'), null, 'dynamic');
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_simple() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String s) => 1;
|
||||
void operator[]=(String s, num n) {}
|
||||
}
|
||||
_f(_C c) => c['foo'] = 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), null, 'num');
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_simple_check_lhs() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String s) => 1;
|
||||
void operator[]=(String s, num n) {}
|
||||
}
|
||||
_f(_C/*?*/ c) => c['foo'] = 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), null, 'num',
|
||||
nullChecked: {findNode.simple('c[')});
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_simple_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String/*?*/ s) => 1;
|
||||
void operator[]=(String/*!*/ s, num n) {}
|
||||
}
|
||||
_f(_C c, String/*?*/ s) => c[s] = 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), null, 'num',
|
||||
nullChecked: {findNode.simple('s]')});
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_substituted() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
void operator[]=(U u, T t) {}
|
||||
}
|
||||
_f(_C<int, String> c) => c['foo'] = 1;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), null, 'int');
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_substituted_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
void operator[]=(U/*?*/ u, T t) {}
|
||||
}
|
||||
_f(_C<int, String/*!*/> c, String/*?*/ s) => c[s] = 1;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), null, 'int',
|
||||
nullChecked: {findNode.simple('s]')});
|
||||
}
|
||||
|
||||
test_assignmentTarget_indexExpression_substituted_no_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
void operator[]=(U u, T t) {}
|
||||
}
|
||||
_f(_C<int, String/*?*/> c, String/*?*/ s) => c[s] = 0;
|
||||
''');
|
||||
visitAssignmentTarget(findNode.index('c['), null, 'int');
|
||||
}
|
||||
|
||||
test_assignmentTarget_simpleIdentifier_field_generic() async {
|
||||
await analyze('''
|
||||
abstract class _C<T> {
|
||||
|
@ -645,6 +797,77 @@ _f(int/*?*/ x) {
|
|||
visitStatement(findNode.statement('if'));
|
||||
}
|
||||
|
||||
test_indexExpression_dynamic() async {
|
||||
await analyze('''
|
||||
Object/*!*/ _f(dynamic d, int/*?*/ i) => d[i];
|
||||
''');
|
||||
visitSubexpression(findNode.index('d[i]'), 'dynamic',
|
||||
contextType: objectType);
|
||||
}
|
||||
|
||||
test_indexExpression_simple() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String s) => 1;
|
||||
}
|
||||
_f(_C c) => c['foo'];
|
||||
''');
|
||||
visitSubexpression(findNode.index('c['), 'int');
|
||||
}
|
||||
|
||||
test_indexExpression_simple_check_lhs() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String s) => 1;
|
||||
}
|
||||
_f(_C/*?*/ c) => c['foo'];
|
||||
''');
|
||||
visitSubexpression(findNode.index('c['), 'int',
|
||||
nullChecked: {findNode.simple('c[')});
|
||||
}
|
||||
|
||||
test_indexExpression_simple_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C {
|
||||
int operator[](String/*!*/ s) => 1;
|
||||
}
|
||||
_f(_C c, String/*?*/ s) => c[s];
|
||||
''');
|
||||
visitSubexpression(findNode.index('c['), 'int',
|
||||
nullChecked: {findNode.simple('s]')});
|
||||
}
|
||||
|
||||
test_indexExpression_substituted() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
}
|
||||
_f(_C<int, String> c) => c['foo'];
|
||||
''');
|
||||
visitSubexpression(findNode.index('c['), 'int');
|
||||
}
|
||||
|
||||
test_indexExpression_substituted_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
}
|
||||
_f(_C<int, String/*!*/> c, String/*?*/ s) => c[s];
|
||||
''');
|
||||
visitSubexpression(findNode.index('c['), 'int',
|
||||
nullChecked: {findNode.simple('s]')});
|
||||
}
|
||||
|
||||
test_indexExpression_substituted_no_check_rhs() async {
|
||||
await analyze('''
|
||||
class _C<T, U> {
|
||||
T operator[](U u) => throw 'foo';
|
||||
}
|
||||
_f(_C<int, String/*?*/> c, String/*?*/ s) => c[s];
|
||||
''');
|
||||
visitSubexpression(findNode.index('c['), 'int');
|
||||
}
|
||||
|
||||
test_integerLiteral() async {
|
||||
await analyze('''
|
||||
f() => 1;
|
||||
|
|
Loading…
Reference in a new issue