diff --git a/src/org/rascalmpl/uri/URIResolverRegistry.java b/src/org/rascalmpl/uri/URIResolverRegistry.java index 4ea3e0b435b..f82292a4389 100644 --- a/src/org/rascalmpl/uri/URIResolverRegistry.java +++ b/src/org/rascalmpl/uri/URIResolverRegistry.java @@ -964,29 +964,40 @@ private void mkParentDir(ISourceLocation uri) throws IOException { } } - public void watch(ISourceLocation loc, boolean recursive, Consumer callback) + public void watch(ISourceLocation loc, boolean recursive, final Consumer callback) throws IOException { - loc = safeResolve(loc); - if (!isDirectory(loc)) { // so underlying implementations of ISourceLocationWatcher only have to support // watching directories (the native NEO file watchers are like that) loc = URIUtil.getParentLocation(loc); } - ISourceLocationWatcher watcher = watchers.getOrDefault(loc.getScheme(), fallbackWatcher); + ISourceLocation resolved = safeResolve(loc); + + Consumer newCallback = !resolved.equals(loc) ? + // we resolved logical resolvers in order to use native watchers as much as possible + // for efficiency sake, but this breaks the logical URI abstraction. We have to undo + // this renaming before we trigger the callback. + changes -> { + ISourceLocation relative = URIUtil.relativize(resolved, changes.getLocation()); + ISourceLocation unresolved = URIUtil.getChildLocation(loc, relative.getPath()); + callback.accept(ISourceLocationWatcher.makeChange(unresolved, changes.getChangeType(), changes.getType())); + } + : callback; + + ISourceLocationWatcher watcher = watchers.getOrDefault(resolved.getScheme(), fallbackWatcher); if (watcher != null) { - watcher.watch(loc, callback); + watcher.watch(resolved, callback); } else { - watching.computeIfAbsent(loc, k -> ConcurrentHashMap.newKeySet()).add(callback); + watching.computeIfAbsent(resolved, k -> ConcurrentHashMap.newKeySet()).add(newCallback); } - if (isDirectory(loc) && recursive) { - for (ISourceLocation elem : list(loc)) { + if (isDirectory(resolved) && recursive) { + for (ISourceLocation elem : list(resolved)) { if (isDirectory(elem)) { try { - watch(elem, recursive, callback); + watch(elem, recursive, newCallback); } catch (IOException e) { // we swallow recursive IO errors which can be caused by file permissions.