Treat add events for known files as modifications instead of discarding them on Mac OS. Fixes pub serve not seeing files saved in IntelliJ or other tools that use "safe" writes.

https://code.google.com/p/dart/issues/detail?id=21402

R=ajohnsen@google.com, nweiz@google.com

Review URL: https://codereview.chromium.org//861313006
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eb544f6..2ff887e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 0.9.4
+
+* Treat add events for known files as modifications instead of discarding them
+  on Mac OS.
+
 # 0.9.3
 
 * Improved support for Windows via `WindowsDirectoryWatcher`.
diff --git a/lib/src/directory_watcher/mac_os.dart b/lib/src/directory_watcher/mac_os.dart
index e3efa2d..ee20136 100644
--- a/lib/src/directory_watcher/mac_os.dart
+++ b/lib/src/directory_watcher/mac_os.dart
@@ -179,12 +179,15 @@
       for (var event in events) {
         if (event is FileSystemCreateEvent) {
           if (!event.isDirectory) {
-            // Don't emit ADD events for files or directories that we already
-            // know about. Such an event comes from FSEvents reporting an add
-            // that happened prior to the watch beginning.
-            if (_files.contains(path)) continue;
+            // If we already know about the file, treat it like a modification.
+            // This can happen if a file is copied on top of an existing one.
+            // We'll see an ADD event for the latter file when from the user's
+            // perspective, the file's contents just changed.
+            var type = _files.contains(path)
+                ? ChangeType.MODIFY
+                : ChangeType.ADD;
 
-            _emitEvent(ChangeType.ADD, path);
+            _emitEvent(type, path);
             _files.add(path);
             continue;
           }
diff --git a/pubspec.yaml b/pubspec.yaml
index 658ef78..c0c71eb 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: watcher
-version: 0.9.3
+version: 0.9.4
 author: Dart Team <misc@dartlang.org>
 homepage: http://github.com/dart-lang/watcher
 description: >
diff --git a/test/directory_watcher/shared.dart b/test/directory_watcher/shared.dart
index 8632401..a4cec5e 100644
--- a/test/directory_watcher/shared.dart
+++ b/test/directory_watcher/shared.dart
@@ -121,6 +121,18 @@
       renameFile("dir/old.txt", "new.txt");
       expectRemoveEvent("dir/old.txt");
     });
+
+    test('notifies when a file is moved onto an existing one', () {
+      writeFile("from.txt");
+      writeFile("to.txt");
+      startWatcher();
+
+      renameFile("from.txt", "to.txt");
+      inAnyOrder([
+        isRemoveEvent("from.txt"),
+        isModifyEvent("to.txt")
+      ]);
+    });
   });
 
   // Most of the time, when multiple filesystem actions happen in sequence,