Re-add tests for MOVE_FILE refactoring.
- Revert commit 90121b528aac0086d5c5fa5324044aa3aa9b2987
- Remove old implementation of MOVE_FILE and return an empty change
- Fix compile errors
- Mark all tests with @failingTest
Bug: https://github.com/dart-lang/sdk/issues/33605
Change-Id: Idb3b31e2bec1788d0e4148dd99213d57b6b2e38a
Reviewed-on: https://dart-review.googlesource.com/63584
Commit-Queue: Danny Tuppeny <dantup@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index e80dadc..b4fd926 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -782,6 +782,7 @@
refactoring is ExtractMethodRefactoring ||
refactoring is ExtractWidgetRefactoring ||
refactoring is InlineMethodRefactoring ||
+ refactoring is MoveFileRefactoring ||
refactoring is RenameRefactoring;
}
@@ -1160,6 +1161,12 @@
inlineRefactoring.inlineAll = inlineOptions.inlineAll;
return new RefactoringStatus();
}
+ if (refactoring is MoveFileRefactoring) {
+ MoveFileRefactoring moveRefactoring = this.refactoring;
+ MoveFileOptions moveOptions = params.options;
+ moveRefactoring.newFile = moveOptions.newFile;
+ return new RefactoringStatus();
+ }
if (refactoring is RenameRefactoring) {
RenameRefactoring renameRefactoring = refactoring;
RenameOptions renameOptions = params.options;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
new file mode 100644
index 0000000..d6d56db
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2018, 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 'dart:async';
+import 'dart:core';
+
+import 'package:analysis_server/src/protocol_server.dart' hide Element;
+import 'package:analysis_server/src/services/correction/status.dart';
+import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:path/path.dart' as pathos;
+
+/**
+ * [MoveFileRefactoring] implementation.
+ */
+class MoveFileRefactoringImpl extends RefactoringImpl
+ implements MoveFileRefactoring {
+ final ResourceProvider resourceProvider;
+ final pathos.Context pathContext;
+ final RefactoringWorkspace workspace;
+ final Source source;
+
+ String oldFile;
+ String newFile;
+
+ SourceChange change;
+ LibraryElement library;
+ String oldLibraryDir;
+ String newLibraryDir;
+
+ MoveFileRefactoringImpl(ResourceProvider resourceProvider, this.workspace,
+ this.source, this.oldFile)
+ : resourceProvider = resourceProvider,
+ pathContext = resourceProvider.pathContext {
+ if (source != null) {
+ oldFile = source.fullName;
+ }
+ }
+
+ @override
+ String get refactoringName => 'Move File';
+
+ @override
+ Future<RefactoringStatus> checkFinalConditions() {
+ RefactoringStatus result = new RefactoringStatus();
+ return new Future.value(result);
+ }
+
+ @override
+ Future<RefactoringStatus> checkInitialConditions() {
+ RefactoringStatus result = new RefactoringStatus();
+ return new Future.value(result);
+ }
+
+ @override
+ Future<SourceChange> createChange() async {
+ // TODO(dantup): Implement!
+ return new SourceChange('Update File References');
+ }
+
+ @override
+ bool requiresPreview() => false;
+
+ String _getRelativeUri(String path, String from) {
+ String uri = pathContext.relative(path, from: from);
+ List<String> parts = pathContext.split(uri);
+ return pathos.posix.joinAll(parts);
+ }
+
+ /**
+ * Checks if the given [path] represents a relative URI.
+ *
+ * The following URI's are not relative:
+ * `/absolute/path/file.dart`
+ * `dart:math`
+ */
+ bool _isRelativeUri(String path) {
+ // absolute URI
+ if (Uri.parse(path).isAbsolute) {
+ return false;
+ }
+ // absolute path
+ if (pathContext.isAbsolute(path)) {
+ return false;
+ }
+ // OK
+ return true;
+ }
+
+ void _updateUriReference(UriReferencedElement element) {
+ if (!element.isSynthetic) {
+ String elementUri = element.uri;
+ if (_isRelativeUri(elementUri)) {
+ String elementPath = pathContext.join(oldLibraryDir, elementUri);
+ String newUri = _getRelativeUri(elementPath, newLibraryDir);
+ int uriOffset = element.uriOffset;
+ int uriLength = element.uriEnd - uriOffset;
+ doSourceChange_addElementEdit(
+ change, library, new SourceEdit(uriOffset, uriLength, "'$newUri'"));
+ }
+ }
+ }
+
+ void _updateUriReferences(List<UriReferencedElement> elements) {
+ for (UriReferencedElement element in elements) {
+ _updateUriReference(element);
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index a93e45b..6b5c4904 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -12,6 +12,7 @@
import 'package:analysis_server/src/services/refactoring/extract_widget.dart';
import 'package:analysis_server/src/services/refactoring/inline_local.dart';
import 'package:analysis_server/src/services/refactoring/inline_method.dart';
+import 'package:analysis_server/src/services/refactoring/move_file.dart';
import 'package:analysis_server/src/services/refactoring/rename_class_member.dart';
import 'package:analysis_server/src/services/refactoring/rename_constructor.dart';
import 'package:analysis_server/src/services/refactoring/rename_import.dart';
@@ -24,8 +25,10 @@
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/ast_provider.dart';
+import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show RefactoringMethodParameter, SourceChange;
@@ -337,6 +340,25 @@
}
/**
+ * [Refactoring] to move/rename a file.
+ */
+abstract class MoveFileRefactoring implements Refactoring {
+ /**
+ * Returns a new [MoveFileRefactoring] instance.
+ */
+ factory MoveFileRefactoring(ResourceProvider resourceProvider,
+ RefactoringWorkspace workspace, Source source, String oldFile) {
+ return new MoveFileRefactoringImpl(
+ resourceProvider, workspace, source, oldFile);
+ }
+
+ /**
+ * The new file path to which the given file is being moved.
+ */
+ void set newFile(String newName);
+}
+
+/**
* Abstract interface for all refactorings.
*/
abstract class Refactoring {
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
new file mode 100644
index 0000000..d2dd25d
--- /dev/null
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -0,0 +1,218 @@
+// Copyright (c) 2018, 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 'dart:async';
+
+import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'abstract_refactoring.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MoveFileTest);
+ });
+}
+
+@reflectiveTest
+class MoveFileTest extends RefactoringTest {
+ MoveFileRefactoring refactoring;
+
+ @failingTest
+ test_file_containing_imports_exports_parts() async {
+ String pathA = '/project/000/1111/a.dart';
+ String pathB = '/project/000/1111/b.dart';
+ String pathC = '/project/000/1111/22/c.dart';
+ testFile = '/project/000/1111/test.dart';
+ addSource('/absolute/uri.dart', '');
+ addSource(pathA, 'part of lib;');
+ addSource(pathB, "import 'test.dart';");
+ addSource(pathC, '');
+ addTestSource('''
+library lib;
+import 'dart:math';
+import '22/c.dart';
+export '333/d.dart';
+part 'a.dart';
+part '/absolute/uri.dart';
+''');
+ // perform refactoring
+ _createRefactoring('/project/000/1111/22/new_name.dart');
+ await _assertSuccessfulRefactoring();
+ assertNoFileChange(pathA);
+ assertFileChangeResult(pathB, "import '22/new_name.dart';");
+ assertNoFileChange(pathC);
+ assertFileChangeResult(testFile, '''
+library lib;
+import 'dart:math';
+import 'c.dart';
+export '../333/d.dart';
+part '../a.dart';
+part '/absolute/uri.dart';
+''');
+ }
+
+ @failingTest
+ test_file_importedLibrary_sideways() async {
+ String pathA = '/project/000/1111/a.dart';
+ testFile = '/project/000/1111/sub/folder/test.dart';
+ addSource(pathA, '''
+import 'sub/folder/test.dart';
+''');
+ addTestSource('');
+ // perform refactoring
+ _createRefactoring('/project/000/new/folder/name/new_name.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+import '../new/folder/name/new_name.dart';
+''');
+ assertNoFileChange(testFile);
+ }
+
+ @failingTest
+ test_file_importedLibrary_down() async {
+ String pathA = '/project/000/1111/a.dart';
+ testFile = '/project/000/1111/test.dart';
+ addSource(pathA, '''
+import 'test.dart';
+''');
+ addTestSource('');
+ // perform refactoring
+ _createRefactoring('/project/000/1111/22/new_name.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+import '22/new_name.dart';
+''');
+ assertNoFileChange(testFile);
+ }
+
+ @failingTest
+ test_file_importedLibrary_package() async {
+ // configure packages
+ testFile = '/packages/my_pkg/lib/aaa/test.dart';
+ newFile(testFile, content: '');
+ // TODO(brianwilkerson) Figure out what this should be replaced with.
+ // TODO(dantup): Change this to use addPackageSource
+// Map<String, List<Folder>> packageMap = {
+// 'my_pkg': <Folder>[provider.getResource('/packages/my_pkg/lib')]
+// };
+// context.sourceFactory = new SourceFactory([
+// new DartUriResolver(sdk),
+// new PackageMapUriResolver(provider, packageMap),
+// resourceResolver
+// ]);
+ // do testing
+ String pathA = '/project/bin/a.dart';
+ addSource(pathA, '''
+import 'package:my_pkg/aaa/test.dart';
+''');
+ addTestSource('', Uri.parse('package:my_pkg/aaa/test.dart'));
+ // perform refactoring
+ _createRefactoring('/packages/my_pkg/lib/bbb/ccc/new_name.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+import 'package:my_pkg/bbb/ccc/new_name.dart';
+''');
+ assertNoFileChange(testFile);
+ }
+
+ @failingTest
+ test_file_importedLibrary_up() async {
+ String pathA = '/project/000/1111/a.dart';
+ testFile = '/project/000/1111/22/test.dart';
+ addSource(pathA, '''
+import '22/test.dart';
+''');
+ addTestSource('');
+ // perform refactoring
+ _createRefactoring('/project/000/1111/new_name.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+import 'new_name.dart';
+''');
+ assertNoFileChange(testFile);
+ }
+
+ @failingTest
+ test_file_referenced_by_part() async {
+ String pathA = '/project/000/1111/a.dart';
+ testFile = '/project/000/1111/22/test.dart';
+ addSource(pathA, '''
+library lib;
+part '22/test.dart';
+''');
+ addTestSource('''
+part of lib;
+''');
+ // perform refactoring
+ _createRefactoring('/project/000/1111/22/new_name.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+library lib;
+part '22/new_name.dart';
+''');
+ assertNoFileChange(testFile);
+ }
+
+ @failingTest
+ test_file_referenced_by_multiple_libraries() async {
+ String pathA = '/project/000/1111/a.dart';
+ String pathB = '/project/000/b.dart';
+ testFile = '/project/000/1111/22/test.dart';
+ addSource(pathA, '''
+library lib;
+part '22/test.dart';
+''');
+ addSource(pathB, '''
+library lib;
+part '1111/22/test.dart';
+''');
+ addTestSource('''
+part of lib;
+''');
+ // perform refactoring
+ _createRefactoring('/project/000/1111/22/new_name.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+library lib;
+part '22/new_name.dart';
+''');
+ assertFileChangeResult(pathB, '''
+library lib;
+part '1111/22/new_name.dart';
+''');
+ assertNoFileChange(testFile);
+ }
+
+ @failingTest
+ test_projectFolder() async {
+ fail('Not yet implemented/tested');
+ }
+
+ @failingTest
+ test_folder_inside_project() async {
+ fail('Not yet implemented/tested');
+ }
+
+ @failingTest
+ test_project_folder_ancestor() async {
+ fail('Not yet implemented/tested');
+ }
+
+ /**
+ * Checks that all conditions are OK.
+ */
+ Future _assertSuccessfulRefactoring() async {
+ await assertRefactoringConditionsOK();
+ refactoringChange = await refactoring.createChange();
+ }
+
+ void _createRefactoring(String newName) {
+ var workspace = new RefactoringWorkspace([driver], searchEngine);
+ refactoring =
+ new MoveFileRefactoring(resourceProvider, workspace, testSource, null);
+ refactoring.newFile = newName;
+ }
+}
diff --git a/pkg/analysis_server/test/services/refactoring/test_all.dart b/pkg/analysis_server/test/services/refactoring/test_all.dart
index 9a75af9..5dc96b6 100644
--- a/pkg/analysis_server/test/services/refactoring/test_all.dart
+++ b/pkg/analysis_server/test/services/refactoring/test_all.dart
@@ -11,6 +11,7 @@
import 'extract_widget_test.dart' as extract_widget_test;
import 'inline_local_test.dart' as inline_local_test;
import 'inline_method_test.dart' as inline_method_test;
+import 'move_file_test.dart' as move_file_test;
import 'naming_conventions_test.dart' as naming_conventions_test;
import 'rename_class_member_test.dart' as rename_class_member_test;
import 'rename_constructor_test.dart' as rename_constructor_test;
@@ -30,6 +31,7 @@
extract_widget_test.main();
inline_local_test.main();
inline_method_test.main();
+ move_file_test.main();
naming_conventions_test.main();
rename_class_member_test.main();
rename_constructor_test.main();