OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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/edit/assist/assist_core.dart'; | 7 import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; |
8 import 'package:analysis_server/plugin/edit/assist/assist_dart.dart'; | 8 import 'package:analysis_server/plugin/edit/assist/assist_dart.dart'; |
9 import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; | 9 import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; |
10 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart'; | 10 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart'; |
(...skipping 18 matching lines...) Expand all Loading... |
29 import 'package:analyzer/error/error.dart' as engine; | 29 import 'package:analyzer/error/error.dart' as engine; |
30 import 'package:analyzer/file_system/file_system.dart'; | 30 import 'package:analyzer/file_system/file_system.dart'; |
31 import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; | 31 import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; |
32 import 'package:analyzer/src/dart/analysis/driver.dart'; | 32 import 'package:analyzer/src/dart/analysis/driver.dart'; |
33 import 'package:analyzer/src/dart/element/ast_provider.dart'; | 33 import 'package:analyzer/src/dart/element/ast_provider.dart'; |
34 import 'package:analyzer/src/dart/scanner/scanner.dart' as engine; | 34 import 'package:analyzer/src/dart/scanner/scanner.dart' as engine; |
35 import 'package:analyzer/src/error/codes.dart' as engine; | 35 import 'package:analyzer/src/error/codes.dart' as engine; |
36 import 'package:analyzer/src/generated/engine.dart' as engine; | 36 import 'package:analyzer/src/generated/engine.dart' as engine; |
37 import 'package:analyzer/src/generated/parser.dart' as engine; | 37 import 'package:analyzer/src/generated/parser.dart' as engine; |
38 import 'package:analyzer/src/generated/source.dart'; | 38 import 'package:analyzer/src/generated/source.dart'; |
39 import 'package:analyzer/task/dart.dart'; | |
40 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; | 39 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; |
41 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; | 40 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; |
42 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; | 41 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; |
43 import 'package:dart_style/dart_style.dart'; | 42 import 'package:dart_style/dart_style.dart'; |
44 | 43 |
45 int test_resetCount = 0; | 44 int test_resetCount = 0; |
46 | 45 |
47 bool test_simulateRefactoringException_change = false; | 46 bool test_simulateRefactoringException_change = false; |
48 bool test_simulateRefactoringException_final = false; | 47 bool test_simulateRefactoringException_final = false; |
49 bool test_simulateRefactoringException_init = false; | 48 bool test_simulateRefactoringException_init = false; |
(...skipping 25 matching lines...) Expand all Loading... |
75 _newRefactoringManager(); | 74 _newRefactoringManager(); |
76 } | 75 } |
77 | 76 |
78 Response format(Request request) { | 77 Response format(Request request) { |
79 EditFormatParams params = new EditFormatParams.fromRequest(request); | 78 EditFormatParams params = new EditFormatParams.fromRequest(request); |
80 String file = params.file; | 79 String file = params.file; |
81 | 80 |
82 String unformattedSource; | 81 String unformattedSource; |
83 try { | 82 try { |
84 Source source = server.resourceProvider.getFile(file).createSource(); | 83 Source source = server.resourceProvider.getFile(file).createSource(); |
85 if (server.options.enableNewAnalysisDriver) { | 84 unformattedSource = |
86 unformattedSource = server.fileContentOverlay[file]; | 85 server.fileContentOverlay[file] ?? source.contents.data; |
87 } else { | |
88 unformattedSource = server.overlayState.getContents(source); | |
89 } | |
90 unformattedSource ??= source.contents.data; | |
91 } catch (e) { | 86 } catch (e) { |
92 return new Response.formatInvalidFile(request); | 87 return new Response.formatInvalidFile(request); |
93 } | 88 } |
94 | 89 |
95 int start = params.selectionOffset; | 90 int start = params.selectionOffset; |
96 int length = params.selectionLength; | 91 int length = params.selectionLength; |
97 | 92 |
98 // No need to preserve 0,0 selection | 93 // No need to preserve 0,0 selection |
99 if (start == 0 && length == 0) { | 94 if (start == 0 && length == 0) { |
100 start = null; | 95 start = null; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 | 333 |
339 Future<Null> organizeDirectives(Request request) async { | 334 Future<Null> organizeDirectives(Request request) async { |
340 var params = new EditOrganizeDirectivesParams.fromRequest(request); | 335 var params = new EditOrganizeDirectivesParams.fromRequest(request); |
341 // prepare file | 336 // prepare file |
342 String file = params.file; | 337 String file = params.file; |
343 if (!engine.AnalysisEngine.isDartFileName(file)) { | 338 if (!engine.AnalysisEngine.isDartFileName(file)) { |
344 server.sendResponse(new Response.fileNotAnalyzed(request, file)); | 339 server.sendResponse(new Response.fileNotAnalyzed(request, file)); |
345 return; | 340 return; |
346 } | 341 } |
347 // Prepare the file information. | 342 // Prepare the file information. |
348 int fileStamp; | 343 AnalysisResult result = await server.getAnalysisResult(file); |
349 String code; | 344 if (result == null) { |
350 CompilationUnit unit; | 345 server.sendResponse(new Response.fileNotAnalyzed(request, file)); |
351 List<engine.AnalysisError> errors; | 346 return; |
352 if (server.options.enableNewAnalysisDriver) { | |
353 AnalysisResult result = await server.getAnalysisResult(file); | |
354 if (result == null) { | |
355 server.sendResponse(new Response.fileNotAnalyzed(request, file)); | |
356 return; | |
357 } | |
358 fileStamp = -1; | |
359 code = result.content; | |
360 unit = result.unit; | |
361 errors = result.errors; | |
362 } else { | |
363 // prepare resolved unit | |
364 unit = await server.getResolvedCompilationUnit(file); | |
365 if (unit == null) { | |
366 server.sendResponse(new Response.fileNotAnalyzed(request, file)); | |
367 return; | |
368 } | |
369 // prepare context | |
370 CompilationUnitElement compilationUnitElement = | |
371 resolutionMap.elementDeclaredByCompilationUnit(unit); | |
372 engine.AnalysisContext context = compilationUnitElement.context; | |
373 Source source = compilationUnitElement.source; | |
374 errors = context.computeErrors(source); | |
375 // prepare code | |
376 fileStamp = context.getModificationStamp(source); | |
377 code = context.getContents(source).data; | |
378 } | 347 } |
| 348 int fileStamp = -1; |
| 349 String code = result.content; |
| 350 CompilationUnit unit = result.unit; |
| 351 List<engine.AnalysisError> errors = result.errors; |
379 // check if there are scan/parse errors in the file | 352 // check if there are scan/parse errors in the file |
380 int numScanParseErrors = _getNumberOfScanParseErrors(errors); | 353 int numScanParseErrors = _getNumberOfScanParseErrors(errors); |
381 if (numScanParseErrors != 0) { | 354 if (numScanParseErrors != 0) { |
382 server.sendResponse(new Response.organizeDirectivesError( | 355 server.sendResponse(new Response.organizeDirectivesError( |
383 request, 'File has $numScanParseErrors scan/parse errors.')); | 356 request, 'File has $numScanParseErrors scan/parse errors.')); |
384 return; | 357 return; |
385 } | 358 } |
386 // do organize | 359 // do organize |
387 DirectiveOrganizer sorter = new DirectiveOrganizer(code, unit, errors); | 360 DirectiveOrganizer sorter = new DirectiveOrganizer(code, unit, errors); |
388 List<SourceEdit> edits = sorter.organize(); | 361 List<SourceEdit> edits = sorter.organize(); |
389 SourceFileEdit fileEdit = new SourceFileEdit(file, fileStamp, edits: edits); | 362 SourceFileEdit fileEdit = new SourceFileEdit(file, fileStamp, edits: edits); |
390 server.sendResponse( | 363 server.sendResponse( |
391 new EditOrganizeDirectivesResult(fileEdit).toResponse(request.id)); | 364 new EditOrganizeDirectivesResult(fileEdit).toResponse(request.id)); |
392 } | 365 } |
393 | 366 |
394 Future<Null> sortMembers(Request request) async { | 367 Future<Null> sortMembers(Request request) async { |
395 var params = new EditSortMembersParams.fromRequest(request); | 368 var params = new EditSortMembersParams.fromRequest(request); |
396 // prepare file | 369 // prepare file |
397 String file = params.file; | 370 String file = params.file; |
398 if (!engine.AnalysisEngine.isDartFileName(file)) { | 371 if (!engine.AnalysisEngine.isDartFileName(file)) { |
399 server.sendResponse(new Response.sortMembersInvalidFile(request)); | 372 server.sendResponse(new Response.sortMembersInvalidFile(request)); |
400 return; | 373 return; |
401 } | 374 } |
402 // Prepare the file information. | 375 // Prepare the file information. |
403 int fileStamp; | 376 AnalysisDriver driver = server.getAnalysisDriver(file); |
404 String code; | 377 ParseResult result = await driver?.parseFile(file); |
405 CompilationUnit unit; | 378 if (result == null) { |
406 List<engine.AnalysisError> errors; | 379 server.sendResponse(new Response.fileNotAnalyzed(request, file)); |
407 if (server.options.enableNewAnalysisDriver) { | 380 return; |
408 AnalysisDriver driver = server.getAnalysisDriver(file); | |
409 ParseResult result = await driver?.parseFile(file); | |
410 if (result == null) { | |
411 server.sendResponse(new Response.fileNotAnalyzed(request, file)); | |
412 return; | |
413 } | |
414 fileStamp = -1; | |
415 code = result.content; | |
416 unit = result.unit; | |
417 errors = result.errors; | |
418 } else { | |
419 // prepare location | |
420 ContextSourcePair contextSource = server.getContextSourcePair(file); | |
421 engine.AnalysisContext context = contextSource.context; | |
422 Source source = contextSource.source; | |
423 if (context == null || source == null) { | |
424 server.sendResponse(new Response.sortMembersInvalidFile(request)); | |
425 return; | |
426 } | |
427 // prepare code | |
428 fileStamp = context.getModificationStamp(source); | |
429 code = context.getContents(source).data; | |
430 // prepare parsed unit | |
431 try { | |
432 unit = context.parseCompilationUnit(source); | |
433 } catch (e) { | |
434 server.sendResponse(new Response.sortMembersInvalidFile(request)); | |
435 return; | |
436 } | |
437 // Get the errors. | |
438 errors = context.getErrors(source).errors; | |
439 } | 381 } |
| 382 int fileStamp = -1; |
| 383 String code = result.content; |
| 384 CompilationUnit unit = result.unit; |
| 385 List<engine.AnalysisError> errors = result.errors; |
440 // Check if there are scan/parse errors in the file. | 386 // Check if there are scan/parse errors in the file. |
441 int numScanParseErrors = _getNumberOfScanParseErrors(errors); | 387 int numScanParseErrors = _getNumberOfScanParseErrors(errors); |
442 if (numScanParseErrors != 0) { | 388 if (numScanParseErrors != 0) { |
443 server.sendResponse( | 389 server.sendResponse( |
444 new Response.sortMembersParseErrors(request, numScanParseErrors)); | 390 new Response.sortMembersParseErrors(request, numScanParseErrors)); |
445 return; | 391 return; |
446 } | 392 } |
447 // Do sort. | 393 // Do sort. |
448 MemberSorter sorter = new MemberSorter(code, unit); | 394 MemberSorter sorter = new MemberSorter(code, unit); |
449 List<SourceEdit> edits = sorter.sort(); | 395 List<SourceEdit> edits = sorter.sort(); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 cancel(); | 652 cancel(); |
707 } else { | 653 } else { |
708 server.instrumentationService.logException(exception, stackTrace); | 654 server.instrumentationService.logException(exception, stackTrace); |
709 server.sendResponse( | 655 server.sendResponse( |
710 new Response.serverError(_request, exception, stackTrace)); | 656 new Response.serverError(_request, exception, stackTrace)); |
711 } | 657 } |
712 _reset(); | 658 _reset(); |
713 }); | 659 }); |
714 } | 660 } |
715 | 661 |
716 /** | |
717 * Perform enough analysis to be able to perform refactoring of the given | |
718 * [kind] in the given [file]. | |
719 */ | |
720 Future<Null> _analyzeForRefactoring(String file, RefactoringKind kind) async { | |
721 if (server.options.enableNewAnalysisDriver) { | |
722 return; | |
723 } | |
724 // "Extract Local" and "Inline Local" refactorings need only local analysis. | |
725 if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE || | |
726 kind == RefactoringKind.INLINE_LOCAL_VARIABLE) { | |
727 ContextSourcePair pair = server.getContextSourcePair(file); | |
728 engine.AnalysisContext context = pair.context; | |
729 Source source = pair.source; | |
730 if (context != null && source != null) { | |
731 if (context.computeResult(source, SOURCE_KIND) == SourceKind.LIBRARY) { | |
732 await context.computeResolvedCompilationUnitAsync(source, source); | |
733 return; | |
734 } | |
735 } | |
736 } | |
737 // A refactoring for which we cannot optimize analysis. | |
738 // So, wait for full analysis. | |
739 await server.onAnalysisComplete; | |
740 } | |
741 | |
742 void _checkForReset_afterCreateChange() { | 662 void _checkForReset_afterCreateChange() { |
743 if (test_simulateRefactoringReset_afterCreateChange) { | 663 if (test_simulateRefactoringReset_afterCreateChange) { |
744 _reset(); | 664 _reset(); |
745 } | 665 } |
746 if (refactoring == null) { | 666 if (refactoring == null) { |
747 throw new _ResetError(); | 667 throw new _ResetError(); |
748 } | 668 } |
749 } | 669 } |
750 | 670 |
751 void _checkForReset_afterFinalConditions() { | 671 void _checkForReset_afterFinalConditions() { |
(...skipping 13 matching lines...) Expand all Loading... |
765 throw new _ResetError(); | 685 throw new _ResetError(); |
766 } | 686 } |
767 } | 687 } |
768 | 688 |
769 /** | 689 /** |
770 * Initializes this context to perform a refactoring with the specified | 690 * Initializes this context to perform a refactoring with the specified |
771 * parameters. The existing [Refactoring] is reused or created as needed. | 691 * parameters. The existing [Refactoring] is reused or created as needed. |
772 */ | 692 */ |
773 Future _init( | 693 Future _init( |
774 RefactoringKind kind, String file, int offset, int length) async { | 694 RefactoringKind kind, String file, int offset, int length) async { |
775 await _analyzeForRefactoring(file, kind); | |
776 // check if we can continue with the existing Refactoring instance | 695 // check if we can continue with the existing Refactoring instance |
777 if (this.kind == kind && | 696 if (this.kind == kind && |
778 this.file == file && | 697 this.file == file && |
779 this.offset == offset && | 698 this.offset == offset && |
780 this.length == length) { | 699 this.length == length) { |
781 return; | 700 return; |
782 } | 701 } |
783 _reset(); | 702 _reset(); |
784 this.kind = kind; | 703 this.kind = kind; |
785 this.file = file; | 704 this.file = file; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 } | 760 } |
842 if (kind == RefactoringKind.INLINE_METHOD) { | 761 if (kind == RefactoringKind.INLINE_METHOD) { |
843 CompilationUnit unit = await server.getResolvedCompilationUnit(file); | 762 CompilationUnit unit = await server.getResolvedCompilationUnit(file); |
844 if (unit != null) { | 763 if (unit != null) { |
845 _resetOnAnalysisStarted(); | 764 _resetOnAnalysisStarted(); |
846 refactoring = new InlineMethodRefactoring( | 765 refactoring = new InlineMethodRefactoring( |
847 searchEngine, server.getAstProvider(file), unit, offset); | 766 searchEngine, server.getAstProvider(file), unit, offset); |
848 } | 767 } |
849 } | 768 } |
850 if (kind == RefactoringKind.MOVE_FILE) { | 769 if (kind == RefactoringKind.MOVE_FILE) { |
851 _resetOnAnalysisStarted(); | 770 // TODO(brianwilkerson) Re-implement this refactoring under the new analys
is driver |
852 ContextSourcePair contextSource = server.getContextSourcePair(file); | 771 // _resetOnAnalysisStarted(); |
853 engine.AnalysisContext context = contextSource.context; | 772 // ContextSourcePair contextSource = server.getContextSourcePair(file); |
854 Source source = contextSource.source; | 773 // engine.AnalysisContext context = contextSource.context; |
855 refactoring = new MoveFileRefactoring( | 774 // Source source = contextSource.source; |
856 server.resourceProvider, searchEngine, context, source, file); | 775 // refactoring = new MoveFileRefactoring( |
| 776 // server.resourceProvider, searchEngine, context, source, file); |
857 } | 777 } |
858 if (kind == RefactoringKind.RENAME) { | 778 if (kind == RefactoringKind.RENAME) { |
859 AstNode node = await server.getNodeAtOffset(file, offset); | 779 AstNode node = await server.getNodeAtOffset(file, offset); |
860 Element element = server.getElementOfNode(node); | 780 Element element = server.getElementOfNode(node); |
861 if (node != null && element != null) { | 781 if (node != null && element != null) { |
862 if (element is FieldFormalParameterElement) { | 782 if (element is FieldFormalParameterElement) { |
863 element = (element as FieldFormalParameterElement).field; | 783 element = (element as FieldFormalParameterElement).field; |
864 } | 784 } |
865 // climb from "Class" in "new Class.named()" to "Class.named" | 785 // climb from "Class" in "new Class.named()" to "Class.named" |
866 if (node.parent is TypeName && node.parent.parent is ConstructorName) { | 786 if (node.parent is TypeName && node.parent.parent is ConstructorName) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 subscriptionToReset?.cancel(); | 866 subscriptionToReset?.cancel(); |
947 subscriptionToReset = server.onAnalysisStarted.listen((_) => _reset()); | 867 subscriptionToReset = server.onAnalysisStarted.listen((_) => _reset()); |
948 } | 868 } |
949 | 869 |
950 /** | 870 /** |
951 * We're performing a refactoring that affects only the given [file]. | 871 * We're performing a refactoring that affects only the given [file]. |
952 * So, when the [file] resolution is changed, we need to reset refactoring. | 872 * So, when the [file] resolution is changed, we need to reset refactoring. |
953 * But when any other file is changed or analyzed, we can continue. | 873 * But when any other file is changed or analyzed, we can continue. |
954 */ | 874 */ |
955 void _resetOnFileResolutionChanged(String file) { | 875 void _resetOnFileResolutionChanged(String file) { |
956 if (server.options.enableNewAnalysisDriver) { | 876 // TODO(brianwilkerson) Decide whether we want to implement this |
957 return; | 877 // functionality for the new analysis driver or whether we should remove |
958 } | 878 // this method. |
959 subscriptionToReset?.cancel(); | |
960 subscriptionToReset = server | |
961 .getAnalysisContext(file) | |
962 ?.onResultChanged(RESOLVED_UNIT) | |
963 ?.listen((event) { | |
964 Source targetSource = event.target.source; | |
965 if (targetSource?.fullName == file) { | |
966 _reset(); | |
967 } | |
968 }); | |
969 } | 879 } |
970 | 880 |
971 void _sendResultResponse() { | 881 void _sendResultResponse() { |
972 // ignore if was cancelled | 882 // ignore if was cancelled |
973 if (request == null) { | 883 if (request == null) { |
974 return; | 884 return; |
975 } | 885 } |
976 // set feedback | 886 // set feedback |
977 result.feedback = feedback; | 887 result.feedback = feedback; |
978 // set problems | 888 // set problems |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 } | 937 } |
1028 return new RefactoringStatus(); | 938 return new RefactoringStatus(); |
1029 } | 939 } |
1030 } | 940 } |
1031 | 941 |
1032 /** | 942 /** |
1033 * [_RefactoringManager] throws instances of this class internally to stop | 943 * [_RefactoringManager] throws instances of this class internally to stop |
1034 * processing in a manager that was reset. | 944 * processing in a manager that was reset. |
1035 */ | 945 */ |
1036 class _ResetError {} | 946 class _ResetError {} |
OLD | NEW |