blob: 4a95d534dd92263bdb984a41ab7ba69cde0298fe [file] [log] [blame]
// Copyright (c) 2018, 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 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(IndexExpressionTest);
defineReflectiveTests(IndexExpressionWithNnbdTest);
});
}
@reflectiveTest
class IndexExpressionTest extends DriverResolutionTest {
test_read() async {
await assertNoErrorsInCode(r'''
class A {
bool operator[](int index) => false;
}
main(A a) {
a[0];
}
''');
var indexElement = findElement.method('[]');
var indexExpression = findNode.index('a[0]');
assertElement(indexExpression, indexElement);
assertAuxElement(indexExpression, null);
assertParameterElement(
indexExpression.index,
indexElement.parameters[0],
);
assertType(indexExpression, 'bool');
}
test_read_generic() async {
await assertNoErrorsInCode(r'''
class A<T> {
T operator[](int index) => null;
}
main(A<double> a) {
a[0];
}
''');
var indexElement = findElement.method('[]');
var indexExpression = findNode.index('a[0]');
assertMember(indexExpression, indexElement, {'T': 'double'});
assertAuxElement(indexExpression, null);
assertParameterElement(
indexExpression.index,
indexElement.parameters[0],
);
assertType(indexExpression, 'double');
}
test_readWrite() async {
await assertNoErrorsInCode(r'''
class A {
num operator[](int index) => 0;
void operator[]=(int index, num value) {}
}
main(A a) {
a[0] += 1.2;
}
''');
var indexElement = findElement.method('[]');
var indexEqElement = findElement.method('[]=');
var numPlusElement = numElement.getMethod('+');
var indexExpression = findNode.index('a[0]');
assertElement(indexExpression, indexEqElement);
assertAuxElement(indexExpression, indexElement);
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
assertType(indexExpression, 'num');
var assignment = indexExpression.parent as AssignmentExpression;
assertElement(assignment, numPlusElement);
assertType(assignment, 'num');
assertParameterElement(
assignment.rightHandSide,
numPlusElement.parameters[0],
);
}
test_readWrite_generic() async {
await assertNoErrorsInCode(r'''
class A<T> {
T operator[](int index) => null;
void operator[]=(int index, T value) {}
}
main(A<double> a) {
a[0] += 1.2;
}
''');
var indexElement = findElement.method('[]');
var indexEqElement = findElement.method('[]=');
var doublePlusElement = doubleElement.getMethod('+');
var indexExpression = findNode.index('a[0]');
assertMember(indexExpression, indexEqElement, {'T': 'double'});
assertAuxMember(indexExpression, indexElement, {'T': 'double'});
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
assertType(indexExpression, 'double');
var assignment = indexExpression.parent as AssignmentExpression;
assertElement(assignment, doublePlusElement);
assertType(assignment, 'double');
assertParameterElement(
assignment.rightHandSide,
doublePlusElement.parameters[0],
);
}
test_write() async {
await assertNoErrorsInCode(r'''
class A {
void operator[]=(int index, num value) {}
}
main(A a) {
a[0] = 1.2;
}
''');
var indexEqElement = findElement.method('[]=');
var indexExpression = findNode.index('a[0]');
assertElement(indexExpression, indexEqElement);
assertAuxElement(indexExpression, null);
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
assertType(indexExpression, 'num');
var assignment = indexExpression.parent as AssignmentExpression;
assertElement(assignment, null);
assertType(assignment, 'double');
assertParameterElement(assignment.rightHandSide, null);
}
test_write_generic() async {
await assertNoErrorsInCode(r'''
class A<T> {
void operator[]=(int index, T value) {}
}
main(A<double> a) {
a[0] = 1.2;
}
''');
var indexEqElement = findElement.method('[]=');
var indexExpression = findNode.index('a[0]');
assertMember(indexExpression, indexEqElement, {'T': 'double'});
assertAuxElement(indexExpression, null);
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
assertType(indexExpression, 'double');
var assignment = indexExpression.parent as AssignmentExpression;
assertElement(assignment, null);
assertType(assignment, 'double');
assertParameterElement(assignment.rightHandSide, null);
}
}
@reflectiveTest
class IndexExpressionWithNnbdTest extends IndexExpressionTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
..contextFeatures = FeatureSet.forTesting(
sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
@override
bool get typeToStringWithNullability => true;
test_read_nullable() async {
await assertNoErrorsInCode(r'''
class A {
bool operator[](int index) => false;
}
main(A? a) {
a?.[0];
}
''');
var indexElement = findElement.method('[]');
var indexExpression = findNode.index('a?.[0]');
assertElement(indexExpression, indexElement);
assertAuxElement(indexExpression, null);
assertType(indexExpression, 'bool?');
}
test_readWrite_nullable() async {
await assertNoErrorsInCode(r'''
class A {
num operator[](int index) => 0;
void operator[]=(int index, num value) {}
}
main(A? a) {
a?.[0] += 1.2;
}
''');
var indexElement = findElement.method('[]');
var indexEqElement = findElement.method('[]=');
var numPlusElement = numElement.getMethod('+');
var indexExpression = findNode.index('a?.[0]');
assertElement(indexExpression, indexEqElement);
assertAuxElement(indexExpression, indexElement);
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
assertType(indexExpression, 'num');
var assignment = indexExpression.parent as AssignmentExpression;
assertElement(assignment, numPlusElement);
assertType(assignment, 'num?');
assertParameterElement(
assignment.rightHandSide,
numPlusElement.parameters[0],
);
}
test_write_nullable() async {
await assertNoErrorsInCode(r'''
class A {
void operator[]=(int index, num value) {}
}
main(A? a) {
a?.[0] = 1.2;
}
''');
var indexEqElement = findElement.method('[]=');
var indexExpression = findNode.index('a?.[0]');
assertElement(indexExpression, indexEqElement);
assertAuxElement(indexExpression, null);
assertParameterElement(
indexExpression.index,
indexEqElement.parameters[0],
);
assertType(indexExpression, 'num');
var assignment = indexExpression.parent as AssignmentExpression;
assertElement(assignment, null);
assertType(assignment, 'double?');
assertParameterElement(assignment.rightHandSide, null);
}
}