void (List<VFileEvent> events, NewVirtualFileSystem fs, @Nullable NewVirtualFile parent, NewVirtualFile child, FileAttributes childAttributes, boolean enqueue) { boolean fileDirty = child.isDirty(); if (LOG.isTraceEnabled()) LOG.trace("file=" + child + " dirty=" + fileDirty); if (!fileDirty) { return; } if (checkAndScheduleFileTypeChange(events, fs, parent, child, childAttributes)) { child.markClean(); return; } checkWritableAttributeChange(events, child, myPersistence.isWritable(child), childAttributes.isWritable()); if (SystemInfoRt.isWindows) { checkHiddenAttributeChange(events, child, child.is(VFileProperty.HIDDEN), childAttributes.isHidden()); } if (childAttributes.isSymLink()) { var t = System.nanoTime(); var target = fs.resolveSymLink(child); myIoTime.addAndGet(System.nanoTime() - t); checkSymbolicLinkChange(events, child, child.getCanonicalPath(), target); } if (!childAttributes.isDirectory()) { long oldTimestamp = myPersistence.getTimeStamp(child), newTimestamp = childAttributes.lastModified; long oldLength = myPersistence.getLastRecordedLength(child), newLength = childAttributes.length; if (oldTimestamp != newTimestamp || oldLength != newLength) { if (LOG.isTraceEnabled()) LOG.trace( "update file=" + child + (oldTimestamp != newTimestamp ? " TS=" + oldTimestamp + "->" + newTimestamp : "") + (oldLength != newLength ? " len=" + oldLength + "->" + newLength : "")); events.add(new VFileContentChangeEvent(myRequestor, child, child.getModificationStamp(), -1, oldTimestamp, newTimestamp, oldLength, newLength)); } child.markClean(); } else if (enqueue && myIsRecursive) { if (child instanceof VirtualDirectoryImpl) { mySemaphore.down(); myRefreshQueue.add(child); } else { LOG.error("not a directory: " + child + " (" + child.getClass() + ')'); } } }