Fix state machine in _DiscoverAvailableFilesTask.perform

* When iterating over folders with folderIterator we must check
elapsed time and decide to exit before we call moveNext. If we
do it in an oposite order we will skip the current element when we
come back - because we will call moveNext again.

* Only add driver.addedFiles *once* to the list of files. Previous
we were adding it everytime we called perform() leading to duplicates
in the list.

Change-Id: Idd1d2a272661fe204b24af0be4539c3a154c9652
Reviewed-on: https://dart-review.googlesource.com/57826
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 83c5c4c..62b19d3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -2284,11 +2284,11 @@
    * task should continue to be run.
    */
   void perform() {
-    // Always discover added files.
-    files.addAll(driver.addedFiles);
-
     // Prepare the iterator of package/lib folders.
     if (folderIterator == null) {
+      // Always discover added files.
+      files.addAll(driver.addedFiles);
+
       var packageMap = driver._sourceFactory.packageMap;
       if (packageMap != null) {
         folderIterator = packageMap.values.expand((f) => f).iterator;
@@ -2300,11 +2300,14 @@
     // List each package/lib folder recursively.
     Stopwatch timer = new Stopwatch()..start();
     while (folderIterator.moveNext()) {
+      var folder = folderIterator.current;
+      _appendFilesRecursively(folder);
+
+      // Note: must check if we are exiting before calling moveNext()
+      // otherwise we will skip one iteration of the loop when we come back.
       if (timer.elapsedMilliseconds > _MS_WORK_INTERVAL) {
         return;
       }
-      var folder = folderIterator.current;
-      _appendFilesRecursively(folder);
     }
 
     // Get know files one by one.