OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 | 6 |
7 import 'package:analysis_server/plugin/protocol/protocol.dart'; | 7 import 'package:analysis_server/plugin/protocol/protocol.dart'; |
8 import 'package:analysis_server/src/provisional/edit/utilities/change_builder_co
re.dart'; | 8 import 'package:analysis_server/src/provisional/edit/utilities/change_builder_co
re.dart'; |
9 import 'package:analysis_server/src/provisional/edit/utilities/change_builder_da
rt.dart'; | 9 import 'package:analysis_server/src/provisional/edit/utilities/change_builder_da
rt.dart'; |
10 import 'package:analysis_server/src/utilities/change_builder_dart.dart'; | 10 import 'package:analysis_server/src/utilities/change_builder_dart.dart'; |
11 import 'package:analyzer/dart/ast/ast.dart'; | 11 import 'package:analyzer/dart/ast/ast.dart'; |
12 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 12 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
13 import 'package:analyzer/dart/element/element.dart'; | 13 import 'package:analyzer/dart/element/element.dart'; |
14 import 'package:analyzer/dart/element/type.dart'; | 14 import 'package:analyzer/dart/element/type.dart'; |
| 15 import 'package:analyzer/src/context/source.dart'; |
15 import 'package:analyzer/src/dart/analysis/driver.dart'; | 16 import 'package:analyzer/src/dart/analysis/driver.dart'; |
| 17 import 'package:analyzer/src/generated/engine.dart'; |
| 18 import 'package:analyzer/src/generated/resolver.dart'; |
| 19 import 'package:analyzer/src/generated/source.dart'; |
| 20 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; |
16 import 'package:test/test.dart'; | 21 import 'package:test/test.dart'; |
17 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 22 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
18 | 23 |
19 import '../../abstract_context.dart'; | 24 import '../../abstract_context.dart'; |
20 | 25 |
21 main() { | 26 main() { |
22 defineReflectiveSuite(() { | 27 defineReflectiveSuite(() { |
23 defineReflectiveTests(DartChangeBuilderImplTest); | 28 defineReflectiveTests(DartChangeBuilderImplTest); |
24 defineReflectiveTests(DartEditBuilderImplTest); | 29 defineReflectiveTests(DartEditBuilderImplTest); |
25 defineReflectiveTests(DartFileEditBuilderImplTest); | 30 defineReflectiveTests(DartFileEditBuilderImplTest); |
| 31 defineReflectiveTests(DartLinkedEditBuilderImplTest); |
26 }); | 32 }); |
27 } | 33 } |
28 | 34 |
| 35 abstract class BuilderTestMixin { |
| 36 SourceEdit getEdit(DartChangeBuilderImpl builder) { |
| 37 SourceChange sourceChange = builder.sourceChange; |
| 38 expect(sourceChange, isNotNull); |
| 39 List<SourceFileEdit> fileEdits = sourceChange.edits; |
| 40 expect(fileEdits, hasLength(1)); |
| 41 SourceFileEdit fileEdit = fileEdits[0]; |
| 42 expect(fileEdit, isNotNull); |
| 43 List<SourceEdit> edits = fileEdit.edits; |
| 44 expect(edits, hasLength(1)); |
| 45 return edits[0]; |
| 46 } |
| 47 |
| 48 List<SourceEdit> getEdits(DartChangeBuilderImpl builder) { |
| 49 SourceChange sourceChange = builder.sourceChange; |
| 50 expect(sourceChange, isNotNull); |
| 51 List<SourceFileEdit> fileEdits = sourceChange.edits; |
| 52 expect(fileEdits, hasLength(1)); |
| 53 SourceFileEdit fileEdit = fileEdits[0]; |
| 54 expect(fileEdit, isNotNull); |
| 55 return fileEdit.edits; |
| 56 } |
| 57 } |
| 58 |
29 @reflectiveTest | 59 @reflectiveTest |
30 class DartChangeBuilderImplTest extends AbstractContextTest { | 60 class DartChangeBuilderImplTest extends AbstractContextTest { |
31 @override | 61 @override |
32 bool get enableNewAnalysisDriver => true; | 62 bool get enableNewAnalysisDriver => true; |
33 | 63 |
34 test_createFileEditBuilder() async { | 64 test_createFileEditBuilder() async { |
35 String path = '/test.dart'; | 65 String path = '/test.dart'; |
36 addSource(path, 'library test;'); | 66 addSource(path, 'library test;'); |
37 int timeStamp = 54; | 67 int timeStamp = 54; |
38 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 68 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
39 DartFileEditBuilderImpl fileEditBuilder = | 69 DartFileEditBuilderImpl fileEditBuilder = |
40 await builder.createFileEditBuilder(path, timeStamp); | 70 await builder.createFileEditBuilder(path, timeStamp); |
41 expect(fileEditBuilder, new isInstanceOf<DartFileEditBuilder>()); | 71 expect(fileEditBuilder, new isInstanceOf<DartFileEditBuilder>()); |
42 SourceFileEdit fileEdit = fileEditBuilder.fileEdit; | 72 SourceFileEdit fileEdit = fileEditBuilder.fileEdit; |
43 expect(fileEdit.file, path); | 73 expect(fileEdit.file, path); |
44 expect(fileEdit.fileStamp, timeStamp); | 74 expect(fileEdit.fileStamp, timeStamp); |
45 } | 75 } |
46 } | 76 } |
47 | 77 |
48 @reflectiveTest | 78 @reflectiveTest |
49 class DartEditBuilderImplTest extends AbstractContextTest { | 79 class DartEditBuilderImplTest extends AbstractContextTest |
| 80 with BuilderTestMixin { |
50 @override | 81 @override |
51 bool get enableNewAnalysisDriver => true; | 82 bool get enableNewAnalysisDriver => true; |
52 | 83 |
53 SourceEdit getEdit(DartChangeBuilderImpl builder) { | |
54 SourceChange sourceChange = builder.sourceChange; | |
55 expect(sourceChange, isNotNull); | |
56 List<SourceFileEdit> fileEdits = sourceChange.edits; | |
57 expect(fileEdits, hasLength(1)); | |
58 SourceFileEdit fileEdit = fileEdits[0]; | |
59 expect(fileEdit, isNotNull); | |
60 List<SourceEdit> edits = fileEdit.edits; | |
61 expect(edits, hasLength(1)); | |
62 return edits[0]; | |
63 } | |
64 | |
65 test_writeClassDeclaration_interfaces() async { | 84 test_writeClassDeclaration_interfaces() async { |
66 String path = '/test.dart'; | 85 String path = '/test.dart'; |
67 addSource(path, 'class A {}'); | 86 addSource(path, 'class A {}'); |
68 DartType typeA = await _getType(path, 'A'); | 87 DartType typeA = await _getType(path, 'A'); |
69 | 88 |
70 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 89 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
71 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 90 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
72 builder.addInsertion(0, (EditBuilder builder) { | 91 builder.addInsertion(0, (EditBuilder builder) { |
73 (builder as DartEditBuilder) | 92 (builder as DartEditBuilder) |
74 .writeClassDeclaration('C', interfaces: [typeA]); | 93 .writeClassDeclaration('C', interfaces: [typeA]); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 188 } |
170 | 189 |
171 test_writeClassDeclaration_superclass() async { | 190 test_writeClassDeclaration_superclass() async { |
172 String path = '/test.dart'; | 191 String path = '/test.dart'; |
173 addSource(path, 'class B {}'); | 192 addSource(path, 'class B {}'); |
174 DartType typeB = await _getType(path, 'B'); | 193 DartType typeB = await _getType(path, 'B'); |
175 | 194 |
176 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 195 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
177 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 196 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
178 builder.addInsertion(0, (EditBuilder builder) { | 197 builder.addInsertion(0, (EditBuilder builder) { |
179 (builder as DartEditBuilder) | 198 (builder as DartEditBuilder).writeClassDeclaration('C', |
180 .writeClassDeclaration('C', superclass: typeB); | 199 superclass: typeB, superclassGroupName: 'superclass'); |
181 }); | 200 }); |
182 }); | 201 }); |
183 SourceEdit edit = getEdit(builder); | 202 SourceEdit edit = getEdit(builder); |
184 expect(edit.replacement, equalsIgnoringWhitespace('class C extends B { }')); | 203 expect(edit.replacement, equalsIgnoringWhitespace('class C extends B { }')); |
| 204 |
| 205 List<LinkedEditGroup> linkedEditGroups = |
| 206 builder.sourceChange.linkedEditGroups; |
| 207 expect(linkedEditGroups, hasLength(1)); |
| 208 LinkedEditGroup group = linkedEditGroups[0]; |
| 209 expect(group.length, 1); |
| 210 expect(group.positions, hasLength(1)); |
185 } | 211 } |
186 | 212 |
187 test_writeFieldDeclaration_initializerWriter() async { | 213 test_writeFieldDeclaration_initializerWriter() async { |
188 String path = '/test.dart'; | 214 String path = '/test.dart'; |
189 String content = 'class A {}'; | 215 String content = 'class A {}'; |
190 addSource(path, content); | 216 addSource(path, content); |
191 | 217 |
192 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 218 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
193 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 219 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
194 builder.addInsertion(content.length - 1, (EditBuilder builder) { | 220 builder.addInsertion(content.length - 1, (EditBuilder builder) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 List<LinkedEditGroup> linkedEditGroups = | 333 List<LinkedEditGroup> linkedEditGroups = |
308 builder.sourceChange.linkedEditGroups; | 334 builder.sourceChange.linkedEditGroups; |
309 expect(linkedEditGroups, hasLength(1)); | 335 expect(linkedEditGroups, hasLength(1)); |
310 LinkedEditGroup group = linkedEditGroups[0]; | 336 LinkedEditGroup group = linkedEditGroups[0]; |
311 expect(group.length, 1); | 337 expect(group.length, 1); |
312 expect(group.positions, hasLength(1)); | 338 expect(group.positions, hasLength(1)); |
313 Position position = group.positions[0]; | 339 Position position = group.positions[0]; |
314 expect(position.offset, equals(20)); | 340 expect(position.offset, equals(20)); |
315 } | 341 } |
316 | 342 |
| 343 test_writeFunctionDeclaration_noReturnType_noParams_body() async { |
| 344 String path = '/test.dart'; |
| 345 String content = ''; |
| 346 addSource(path, content); |
| 347 |
| 348 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 349 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 350 builder.addInsertion(0, (EditBuilder builder) { |
| 351 (builder as DartEditBuilder).writeFunctionDeclaration('fib', |
| 352 bodyWriter: () { |
| 353 builder.write('{ ... }'); |
| 354 }); |
| 355 }); |
| 356 }); |
| 357 SourceEdit edit = getEdit(builder); |
| 358 expect(edit.replacement, equalsIgnoringWhitespace('fib() { ... }')); |
| 359 } |
| 360 |
| 361 test_writeFunctionDeclaration_noReturnType_noParams_noBody() async { |
| 362 String path = '/test.dart'; |
| 363 String content = ''; |
| 364 addSource(path, content); |
| 365 |
| 366 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 367 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 368 builder.addInsertion(0, (EditBuilder builder) { |
| 369 (builder as DartEditBuilder) |
| 370 .writeFunctionDeclaration('fib', nameGroupName: 'name'); |
| 371 }); |
| 372 }); |
| 373 SourceEdit edit = getEdit(builder); |
| 374 expect(edit.replacement, equalsIgnoringWhitespace('fib() {}')); |
| 375 |
| 376 List<LinkedEditGroup> linkedEditGroups = |
| 377 builder.sourceChange.linkedEditGroups; |
| 378 expect(linkedEditGroups, hasLength(1)); |
| 379 LinkedEditGroup group = linkedEditGroups[0]; |
| 380 expect(group.length, 3); |
| 381 expect(group.positions, hasLength(1)); |
| 382 } |
| 383 |
| 384 test_writeFunctionDeclaration_noReturnType_params_noBody() async { |
| 385 String path = '/test.dart'; |
| 386 String content = ''; |
| 387 addSource(path, content); |
| 388 |
| 389 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 390 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 391 builder.addInsertion(0, (EditBuilder builder) { |
| 392 (builder as DartEditBuilder).writeFunctionDeclaration('fib', |
| 393 parameterWriter: () { |
| 394 builder.write('p, q, r'); |
| 395 }); |
| 396 }); |
| 397 }); |
| 398 SourceEdit edit = getEdit(builder); |
| 399 expect(edit.replacement, equalsIgnoringWhitespace('fib(p, q, r) {}')); |
| 400 } |
| 401 |
| 402 test_writeFunctionDeclaration_returnType_noParams_noBody() async { |
| 403 String path = '/test.dart'; |
| 404 String content = 'class A {}'; |
| 405 addSource(path, content); |
| 406 |
| 407 DartType typeA = await _getType(path, 'A'); |
| 408 |
| 409 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 410 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 411 builder.addInsertion(0, (EditBuilder builder) { |
| 412 (builder as DartEditBuilder).writeFunctionDeclaration('fib', |
| 413 returnType: typeA, returnTypeGroupName: 'type'); |
| 414 }); |
| 415 }); |
| 416 SourceEdit edit = getEdit(builder); |
| 417 expect(edit.replacement, equalsIgnoringWhitespace('A fib() => null;')); |
| 418 |
| 419 List<LinkedEditGroup> linkedEditGroups = |
| 420 builder.sourceChange.linkedEditGroups; |
| 421 expect(linkedEditGroups, hasLength(1)); |
| 422 LinkedEditGroup group = linkedEditGroups[0]; |
| 423 expect(group.length, 1); |
| 424 expect(group.positions, hasLength(1)); |
| 425 } |
| 426 |
317 test_writeGetterDeclaration_bodyWriter() async { | 427 test_writeGetterDeclaration_bodyWriter() async { |
318 String path = '/test.dart'; | 428 String path = '/test.dart'; |
319 String content = 'class A {}'; | 429 String content = 'class A {}'; |
320 addSource(path, content); | 430 addSource(path, content); |
321 | 431 |
322 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 432 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
323 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 433 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
324 builder.addInsertion(content.length - 1, (EditBuilder builder) { | 434 builder.addInsertion(content.length - 1, (EditBuilder builder) { |
325 (builder as DartEditBuilder).writeGetterDeclaration('g', | 435 (builder as DartEditBuilder).writeGetterDeclaration('g', |
326 bodyWriter: () { | 436 bodyWriter: () { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 List<LinkedEditGroup> linkedEditGroups = | 502 List<LinkedEditGroup> linkedEditGroups = |
393 builder.sourceChange.linkedEditGroups; | 503 builder.sourceChange.linkedEditGroups; |
394 expect(linkedEditGroups, hasLength(1)); | 504 expect(linkedEditGroups, hasLength(1)); |
395 LinkedEditGroup group = linkedEditGroups[0]; | 505 LinkedEditGroup group = linkedEditGroups[0]; |
396 expect(group.length, 1); | 506 expect(group.length, 1); |
397 expect(group.positions, hasLength(1)); | 507 expect(group.positions, hasLength(1)); |
398 Position position = group.positions[0]; | 508 Position position = group.positions[0]; |
399 expect(position.offset, equals(20)); | 509 expect(position.offset, equals(20)); |
400 } | 510 } |
401 | 511 |
| 512 test_writeLocalVariableDeclaration_noType_initializer() async { |
| 513 String path = '/test.dart'; |
| 514 String content = ''' |
| 515 void f() { |
| 516 |
| 517 }'''; |
| 518 addSource(path, content); |
| 519 await driver.getResult(path); |
| 520 |
| 521 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 522 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 523 builder.addInsertion(11, (EditBuilder builder) { |
| 524 (builder as DartEditBuilder).writeLocalVariableDeclaration('foo', |
| 525 initializerWriter: () { |
| 526 builder.write('null'); |
| 527 }); |
| 528 }); |
| 529 }); |
| 530 SourceEdit edit = getEdit(builder); |
| 531 expect(edit.replacement, equalsIgnoringWhitespace('var foo = null;')); |
| 532 } |
| 533 |
| 534 test_writeLocalVariableDeclaration_noType_noInitializer() async { |
| 535 String path = '/test.dart'; |
| 536 String content = ''' |
| 537 void f() { |
| 538 |
| 539 }'''; |
| 540 addSource(path, content); |
| 541 await driver.getResult(path); |
| 542 |
| 543 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 544 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 545 builder.addInsertion(11, (EditBuilder builder) { |
| 546 (builder as DartEditBuilder) |
| 547 .writeLocalVariableDeclaration('foo', nameGroupName: 'name'); |
| 548 }); |
| 549 }); |
| 550 SourceEdit edit = getEdit(builder); |
| 551 expect(edit.replacement, equalsIgnoringWhitespace('var foo;')); |
| 552 |
| 553 List<LinkedEditGroup> linkedEditGroups = |
| 554 builder.sourceChange.linkedEditGroups; |
| 555 expect(linkedEditGroups, hasLength(1)); |
| 556 LinkedEditGroup group = linkedEditGroups[0]; |
| 557 expect(group.length, 3); |
| 558 expect(group.positions, hasLength(1)); |
| 559 } |
| 560 |
| 561 test_writeLocalVariableDeclaration_noType_noInitializer_const() async { |
| 562 String path = '/test.dart'; |
| 563 String content = ''' |
| 564 void f() { |
| 565 |
| 566 }'''; |
| 567 addSource(path, content); |
| 568 await driver.getResult(path); |
| 569 |
| 570 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 571 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 572 builder.addInsertion(11, (EditBuilder builder) { |
| 573 (builder as DartEditBuilder) |
| 574 .writeLocalVariableDeclaration('foo', isConst: true); |
| 575 }); |
| 576 }); |
| 577 SourceEdit edit = getEdit(builder); |
| 578 expect(edit.replacement, equalsIgnoringWhitespace('const foo;')); |
| 579 } |
| 580 |
| 581 test_writeLocalVariableDeclaration_noType_noInitializer_final() async { |
| 582 String path = '/test.dart'; |
| 583 String content = ''' |
| 584 void f() { |
| 585 |
| 586 }'''; |
| 587 addSource(path, content); |
| 588 await driver.getResult(path); |
| 589 |
| 590 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 591 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 592 builder.addInsertion(11, (EditBuilder builder) { |
| 593 (builder as DartEditBuilder) |
| 594 .writeLocalVariableDeclaration('foo', isFinal: true); |
| 595 }); |
| 596 }); |
| 597 SourceEdit edit = getEdit(builder); |
| 598 expect(edit.replacement, equalsIgnoringWhitespace('final foo;')); |
| 599 } |
| 600 |
| 601 test_writeLocalVariableDeclaration_type_initializer() async { |
| 602 String path = '/test.dart'; |
| 603 String content = ''' |
| 604 void f() { |
| 605 |
| 606 } |
| 607 class MyClass {}'''; |
| 608 addSource(path, content); |
| 609 CompilationUnit unit = (await driver.getResult(path))?.unit; |
| 610 |
| 611 ClassDeclaration A = unit.declarations[1]; |
| 612 |
| 613 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 614 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 615 builder.addInsertion(11, (EditBuilder builder) { |
| 616 (builder as DartEditBuilder).writeLocalVariableDeclaration('foo', |
| 617 initializerWriter: () { |
| 618 builder.write('null'); |
| 619 }, type: A.element.type); |
| 620 }); |
| 621 }); |
| 622 SourceEdit edit = getEdit(builder); |
| 623 expect(edit.replacement, equalsIgnoringWhitespace('MyClass foo = null;')); |
| 624 } |
| 625 |
| 626 test_writeLocalVariableDeclaration_type_noInitializer() async { |
| 627 String path = '/test.dart'; |
| 628 String content = ''' |
| 629 void f() { |
| 630 |
| 631 } |
| 632 class MyClass {}'''; |
| 633 addSource(path, content); |
| 634 CompilationUnit unit = (await driver.getResult(path))?.unit; |
| 635 |
| 636 ClassDeclaration A = unit.declarations[1]; |
| 637 |
| 638 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 639 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 640 builder.addInsertion(11, (EditBuilder builder) { |
| 641 (builder as DartEditBuilder).writeLocalVariableDeclaration('foo', |
| 642 type: A.element.type, typeGroupName: 'type'); |
| 643 }); |
| 644 }); |
| 645 SourceEdit edit = getEdit(builder); |
| 646 expect(edit.replacement, equalsIgnoringWhitespace('MyClass foo;')); |
| 647 |
| 648 List<LinkedEditGroup> linkedEditGroups = |
| 649 builder.sourceChange.linkedEditGroups; |
| 650 expect(linkedEditGroups, hasLength(1)); |
| 651 LinkedEditGroup group = linkedEditGroups[0]; |
| 652 expect(group.length, 7); |
| 653 expect(group.positions, hasLength(1)); |
| 654 } |
| 655 |
| 656 test_writeLocalVariableDeclaration_type_noInitializer_final() async { |
| 657 String path = '/test.dart'; |
| 658 String content = ''' |
| 659 void f() { |
| 660 |
| 661 } |
| 662 class MyClass {}'''; |
| 663 addSource(path, content); |
| 664 CompilationUnit unit = (await driver.getResult(path))?.unit; |
| 665 |
| 666 ClassDeclaration A = unit.declarations[1]; |
| 667 |
| 668 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 669 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 670 builder.addInsertion(11, (EditBuilder builder) { |
| 671 (builder as DartEditBuilder).writeLocalVariableDeclaration('foo', |
| 672 isFinal: true, type: A.element.type, typeGroupName: 'type'); |
| 673 }); |
| 674 }); |
| 675 SourceEdit edit = getEdit(builder); |
| 676 expect(edit.replacement, equalsIgnoringWhitespace('final MyClass foo;')); |
| 677 |
| 678 List<LinkedEditGroup> linkedEditGroups = |
| 679 builder.sourceChange.linkedEditGroups; |
| 680 expect(linkedEditGroups, hasLength(1)); |
| 681 LinkedEditGroup group = linkedEditGroups[0]; |
| 682 expect(group.length, 7); |
| 683 expect(group.positions, hasLength(1)); |
| 684 } |
| 685 |
402 test_writeOverrideOfInheritedMember() async { | 686 test_writeOverrideOfInheritedMember() async { |
403 String path = '/test.dart'; | 687 String path = '/test.dart'; |
404 String content = ''' | 688 String content = ''' |
405 class A { | 689 class A { |
406 A add(A a) => null; | 690 A add(A a) => null; |
407 } | 691 } |
408 class B extends A { | 692 class B extends A { |
409 }'''; | 693 }'''; |
410 addSource(path, content); | 694 addSource(path, content); |
411 ClassElement classA = await _getClassElement(path, 'A'); | 695 ClassElement classA = await _getClassElement(path, 'A'); |
412 | 696 |
413 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 697 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
414 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 698 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
415 builder.addInsertion(content.length - 1, (EditBuilder builder) { | 699 builder.addInsertion(content.length - 1, (EditBuilder builder) { |
416 (builder as DartEditBuilder) | 700 (builder as DartEditBuilder) |
417 .writeOverrideOfInheritedMember(classA.methods[0]); | 701 .writeOverrideOfInheritedMember(classA.methods[0]); |
418 }); | 702 }); |
419 }); | 703 }); |
420 SourceEdit edit = getEdit(builder); | 704 SourceEdit edit = getEdit(builder); |
421 expect(edit.replacement, equalsIgnoringWhitespace(''' | 705 expect(edit.replacement, equalsIgnoringWhitespace(''' |
422 @override | 706 @override |
423 A add(A a) { | 707 A add(A a) { |
424 // TODO: implement add | 708 // TODO: implement add |
425 return null; | 709 return null; |
426 }''')); | 710 }''')); |
427 } | 711 } |
428 | 712 |
| 713 test_writeParameterMatchingArgument() async { |
| 714 String path = '/test.dart'; |
| 715 String content = r''' |
| 716 f() {} |
| 717 g() { |
| 718 f(new A()); |
| 719 } |
| 720 class A {} |
| 721 '''; |
| 722 addSource(path, content); |
| 723 CompilationUnit unit = (await driver.getResult(path))?.unit; |
| 724 FunctionDeclaration g = unit.declarations[1]; |
| 725 BlockFunctionBody body = g.functionExpression.body; |
| 726 ExpressionStatement statement = body.block.statements[0]; |
| 727 MethodInvocation invocation = statement.expression; |
| 728 Expression argument = invocation.argumentList.arguments[0]; |
| 729 |
| 730 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 731 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 732 builder.addInsertion(2, (EditBuilder builder) { |
| 733 (builder as DartEditBuilder) |
| 734 .writeParameterMatchingArgument(argument, 0, new Set<String>()); |
| 735 }); |
| 736 }); |
| 737 SourceEdit edit = getEdit(builder); |
| 738 expect(edit.replacement, equalsIgnoringWhitespace('A a')); |
| 739 } |
| 740 |
429 test_writeParameters_named() async { | 741 test_writeParameters_named() async { |
430 String path = '/test.dart'; | 742 String path = '/test.dart'; |
431 String content = 'f(int i, {String s}) {}'; | 743 String content = 'f(int i, {String s}) {}'; |
432 addSource(path, content); | 744 addSource(path, content); |
| 745 |
433 CompilationUnit unit = (await driver.getResult(path))?.unit; | 746 CompilationUnit unit = (await driver.getResult(path))?.unit; |
434 FunctionDeclaration f = unit.declarations[0]; | 747 FunctionDeclaration f = unit.declarations[0]; |
435 FormalParameterList parameters = f.functionExpression.parameters; | 748 FormalParameterList parameters = f.functionExpression.parameters; |
436 Iterable<ParameterElement> elements = parameters.parameters | 749 Iterable<ParameterElement> elements = parameters.parameters |
437 .map(resolutionMap.elementDeclaredByFormalParameter); | 750 .map(resolutionMap.elementDeclaredByFormalParameter); |
438 | 751 |
439 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 752 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
440 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 753 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
441 builder.addInsertion(content.length - 1, (EditBuilder builder) { | 754 builder.addInsertion(content.length - 1, (EditBuilder builder) { |
442 (builder as DartEditBuilder).writeParameters(elements); | 755 (builder as DartEditBuilder).writeParameters(elements); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 MethodInvocation invocation = statement.expression; | 813 MethodInvocation invocation = statement.expression; |
501 | 814 |
502 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 815 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
503 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 816 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
504 builder.addInsertion(content.length - 1, (EditBuilder builder) { | 817 builder.addInsertion(content.length - 1, (EditBuilder builder) { |
505 (builder as DartEditBuilder) | 818 (builder as DartEditBuilder) |
506 .writeParametersMatchingArguments(invocation.argumentList); | 819 .writeParametersMatchingArguments(invocation.argumentList); |
507 }); | 820 }); |
508 }); | 821 }); |
509 SourceEdit edit = getEdit(builder); | 822 SourceEdit edit = getEdit(builder); |
510 expect( | 823 expect(edit.replacement, equalsIgnoringWhitespace('String s, {int index}')); |
511 edit.replacement, equalsIgnoringWhitespace('(String s, [int index])')); | |
512 } | 824 } |
513 | 825 |
514 test_writeParametersMatchingArguments_required() async { | 826 test_writeParametersMatchingArguments_required() async { |
515 String path = '/test.dart'; | 827 String path = '/test.dart'; |
516 String content = ''' | 828 String content = ''' |
517 f(int i, String s) { | 829 f(int i, String s) { |
518 g(s, i); | 830 g(s, i); |
519 }'''; | 831 }'''; |
520 addSource(path, content); | 832 addSource(path, content); |
521 CompilationUnit unit = (await driver.getResult(path))?.unit; | 833 CompilationUnit unit = (await driver.getResult(path))?.unit; |
522 FunctionDeclaration f = unit.declarations[0]; | 834 FunctionDeclaration f = unit.declarations[0]; |
523 BlockFunctionBody body = f.functionExpression.body; | 835 BlockFunctionBody body = f.functionExpression.body; |
524 ExpressionStatement statement = body.block.statements[0]; | 836 ExpressionStatement statement = body.block.statements[0]; |
525 MethodInvocation invocation = statement.expression; | 837 MethodInvocation invocation = statement.expression; |
526 | 838 |
527 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 839 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
528 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 840 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
529 builder.addInsertion(content.length - 1, (EditBuilder builder) { | 841 builder.addInsertion(content.length - 1, (EditBuilder builder) { |
530 (builder as DartEditBuilder) | 842 (builder as DartEditBuilder) |
531 .writeParametersMatchingArguments(invocation.argumentList); | 843 .writeParametersMatchingArguments(invocation.argumentList); |
532 }); | 844 }); |
533 }); | 845 }); |
534 SourceEdit edit = getEdit(builder); | 846 SourceEdit edit = getEdit(builder); |
535 expect(edit.replacement, equalsIgnoringWhitespace('(String s, int i)')); | 847 expect(edit.replacement, equalsIgnoringWhitespace('String s, int i')); |
536 } | 848 } |
537 | 849 |
538 test_writeParameterSource() async { | 850 test_writeParameterSource() async { |
539 String path = '/test.dart'; | 851 String path = '/test.dart'; |
540 String content = 'class A {}'; | 852 String content = 'class A {}'; |
541 addSource(path, content); | 853 addSource(path, content); |
542 DartType typeA = await _getType(path, 'A'); | 854 DartType typeA = await _getType(path, 'A'); |
543 | 855 |
544 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 856 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
545 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { | 857 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 return result.element.getType(name); | 1109 return result.element.getType(name); |
798 } | 1110 } |
799 | 1111 |
800 Future<DartType> _getType(String path, String name) async { | 1112 Future<DartType> _getType(String path, String name) async { |
801 ClassElement classElement = await _getClassElement(path, name); | 1113 ClassElement classElement = await _getClassElement(path, name); |
802 return classElement.type; | 1114 return classElement.type; |
803 } | 1115 } |
804 } | 1116 } |
805 | 1117 |
806 @reflectiveTest | 1118 @reflectiveTest |
807 class DartFileEditBuilderImplTest extends AbstractContextTest { | 1119 class DartFileEditBuilderImplTest extends AbstractContextTest |
| 1120 with BuilderTestMixin { |
808 @override | 1121 @override |
809 bool get enableNewAnalysisDriver => true; | 1122 bool get enableNewAnalysisDriver => true; |
810 | 1123 |
| 1124 TypeProvider get typeProvider { |
| 1125 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext(); |
| 1126 context.sourceFactory = new SourceFactoryImpl([new DartUriResolver(sdk)]); |
| 1127 return new TestTypeProvider(context); |
| 1128 } |
| 1129 |
| 1130 test_convertFunctionFromSyncToAsync() async { |
| 1131 String path = '/test.dart'; |
| 1132 addSource(path, 'String f() {}'); |
| 1133 |
| 1134 CompilationUnit unit = (await driver.getResult(path))?.unit; |
| 1135 FunctionDeclaration function = unit.declarations[0]; |
| 1136 FunctionBody body = function.functionExpression.body; |
| 1137 |
| 1138 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 1139 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 1140 (builder as DartFileEditBuilder) |
| 1141 .convertFunctionFromSyncToAsync(body, typeProvider); |
| 1142 }); |
| 1143 List<SourceEdit> edits = getEdits(builder); |
| 1144 expect(edits, hasLength(2)); |
| 1145 expect(edits[0].replacement, equalsIgnoringWhitespace('async')); |
| 1146 expect(edits[1].replacement, equalsIgnoringWhitespace('Future<String>')); |
| 1147 } |
| 1148 |
811 test_createEditBuilder() async { | 1149 test_createEditBuilder() async { |
812 String path = '/test.dart'; | 1150 String path = '/test.dart'; |
813 addSource(path, 'library test;'); | 1151 addSource(path, 'library test;'); |
814 int timeStamp = 65; | 1152 int timeStamp = 65; |
815 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); | 1153 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
816 await builder.addFileEdit(path, timeStamp, (FileEditBuilder builder) { | 1154 await builder.addFileEdit(path, timeStamp, (FileEditBuilder builder) { |
817 int offset = 4; | 1155 int offset = 4; |
818 int length = 5; | 1156 int length = 5; |
819 DartEditBuilderImpl editBuilder = (builder as DartFileEditBuilderImpl) | 1157 DartEditBuilderImpl editBuilder = (builder as DartFileEditBuilderImpl) |
820 .createEditBuilder(offset, length); | 1158 .createEditBuilder(offset, length); |
821 expect(editBuilder, new isInstanceOf<DartEditBuilder>()); | 1159 expect(editBuilder, new isInstanceOf<DartEditBuilder>()); |
822 SourceEdit sourceEdit = editBuilder.sourceEdit; | 1160 SourceEdit sourceEdit = editBuilder.sourceEdit; |
823 expect(sourceEdit.length, length); | 1161 expect(sourceEdit.length, length); |
824 expect(sourceEdit.offset, offset); | 1162 expect(sourceEdit.offset, offset); |
825 expect(sourceEdit.replacement, isEmpty); | 1163 expect(sourceEdit.replacement, isEmpty); |
826 }); | 1164 }); |
827 } | 1165 } |
| 1166 |
| 1167 test_replaceTypeWithFuture() async { |
| 1168 String path = '/test.dart'; |
| 1169 addSource(path, 'String f() {}'); |
| 1170 |
| 1171 CompilationUnit unit = (await driver.getResult(path))?.unit; |
| 1172 FunctionDeclaration function = unit.declarations[0]; |
| 1173 TypeAnnotation type = function.returnType; |
| 1174 |
| 1175 DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver); |
| 1176 await builder.addFileEdit(path, 1, (FileEditBuilder builder) { |
| 1177 (builder as DartFileEditBuilder) |
| 1178 .replaceTypeWithFuture(type, typeProvider); |
| 1179 }); |
| 1180 SourceEdit edit = getEdit(builder); |
| 1181 expect(edit.replacement, equalsIgnoringWhitespace('Future<String>')); |
| 1182 } |
828 } | 1183 } |
| 1184 |
| 1185 @reflectiveTest |
| 1186 class DartLinkedEditBuilderImplTest extends AbstractContextTest { |
| 1187 @override |
| 1188 bool get enableNewAnalysisDriver => true; |
| 1189 |
| 1190 test_addSuperTypesAsSuggestions() async { |
| 1191 String path = '/test.dart'; |
| 1192 addSource( |
| 1193 path, |
| 1194 ''' |
| 1195 class A {} |
| 1196 class B extends A {} |
| 1197 class C extends B {} |
| 1198 '''); |
| 1199 CompilationUnit unit = (await driver.getResult(path))?.unit; |
| 1200 ClassDeclaration classC = unit.declarations[2]; |
| 1201 DartLinkedEditBuilderImpl builder = new DartLinkedEditBuilderImpl(null); |
| 1202 builder.addSuperTypesAsSuggestions(classC.element.type); |
| 1203 List<LinkedEditSuggestion> suggestions = builder.suggestions; |
| 1204 expect(suggestions, hasLength(4)); |
| 1205 expect(suggestions.map((s) => s.value), |
| 1206 unorderedEquals(['Object', 'A', 'B', 'C'])); |
| 1207 } |
| 1208 } |
OLD | NEW |