blob: 81d2486c45934537b5b86845d123828642265077 [file] [log] [blame]
// Copyright (c) 2021, 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/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/clients/dart_style/rewrite_cascade.dart';
import 'package:analyzer/src/test_utilities/find_node.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(RewriteCascadeTest);
});
}
@reflectiveTest
class RewriteCascadeTest {
test_fixCascadeByParenthesizingTarget() {
const pairs = {
'c ? a : b..method();': '(c ? a : b)..method();',
'a ?? b..method();': '(a ?? b)..method();',
'a && b..method();': '(a && b)..method();',
'a || b..method();': '(a || b)..method();',
'a == b..method();': '(a == b)..method();',
'a != b..method();': '(a != b)..method();',
'a < b..method();': '(a < b)..method();',
'a > b..method();': '(a > b)..method();',
'a <= b..method();': '(a <= b)..method();',
'a >= b..method();': '(a >= b)..method();',
'a ^ b..method();': '(a ^ b)..method();',
'a | b..method();': '(a | b)..method();',
'a << b..method();': '(a << b)..method();',
'a >> b..method();': '(a >> b)..method();',
'a + b..method();': '(a + b)..method();',
'a - b..method();': '(a - b)..method();',
'a * b..method();': '(a * b)..method();',
'a / b..method();': '(a / b)..method();',
'a ~/ b..method();': '(a ~/ b)..method();',
'-a..method();': '(-a)..method();',
'!a..method();': '(!a)..method();',
'~a..method();': '(~a)..method();',
'a++..method();': '(a++)..method();',
'a--..method();': '(a--)..method();',
};
void assertSingle({
required String input,
required String expected,
}) {
var statement = _parseStringToFindNode('''
void f() {
$input
}
''').expressionStatement(input);
var result = fixCascadeByParenthesizingTarget(
expressionStatement: statement,
cascadeExpression: statement.expression as CascadeExpression,
);
expect(result.toSource(), expected);
expect(result.semicolon, same(statement.semicolon));
}
for (var entry in pairs.entries) {
assertSingle(
input: entry.key,
expected: entry.value,
);
}
}
test_insertCascadeTargetIntoExpression() {
void assertSingle({
required String input,
required String expected,
}) {
var statement = _parseStringToFindNode('''
void f() {
$input;
}
''').expressionStatement(input);
var cascadeExpression = statement.expression as CascadeExpression;
var result = insertCascadeTargetIntoExpression(
expression: cascadeExpression.cascadeSections.single,
cascadeTarget: cascadeExpression.target,
);
expect(result.toSource(), expected);
}
const pairs = {
'obj..method()': 'obj.method()',
'obj..getter': 'obj.getter',
'obj..setter = 3': 'obj.setter = 3',
'obj..[subscript] = 3': 'obj[subscript] = 3',
'obj?..[subscript] = 3': 'obj?[subscript] = 3',
'obj..index[subscript] = 3': 'obj.index[subscript] = 3',
'obj..index?[subscript] = 3': 'obj.index?[subscript] = 3',
// Nested
'obj..foo().bar().method()': 'obj.foo().bar().method()',
'obj..foo.bar.getter': 'obj.foo.bar.getter',
'obj..foo.bar.setter = 0': 'obj.foo.bar.setter = 0',
};
for (var entry in pairs.entries) {
assertSingle(
input: entry.key,
expected: entry.value,
);
}
}
FindNode _parseStringToFindNode(String content) {
var parseResult = parseString(
content: content,
featureSet: FeatureSet.latestLanguageVersion(),
);
return FindNode(parseResult.content, parseResult.unit);
}
}