4
4
// ignore_for_file: avoid_dynamic_calls
5
5
6
6
import 'package:analyzer/dart/ast/ast.dart' ;
7
- import 'package:analyzer/dart/ast/standard_ast_factory.dart' ;
8
7
import 'package:analyzer/dart/ast/token.dart' ;
9
8
import 'package:analyzer/dart/ast/visitor.dart' ;
10
9
import 'package:analyzer/source/line_info.dart' ;
10
+ // ignore: implementation_imports
11
+ import 'package:analyzer/src/clients/dart_style/rewrite_cascade.dart' ;
11
12
12
13
import 'argument_list_visitor.dart' ;
13
14
import 'call_chain_visitor.dart' ;
@@ -1245,74 +1246,6 @@ class SourceVisitor extends ThrowingAstVisitor {
1245
1246
token (node.semicolon);
1246
1247
}
1247
1248
1248
- /// Synthesize a token with [type] to replace the given [operator] .
1249
- ///
1250
- /// Offset, comments, and previous/next links are all preserved.
1251
- static Token _synthesizeToken (TokenType type, Token operator ) =>
1252
- Token (type, operator .offset, operator .precedingComments)
1253
- ..previous = operator .previous
1254
- ..next = operator .next;
1255
-
1256
- static Expression _realTargetOf (Expression expression) {
1257
- if (expression is PropertyAccess ) {
1258
- return expression.realTarget;
1259
- } else if (expression is MethodInvocation ) {
1260
- return expression.realTarget! ;
1261
- } else if (expression is IndexExpression ) {
1262
- return expression.realTarget;
1263
- }
1264
- throw UnimplementedError ('Unhandled ${expression .runtimeType }'
1265
- '($expression )' );
1266
- }
1267
-
1268
- /// Recursively insert [cascadeTarget] (the LHS of the cascade) into the
1269
- /// LHS of the assignment expression that used to be the cascade's RHS.
1270
- static Expression _insertCascadeTargetIntoExpression (
1271
- Expression expression, Expression cascadeTarget) {
1272
- // Base case: We've recursed as deep as possible.
1273
- if (expression == cascadeTarget) return cascadeTarget;
1274
-
1275
- // Otherwise, copy `expression` and recurse into its LHS.
1276
- var expressionTarget = _realTargetOf (expression);
1277
- if (expression is PropertyAccess ) {
1278
- return astFactory.propertyAccess (
1279
- _insertCascadeTargetIntoExpression (expressionTarget, cascadeTarget),
1280
- // If we've reached the end, replace the `..` operator with `.`
1281
- expressionTarget == cascadeTarget
1282
- ? _synthesizeToken (TokenType .PERIOD , expression.operator )
1283
- : expression.operator ,
1284
- expression.propertyName);
1285
- } else if (expression is MethodInvocation ) {
1286
- return astFactory.methodInvocation (
1287
- _insertCascadeTargetIntoExpression (expressionTarget, cascadeTarget),
1288
- // If we've reached the end, replace the `..` operator with `.`
1289
- expressionTarget == cascadeTarget
1290
- ? _synthesizeToken (TokenType .PERIOD , expression.operator ! )
1291
- : expression.operator ,
1292
- expression.methodName,
1293
- expression.typeArguments,
1294
- expression.argumentList);
1295
- } else if (expression is IndexExpression ) {
1296
- var question = expression.question;
1297
-
1298
- // A null-aware cascade treats the `?` in `?..` as part of the token, but
1299
- // for a non-cascade index, it is a separate `?` token.
1300
- if (expression.period? .type == TokenType .QUESTION_PERIOD_PERIOD ) {
1301
- question = _synthesizeToken (TokenType .QUESTION , expression.period! );
1302
- }
1303
-
1304
- return astFactory.indexExpressionForTarget2 (
1305
- target: _insertCascadeTargetIntoExpression (
1306
- expressionTarget, cascadeTarget),
1307
- question: question,
1308
- leftBracket: expression.leftBracket,
1309
- index: expression.index,
1310
- rightBracket: expression.rightBracket);
1311
- }
1312
- throw UnimplementedError ('Unhandled ${expression .runtimeType }'
1313
- '($expression )' );
1314
- }
1315
-
1316
1249
/// Parenthesize the target of the given statement's expression (assumed to
1317
1250
/// be a CascadeExpression) before removing the cascade.
1318
1251
void _fixCascadeByParenthesizingTarget (ExpressionStatement statement) {
@@ -1325,28 +1258,24 @@ class SourceVisitor extends ThrowingAstVisitor {
1325
1258
writePrecedingCommentsAndNewlines (cascade.target.beginToken);
1326
1259
_suppressPrecedingCommentsAndNewLines.add (cascade.target.beginToken);
1327
1260
1328
- var newTarget = astFactory.parenthesizedExpression (
1329
- Token (TokenType .OPEN_PAREN , 0 )
1330
- ..previous = statement.beginToken.previous
1331
- ..next = cascade.target.beginToken,
1332
- cascade.target,
1333
- Token (TokenType .CLOSE_PAREN , 0 )
1334
- ..previous = cascade.target.endToken
1335
- ..next = statement.semicolon);
1336
-
1337
1261
// Finally, we can revisit a clone of this ExpressionStatement to actually
1338
1262
// remove the cascade.
1339
- visit (astFactory.expressionStatement (
1340
- astFactory.cascadeExpression (newTarget, cascade.cascadeSections),
1341
- statement.semicolon));
1263
+ visit (
1264
+ fixCascadeByParenthesizingTarget (
1265
+ expressionStatement: statement,
1266
+ cascadeExpression: cascade,
1267
+ ),
1268
+ );
1342
1269
}
1343
1270
1344
1271
void _removeCascade (ExpressionStatement statement) {
1345
1272
var cascade = statement.expression as CascadeExpression ;
1346
1273
var subexpression = cascade.cascadeSections.single;
1347
1274
builder.nestExpression ();
1348
1275
1349
- if (subexpression is AssignmentExpression ) {
1276
+ if (subexpression is AssignmentExpression ||
1277
+ subexpression is MethodInvocation ||
1278
+ subexpression is PropertyAccess ) {
1350
1279
// CascadeExpression("leftHandSide", "..",
1351
1280
// AssignmentExpression("target", "=", "rightHandSide"))
1352
1281
//
@@ -1356,13 +1285,7 @@ class SourceVisitor extends ThrowingAstVisitor {
1356
1285
// PropertyAccess("leftHandSide", ".", "target"),
1357
1286
// "=",
1358
1287
// "rightHandSide")
1359
- visit (astFactory.assignmentExpression (
1360
- _insertCascadeTargetIntoExpression (
1361
- subexpression.leftHandSide, cascade.target),
1362
- subexpression.operator ,
1363
- subexpression.rightHandSide));
1364
- } else if (subexpression is MethodInvocation ||
1365
- subexpression is PropertyAccess ) {
1288
+ //
1366
1289
// CascadeExpression("leftHandSide", "..",
1367
1290
// MethodInvocation("target", ".", "methodName", ...))
1368
1291
//
@@ -1374,7 +1297,12 @@ class SourceVisitor extends ThrowingAstVisitor {
1374
1297
// "methodName", ...)
1375
1298
//
1376
1299
// And similarly for PropertyAccess expressions.
1377
- visit (_insertCascadeTargetIntoExpression (subexpression, cascade.target));
1300
+ visit (
1301
+ insertCascadeTargetIntoExpression (
1302
+ expression: subexpression,
1303
+ cascadeTarget: cascade.target,
1304
+ ),
1305
+ );
1378
1306
} else {
1379
1307
throw UnsupportedError (
1380
1308
'--fix-single-cascade-statements: subexpression of cascade '
0 commit comments