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();