// Copyright (c) 2014, 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/utilities.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/source/line_info.dart'; import 'package:analyzer/source/source_range.dart'; import 'package:analyzer/src/dart/ast/utilities.dart'; import 'package:analyzer/src/generated/utilities_collection.dart'; import 'package:analyzer/src/test_utilities/find_node.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../util/feature_sets.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(EnumSetTest); defineReflectiveTests(LineInfoTest); defineReflectiveTests(NodeReplacerTest); defineReflectiveTests(SourceRangeTest); }); } @reflectiveTest class EnumSetTest { void test_it() { var enumSet = EnumSet<_MyEnum>.empty(); // Can set `foo`. enumSet = enumSet.updated(_MyEnum.foo, true); expect(enumSet[_MyEnum.foo], true); expect(enumSet[_MyEnum.bar], false); // Can set `bar`. enumSet = enumSet.updated(_MyEnum.bar, true); expect(enumSet[_MyEnum.foo], true); expect(enumSet[_MyEnum.bar], true); // Can set `foo` again. enumSet = enumSet.updated(_MyEnum.foo, true); expect(enumSet[_MyEnum.foo], true); expect(enumSet[_MyEnum.bar], true); // Can clear `foo`. enumSet = enumSet.updated(_MyEnum.foo, false); expect(enumSet[_MyEnum.foo], false); expect(enumSet[_MyEnum.bar], true); // Can clear `foo` again. enumSet = enumSet.updated(_MyEnum.foo, false); expect(enumSet[_MyEnum.foo], false); expect(enumSet[_MyEnum.bar], true); // Can clear `bar`. enumSet = enumSet.updated(_MyEnum.bar, false); expect(enumSet[_MyEnum.foo], false); expect(enumSet[_MyEnum.bar], false); } } @reflectiveTest class LineInfoTest { void test_creation() { expect(LineInfo([0]), isNotNull); } void test_creation_empty() { expect(() { LineInfo([]); }, throwsArgumentError); } void test_fromContent_n() { var content = 'a\nbb\nccc'; var lineInfo = LineInfo.fromContent(content); expect(lineInfo.lineStarts, [0, 2, 5]); expect(LineInfo.getOffsetForLine(0, content), 0); expect(LineInfo.getOffsetForLine(1, content), 2); expect(LineInfo.getOffsetForLine(2, content), 5); } void test_fromContent_r() { var content = 'a\rbb\rccc'; var lineInfo = LineInfo.fromContent(content); expect(lineInfo.lineStarts, [0, 2, 5]); expect(LineInfo.getOffsetForLine(0, content), 0); expect(LineInfo.getOffsetForLine(1, content), 2); expect(LineInfo.getOffsetForLine(2, content), 5); } void test_fromContent_rn() { var content = 'a\r\nbb\r\nccc'; var lineInfo = LineInfo.fromContent(content); expect(lineInfo.lineStarts, [0, 3, 7]); expect(LineInfo.getOffsetForLine(0, content), 0); expect(LineInfo.getOffsetForLine(1, content), 3); expect(LineInfo.getOffsetForLine(2, content), 7); } void test_getLocation_firstLine() { LineInfo info = LineInfo([0, 12, 34]); var location = info.getLocation(4); expect(location.lineNumber, 1); expect(location.columnNumber, 5); } void test_getLocation_lastLine() { LineInfo info = LineInfo([0, 12, 34]); var location = info.getLocation(36); expect(location.lineNumber, 3); expect(location.columnNumber, 3); } void test_getLocation_middleLine() { LineInfo info = LineInfo([0, 12, 34]); var location = info.getLocation(12); expect(location.lineNumber, 2); expect(location.columnNumber, 1); } void test_getOffsetForLine_outside_range() { var content = 'a\r\nbb\r\nccc'; expect(LineInfo.getOffsetForLine(-1, content), null); expect(LineInfo.getOffsetForLine(3, content), null); expect(LineInfo.getOffsetForLine(4, content), null); } void test_getOffsetOfLine() { LineInfo info = LineInfo([0, 12, 34]); expect(0, info.getOffsetOfLine(0)); expect(12, info.getOffsetOfLine(1)); expect(34, info.getOffsetOfLine(2)); } void test_getOffsetOfLineAfter() { LineInfo info = LineInfo([0, 12, 34]); expect(info.getOffsetOfLineAfter(0), 12); expect(info.getOffsetOfLineAfter(11), 12); expect(info.getOffsetOfLineAfter(12), 34); expect(info.getOffsetOfLineAfter(33), 34); } } @reflectiveTest class NodeReplacerTest { void test_adjacentStrings() { var findNode = _parseStringToFindNode(r''' void f() { 'aaa' 'bbb'; } '''); var adjacentStrings = findNode.adjacentStrings('aaa'); _assertReplaceInList( destination: adjacentStrings, child: adjacentStrings.strings[0], replacement: adjacentStrings.strings[1], ); } void test_annotation() { var findNode = _parseStringToFindNode(r''' @prefix.A.named(args) @prefix.B.named(args) void f() {} '''); _assertReplacementForChildren( destination: findNode.annotation('prefix.A'), source: findNode.annotation('prefix.B'), childAccessors: [ (node) => node.arguments!, (node) => node.constructorName!, (node) => node.name, (node) => node.typeArguments!, ], ); } void test_argumentList() { var findNode = _parseStringToFindNode(r''' void f() { g(0, 1); } '''); var argumentList = findNode.argumentList('(0, 1)'); _assertReplaceInList( destination: argumentList, child: argumentList.arguments[0], replacement: argumentList.arguments[1], ); } void test_asExpression() { var findNode = _parseStringToFindNode(r''' void f() { 0 as int; 1 as int; } '''); _assertReplacementForChildren( destination: findNode.as_('0 as'), source: findNode.as_('1 as'), childAccessors: [(node) => node.expression, (node) => node.type], ); } void test_assertStatement() { var findNode = _parseStringToFindNode(r''' void f() { assert(true, 'first'); assert(true, 'second'); } '''); _assertReplacementForChildren( destination: findNode.assertStatement('first'), source: findNode.assertStatement('second'), childAccessors: [(node) => node.condition, (node) => node.message!], ); } void test_assignmentExpression() { var findNode = _parseStringToFindNode(r''' void f() { a = 0; b = 1; } '''); _assertReplacementForChildren( destination: findNode.assignment('a ='), source: findNode.assignment('b ='), childAccessors: [ (node) => node.leftHandSide, (node) => node.rightHandSide, ], ); } void test_awaitExpression() { var findNode = _parseStringToFindNode(r''' void f() async { await 0; await 1; } '''); _assertReplacementForChildren( destination: findNode.awaitExpression('0'), source: findNode.awaitExpression('1'), childAccessors: [(node) => node.expression], ); } void test_binaryExpression() { var findNode = _parseStringToFindNode(r''' void f() { 0 + 1; 1 + 2; } '''); _assertReplacementForChildren( destination: findNode.binary('0 + 1'), source: findNode.binary('1 + 2'), childAccessors: [(node) => node.leftOperand, (node) => node.rightOperand], ); } void test_block() { var findNode = _parseStringToFindNode(r''' void f() { print(0); print(1); } '''); var block = findNode.block('{'); _assertReplaceInList( destination: block, child: block.statements[0], replacement: block.statements[1], ); } void test_blockFunctionBody() { var findNode = _parseStringToFindNode(r''' void f() { print('fff'); } void g() { print('ggg'); } '''); _assertReplacementForChildren( destination: findNode.blockFunctionBody('fff'), source: findNode.blockFunctionBody('ggg'), childAccessors: [(node) => node.block, (node) => node.block], ); } void test_breakStatement() { var findNode = _parseStringToFindNode(r''' void f() { while (true) { break first; break second; } } '''); _assertReplacementForChildren( destination: findNode.breakStatement('first'), source: findNode.breakStatement('second'), childAccessors: [(node) => node.label!], ); } void test_cascadeExpression() { var findNode = _parseStringToFindNode(r''' void f() { 0..foo..bar; 1..foo; } '''); var cascadeExpression = findNode.cascade('0'); _assertReplaceInList( destination: cascadeExpression, child: cascadeExpression.cascadeSections[0], replacement: cascadeExpression.cascadeSections[1], ); _assertReplacementForChildren( destination: findNode.cascade('0'), source: findNode.cascade('1'), childAccessors: [(node) => node.target], ); } void test_catchClause() { var findNode = _parseStringToFindNode(r''' void f() { try {} on E catch (e, st) {} try {} on E2 catch (e2, st2) {} } '''); _assertReplacementForChildren( destination: findNode.catchClause('(e,'), source: findNode.catchClause('(e2,'), childAccessors: [ (node) => node.exceptionType!, (node) => node.exceptionParameter!, (node) => node.stackTraceParameter!, (node) => node.body, ], ); } void test_classTypeAlias() { var findNode = _parseStringToFindNode(r''' /// Comment A. @myA1 @myA2 class A = A0 with M implements I; /// Comment B. class B = B0 with N implements J; '''); _assertAnnotatedNode(findNode.classTypeAlias('A')); _assertReplacementForChildren( destination: findNode.classTypeAlias('A'), source: findNode.classTypeAlias('B'), childAccessors: [ (node) => node.documentationComment!, (node) => node.superclass, (node) => node.implementsClause!, (node) => node.typeParameters!, (node) => node.withClause, ], ); } void test_comment() { var findNode = _parseStringToFindNode(r''' /// Has [foo] and [bar]. void f() {} '''); var comment = findNode.comment('Has'); _assertReplaceInList( destination: comment, child: comment.references[0], replacement: comment.references[1], ); } void test_commentReference() { var findNode = _parseStringToFindNode(r''' /// Has [foo] and [bar]. void f() {} '''); _assertReplacementForChildren( destination: findNode.commentReference('foo'), source: findNode.commentReference('bar'), childAccessors: [(node) => node.expression], ); } void test_compilationUnit() { var findNode = _parseStringToFindNode(r''' import 'a.dart'; import 'b.dart'; class A {} class B {} '''); var unit = findNode.unit; _assertReplaceInList( destination: unit, child: unit.directives[0], replacement: unit.directives[1], ); _assertReplaceInList( destination: unit, child: unit.declarations[0], replacement: unit.declarations[1], ); } void test_conditionalExpression() { var findNode = _parseStringToFindNode(r''' void f() { true ? 0 : 1; false ? 2 : 3; } '''); _assertReplacementForChildren( destination: findNode.conditionalExpression('true'), source: findNode.conditionalExpression('false'), childAccessors: [ (node) => node.condition, (node) => node.thenExpression, (node) => node.elseExpression, ], ); } void test_constantPattern() { var findNode = _parseStringToFindNode(r''' void f(x) async { if (x case 0) {} if (x case 1) {} } '''); _assertReplacementForChildren( destination: findNode.caseClause('0').guardedPattern.pattern as ConstantPattern, source: findNode.caseClause('1').guardedPattern.pattern as ConstantPattern, childAccessors: [(node) => node.expression], ); } void test_constructorDeclaration() { var findNode = _parseStringToFindNode(r''' class A { @myA1 @myA2 A.named(int a) : b = 0, c = 1; } class B { B.named(int b); } '''); _assertReplacementForChildren( destination: findNode.constructor('A.named'), source: findNode.constructor('B.named'), childAccessors: [(node) => node.body, (node) => node.parameters], ); _assertAnnotatedNode(findNode.constructor('A.named')); } void test_constructorDeclaration_redirectedConstructor() { var findNode = _parseStringToFindNode(r''' class A { factory A() = R; } class B { factory B() = R; } '''); _assertReplacementForChildren( destination: findNode.constructor('factory A'), source: findNode.constructor('factory B'), childAccessors: [(node) => node.redirectedConstructor!], ); } void test_constructorFieldInitializer() { var findNode = _parseStringToFindNode(r''' class A { A() : a = 0, b = 1; } '''); _assertReplacementForChildren( destination: findNode.constructorFieldInitializer('a ='), source: findNode.constructorFieldInitializer('b ='), childAccessors: [(node) => node.fieldName, (node) => node.expression], ); } void test_constructorName() { var findNode = _parseStringToFindNode(r''' void f() { new prefix.A.foo(); new prefix.B.bar(); } '''); _assertReplacementForChildren( destination: findNode.constructorName('A.foo'), source: findNode.constructorName('B.bar'), childAccessors: [(node) => node.type, (node) => node.name!], ); } void test_continueStatement() { var findNode = _parseStringToFindNode(r''' void f() { while (true) { continue first; continue second; } } '''); _assertReplacementForChildren( destination: findNode.continueStatement('first'), source: findNode.continueStatement('second'), childAccessors: [(node) => node.label!], ); } void test_declaredIdentifier() { var findNode = _parseStringToFindNode(r''' void f() { for (int i in []) {} for (double j in []) {} } '''); _assertReplacementForChildren( destination: findNode.declaredIdentifier('i in'), source: findNode.declaredIdentifier('j in'), childAccessors: [(node) => node.type!], ); } void test_defaultFormalParameter() { var findNode = _parseStringToFindNode(r''' void f({int a = 0, double b = 1}) {} '''); _assertReplacementForChildren( destination: findNode.defaultParameter('a ='), source: findNode.defaultParameter('b ='), childAccessors: [(node) => node.parameter, (node) => node.defaultValue!], ); } void test_doStatement() { var findNode = _parseStringToFindNode(r''' void f({int a = 0, double b = 1}) {} '''); _assertReplacementForChildren( destination: findNode.defaultParameter('a ='), source: findNode.defaultParameter('b ='), childAccessors: [(node) => node.parameter, (node) => node.defaultValue!], ); } void test_enumBody_constants() { var findNode = _parseStringToFindNode(r''' enum E1 {one} enum E2 {two} '''); _assertReplaceInList( destination: findNode.enumDeclaration('enum E1').body, child: findNode.enumConstantDeclaration('one'), replacement: findNode.enumConstantDeclaration('two'), ); } void test_enumBody_members() { var findNode = _parseStringToFindNode(r''' enum E1 {one; void foo() {}} enum E2 {two; void bar() {}} '''); _assertReplaceInList( destination: findNode.enumDeclaration('enum E1').body, child: findNode.methodDeclaration('foo'), replacement: findNode.methodDeclaration('bar'), ); } void test_enumConstantDeclaration() { var findNode = _parseStringToFindNode(r''' enum E { @myA1 @myA2 aaa, bbb; } '''); _assertAnnotatedNode(findNode.enumConstantDeclaration('aaa')); } void test_enumDeclaration() { var findNode = _parseStringToFindNode(r''' enum E1 with M1 implements I1 {one, two} enum E2 with M2 implements I2 {one, two} '''); _assertReplacementForChildren( destination: findNode.enumDeclaration('enum E1'), source: findNode.enumDeclaration('enum E2'), childAccessors: [ (node) => node.withClause!, (node) => node.implementsClause!, ], ); } void test_exportDirective() { var findNode = _parseStringToFindNode(r''' @myA1 @myA2 export 'a.dart' hide A show B; export 'b.dart'; '''); var export_a = findNode.export('a.dart'); _assertAnnotatedNode(export_a); _assertReplaceInList( destination: export_a, child: export_a.combinators[0], replacement: export_a.combinators[1], ); _assertReplacementForChildren( destination: findNode.export('a.dart'), source: findNode.export('b.dart'), childAccessors: [(node) => node.uri], ); } void test_expressionFunctionBody() { var findNode = _parseStringToFindNode(r''' void f() => 0; void g() => 1; '''); _assertReplacementForChildren( destination: findNode.expressionFunctionBody('0'), source: findNode.expressionFunctionBody('1'), childAccessors: [(node) => node.expression], ); } void test_expressionStatement() { var findNode = _parseStringToFindNode(r''' void f() { 0; 1; } '''); _assertReplacementForChildren( destination: findNode.expressionStatement('0'), source: findNode.expressionStatement('1'), childAccessors: [(node) => node.expression], ); } void test_extendsClause() { var findNode = _parseStringToFindNode(r''' class A extends A0 {} class B extends B0 {} '''); _assertReplacementForChildren( destination: findNode.extendsClause('A0'), source: findNode.extendsClause('B0'), childAccessors: [(node) => node.superclass], ); } void test_fieldDeclaration() { var findNode = _parseStringToFindNode(r''' class A { @myA1 @myA2 int foo = 0; int bar = 0; } class B extends B0 {} '''); _assertAnnotatedNode(findNode.fieldDeclaration('foo')); _assertReplacementForChildren( destination: findNode.fieldDeclaration('foo'), source: findNode.fieldDeclaration('bar'), childAccessors: [(node) => node.fields], ); } void test_fieldFormalParameter() { var findNode = _parseStringToFindNode(r''' class A { A( @myA1 @myA2 int this.foo(int a), int this.bar(int b), ); } '''); var foo = findNode.fieldFormalParameter('foo'); _assertFormalParameterMetadata(foo); _assertReplacementForChildren( destination: findNode.fieldFormalParameter('foo'), source: findNode.fieldFormalParameter('bar'), childAccessors: [ (node) => node.parameters!, (node) => node.type!, (node) => node.typeParameters!, ], ); } void test_forEachPartsWithDeclaration() { var findNode = _parseStringToFindNode(r''' void f() { for (int a in []) {} for (int b in []) {} } '''); _assertReplacementForChildren( destination: findNode.forEachPartsWithDeclaration('a in'), source: findNode.forEachPartsWithDeclaration('b in'), childAccessors: [(node) => node.loopVariable, (node) => node.iterable], ); } void test_forEachPartsWithIdentifier() { var findNode = _parseStringToFindNode(r''' void f() { for (a in []) {} for (b in []) {} } '''); _assertReplacementForChildren( destination: findNode.forEachPartsWithIdentifier('a in'), source: findNode.forEachPartsWithIdentifier('b in'), childAccessors: [(node) => node.identifier, (node) => node.iterable], ); } void test_forEachPartsWithPattern() { var findNode = _parseStringToFindNode(r''' void f() { for (var (a) in []) {} for (var (b) in []) {} } '''); _assertReplacementForChildren( destination: findNode.forEachPartsWithPattern('(a)'), source: findNode.forEachPartsWithPattern('(b)'), childAccessors: [(node) => node.iterable], ); } void test_forEachStatement_withIdentifier() { var findNode = _parseStringToFindNode(r''' void f(int a) { for (a in []) {} for (b in []) {} } '''); _assertReplacementForChildren( destination: findNode.forStatement('a in'), source: findNode.forStatement('b in'), childAccessors: [(node) => node.body, (node) => node.forLoopParts], ); } void test_formalParameterList() { var findNode = _parseStringToFindNode(r''' void f(int a, int b) {} '''); _assertReplaceInList( destination: findNode.formalParameterList('int a'), child: findNode.simpleFormalParameter('int a'), replacement: findNode.simpleFormalParameter('int b'), ); } void test_forPartsWithDeclarations() { var findNode = _parseStringToFindNode(r''' void f() { for (int i = 0; i < 8; i++, i += 2) {} for (int j = 0; j < 8; j++) {} } '''); var for_i = findNode.forPartsWithDeclarations('i = 0'); _assertReplaceInList( destination: for_i, child: for_i.updaters[0], replacement: for_i.updaters[1], ); _assertReplacementForChildren( destination: for_i, source: findNode.forPartsWithDeclarations('j = 0'), childAccessors: [(node) => node.variables, (node) => node.condition!], ); } void test_forPartsWithExpression() { var findNode = _parseStringToFindNode(r''' void f() { for (i = 0; i < 8; i++, i += 2) {} for (j = 0; j < 8; j++) {} } '''); var for_i = findNode.forPartsWithExpression('i = 0'); _assertReplaceInList( destination: for_i, child: for_i.updaters[0], replacement: for_i.updaters[1], ); _assertReplacementForChildren( destination: for_i, source: findNode.forPartsWithExpression('j = 0'), childAccessors: [ (node) => node.initialization!, (node) => node.condition!, ], ); } void test_functionDeclaration() { var findNode = _parseStringToFindNode(r''' @myA1 @myA2 int f() => 0; double g() => 0; '''); _assertAnnotatedNode(findNode.functionDeclaration('f()')); _assertReplacementForChildren( destination: findNode.functionDeclaration('f()'), source: findNode.functionDeclaration('g()'), childAccessors: [ (node) => node.functionExpression, (node) => node.returnType!, ], ); } void test_functionDeclarationStatement() { var findNode = _parseStringToFindNode(r''' void f() { void g() {} void h() {} } '''); _assertReplacementForChildren( destination: findNode.functionDeclarationStatement('g()'), source: findNode.functionDeclarationStatement('h()'), childAccessors: [(node) => node.functionDeclaration], ); } void test_functionExpression() { var findNode = _parseStringToFindNode(r''' void f(int a) { 0; } void g(double b) { 1; } '''); _assertReplacementForChildren( destination: findNode.functionExpression('T>'), source: findNode.functionExpression('U>'), childAccessors: [ (node) => node.body, (node) => node.parameters!, (node) => node.typeParameters!, ], ); } void test_functionExpressionInvocation() { var findNode = _parseStringToFindNode(r''' void f() { (g)(0); (h)(1); } '''); _assertReplacementForChildren( destination: findNode.functionExpressionInvocation(''), source: findNode.functionExpressionInvocation(''), childAccessors: [ (node) => node.function, (node) => node.typeArguments!, (node) => node.argumentList, ], ); } void test_functionTypeAlias() { var findNode = _parseStringToFindNode(r''' @myA1 @myA2 typedef int F(int a); typedef double G(double b); '''); _assertAnnotatedNode(findNode.functionTypeAlias('int F')); _assertReplacementForChildren( destination: findNode.functionTypeAlias('int F'), source: findNode.functionTypeAlias('double G'), childAccessors: [ (node) => node.parameters, (node) => node.returnType!, (node) => node.typeParameters!, ], ); } void test_functionTypedFormalParameter() { var findNode = _parseStringToFindNode(r''' void f( @myA1 @myA2 int a(int a1), double b(double b2), ) {} '''); var a = findNode.functionTypedFormalParameter('a'); _assertFormalParameterMetadata(a); _assertReplacementForChildren( destination: findNode.functionTypedFormalParameter('a'), source: findNode.functionTypedFormalParameter('b'), childAccessors: [ (node) => node.returnType!, (node) => node.typeParameters!, (node) => node.parameters, ], ); } void test_hideCombinator() { var findNode = _parseStringToFindNode(r''' import '' hide A, B; '''); var node = findNode.hideCombinator('hide'); _assertReplaceInList( destination: node, child: node.hiddenNames[0], replacement: node.hiddenNames[1], ); } void test_ifStatement() { var findNode = _parseStringToFindNode(r''' void f() { if (true) { 0; } else { 1; } if (false) { 2; } else { 3; } } '''); _assertReplacementForChildren( destination: findNode.ifStatement('true'), source: findNode.ifStatement('false'), childAccessors: [ (node) => node.expression, (node) => node.thenStatement, (node) => node.elseStatement!, ], ); } void test_implementsClause() { var findNode = _parseStringToFindNode(r''' class A implements I, J {} '''); var node = findNode.implementsClause('implements'); _assertReplaceInList( destination: node, child: node.interfaces[0], replacement: node.interfaces[1], ); } void test_importDirective() { var findNode = _parseStringToFindNode(r''' @myA1 @myA2 import 'a.dart' hide A show B; import 'b.dart'; '''); var import_a = findNode.import('a.dart'); _assertAnnotatedNode(import_a); _assertReplaceInList( destination: import_a, child: import_a.combinators[0], replacement: import_a.combinators[1], ); _assertReplacementForChildren( destination: findNode.import('a.dart'), source: findNode.import('b.dart'), childAccessors: [(node) => node.uri], ); } void test_indexExpression() { var findNode = _parseStringToFindNode(r''' void f() { a[0]; b[1]; } '''); _assertReplacementForChildren( destination: findNode.index('[0]'), source: findNode.index('[1]'), childAccessors: [(node) => node.target!, (node) => node.index], ); } void test_instanceCreationExpression() { var findNode = _parseStringToFindNode(r''' void f() { new A(0); new B(1); } '''); _assertReplacementForChildren( destination: findNode.instanceCreation('A('), source: findNode.instanceCreation('B('), childAccessors: [ (node) => node.constructorName, (node) => node.argumentList, ], ); } void test_interpolationExpression() { var findNode = _parseStringToFindNode(r''' void f() { '$foo $bar'; } '''); _assertReplacementForChildren( destination: findNode.interpolationExpression('foo'), source: findNode.interpolationExpression('bar'), childAccessors: [(node) => node.expression], ); } void test_isExpression() { var findNode = _parseStringToFindNode(r''' void f() { 0 is int; 1 is double; } '''); _assertReplacementForChildren( destination: findNode.isExpression('0 is'), source: findNode.isExpression('1 is'), childAccessors: [(node) => node.expression, (node) => node.type], ); } void test_label() { var findNode = _parseStringToFindNode(r''' void f() { foo: while (true) {} bar: while (true) {} } '''); _assertReplacementForChildren