Made example-vfs compilable and workable.
This commit is contained in:
@@ -82,19 +82,19 @@ public object FileSystem {
|
|||||||
|
|
||||||
/* Scans file recursively and adds info about it to fileToInfo map */
|
/* Scans file recursively and adds info about it to fileToInfo map */
|
||||||
private fun scanAndAddRecursivelyNoEvents(file : VirtualFile) {
|
private fun scanAndAddRecursivelyNoEvents(file : VirtualFile) {
|
||||||
assert(FileSystem.fileToInfo[file.path] == null)
|
require(FileSystem.fileToInfo[file.path] == null)
|
||||||
|
|
||||||
val fileInfo = VirtualFileInfo(file)
|
val fileInfo = VirtualFileInfo(file)
|
||||||
FileSystem.fileToInfo[file.path] = fileInfo
|
FileSystem.fileToInfo[file.path] = fileInfo
|
||||||
fileInfo.children.foreach{ scanAndAddRecursivelyNoEvents(it) }
|
fileInfo.children.forEach{ scanAndAddRecursivelyNoEvents(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun assertCanRead() {
|
internal inline fun assertCanRead() {
|
||||||
assert(lock.getReadHoldCount() != 0 || lock.isWriteLockedByCurrentThread())
|
check(lock.getReadHoldCount() != 0 || lock.isWriteLockedByCurrentThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun assertCanWrite() {
|
internal inline fun assertCanWrite() {
|
||||||
assert(lock.isWriteLockedByCurrentThread())
|
check(lock.isWriteLockedByCurrentThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,12 +107,8 @@ public object FileSystem {
|
|||||||
/**
|
/**
|
||||||
* Adds file system listener which should be notified about changing of file system.
|
* Adds file system listener which should be notified about changing of file system.
|
||||||
*/
|
*/
|
||||||
public fun addVirtualFileListener(listener : VirtualFileListener.(VirtualFileEvent)->Unit) : VirtualFileListener {
|
public fun addVirtualFileListener(listener : (VirtualFileEvent)->Unit) : VirtualFileListener {
|
||||||
val vfl = object: VirtualFileListener{
|
val vfl = SimpleVirtualFileListener(listener)
|
||||||
override fun eventHappened(event: VirtualFileEvent) {
|
|
||||||
listener(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addVirtualFileListener(vfl)
|
addVirtualFileListener(vfl)
|
||||||
return vfl
|
return vfl
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import java.util.Timer
|
|||||||
import java.util.TimerTask
|
import java.util.TimerTask
|
||||||
|
|
||||||
import org.jetbrains.jet.samples.vfs.utils.*
|
import org.jetbrains.jet.samples.vfs.utils.*
|
||||||
import org.jetbrains.jet.samples.vfs.utils.listDifference
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton which creates thread for periodically checking if there are changes in
|
* Singleton which creates thread for periodically checking if there are changes in
|
||||||
@@ -37,13 +36,13 @@ internal object RefreshQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun takeAndRefreshFiles() {
|
private fun takeAndRefreshFiles() {
|
||||||
refreshFiles(taskQueue.take())
|
refreshFiles(taskQueue.take()!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Acquires write lock and refreshes file system */
|
/* Acquires write lock and refreshes file system */
|
||||||
private fun refreshFiles(files : List<VirtualFile>) {
|
private fun refreshFiles(files : List<VirtualFile>) {
|
||||||
FileSystem.write {
|
FileSystem.write {
|
||||||
files.foreach{ refreshFile(it) }
|
files.forEach{ refreshFile(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ internal object RefreshQueue {
|
|||||||
private fun refreshFile(file : VirtualFile) {
|
private fun refreshFile(file : VirtualFile) {
|
||||||
FileSystem.assertCanWrite()
|
FileSystem.assertCanWrite()
|
||||||
val fileInfo = FileSystem.fileToInfo[file.path]
|
val fileInfo = FileSystem.fileToInfo[file.path]
|
||||||
assert(fileInfo != null)
|
check(fileInfo != null)
|
||||||
if (fileInfo == null) {
|
if (fileInfo == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -64,13 +63,13 @@ internal object RefreshQueue {
|
|||||||
val deletedChildren = listDifference(oldChildren, newChildren)
|
val deletedChildren = listDifference(oldChildren, newChildren)
|
||||||
val commonChildren = listIntersection(oldChildren, newChildren)
|
val commonChildren = listIntersection(oldChildren, newChildren)
|
||||||
|
|
||||||
addedChildren.foreach{ addRecursively(it) }
|
addedChildren.forEach{ addRecursively(it) }
|
||||||
deletedChildren.foreach{ deleteRecursively(it) }
|
deletedChildren.forEach{ deleteRecursively(it) }
|
||||||
|
|
||||||
fileInfo.children.clear()
|
fileInfo.children.clear()
|
||||||
fileInfo.children.addAll(newChildren)
|
fileInfo.children.addAll(newChildren)
|
||||||
|
|
||||||
commonChildren.foreach{ refreshFile(it) }
|
commonChildren.forEach{ refreshFile(it) }
|
||||||
} else {
|
} else {
|
||||||
val newModificationTime = file.modificationTime()
|
val newModificationTime = file.modificationTime()
|
||||||
if (fileInfo.lastModified != newModificationTime) {
|
if (fileInfo.lastModified != newModificationTime) {
|
||||||
@@ -83,21 +82,21 @@ internal object RefreshQueue {
|
|||||||
|
|
||||||
/* Adds file to file system recursively, notifying listeners */
|
/* Adds file to file system recursively, notifying listeners */
|
||||||
private fun addRecursively(file : VirtualFile) {
|
private fun addRecursively(file : VirtualFile) {
|
||||||
assert(FileSystem.fileToInfo[file] == null)
|
require(FileSystem.fileToInfo[file] == null)
|
||||||
|
|
||||||
val fileInfo = VirtualFileInfo(file)
|
val fileInfo = VirtualFileInfo(file)
|
||||||
|
|
||||||
FileSystem.fileToInfo[file.path] = fileInfo
|
FileSystem.fileToInfo[file.path] = fileInfo
|
||||||
FileSystem.notifyEventHappened(VirtualFileCreateEvent(file))
|
FileSystem.notifyEventHappened(VirtualFileCreateEvent(file))
|
||||||
|
|
||||||
fileInfo.children.foreach{ addRecursively(it) }
|
fileInfo.children.forEach{ addRecursively(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deletes file from file system recursively, notifying listeners */
|
/* Deletes file from file system recursively, notifying listeners */
|
||||||
private fun deleteRecursively(file : VirtualFile) {
|
private fun deleteRecursively(file : VirtualFile) {
|
||||||
val fileInfoMaybe : VirtualFileInfo? = FileSystem.fileToInfo[file.path]
|
val fileInfoMaybe : VirtualFileInfo? = FileSystem.fileToInfo[file.path]
|
||||||
val fileInfo = fileInfoMaybe.sure()
|
val fileInfo = fileInfoMaybe.sure()
|
||||||
fileInfo.children.foreach{ deleteRecursively(it) }
|
fileInfo.children.forEach{ deleteRecursively(it) }
|
||||||
FileSystem.notifyEventHappened(VirtualFileDeletedEvent(file))
|
FileSystem.notifyEventHappened(VirtualFileDeletedEvent(file))
|
||||||
FileSystem.fileToInfo.remove(file)
|
FileSystem.fileToInfo.remove(file)
|
||||||
}
|
}
|
||||||
@@ -115,7 +114,7 @@ internal object RefreshQueue {
|
|||||||
public fun scheduleRefresh(vararg files : VirtualFile) {
|
public fun scheduleRefresh(vararg files : VirtualFile) {
|
||||||
// FIXME This could be written more concise, using map() & toList() (KT-1164 & KT-1172)
|
// FIXME This could be written more concise, using map() & toList() (KT-1164 & KT-1172)
|
||||||
val filesList = ArrayList<VirtualFile>()
|
val filesList = ArrayList<VirtualFile>()
|
||||||
files.foreach{ filesList.add(it) }
|
files.forEach{ filesList.add(it) }
|
||||||
taskQueue.put(filesList)
|
taskQueue.put(filesList)
|
||||||
|
|
||||||
// taskQueue.put(ArrayList<VirtualFile>(files.map{ it }))
|
// taskQueue.put(ArrayList<VirtualFile>(files.map{ it }))
|
||||||
|
|||||||
@@ -63,38 +63,38 @@ public abstract class VirtualFile(public val path : String) {
|
|||||||
* Type of virtual file which corresponds to real file in file system of OS.
|
* Type of virtual file which corresponds to real file in file system of OS.
|
||||||
*/
|
*/
|
||||||
public class PhysicalVirtualFile(path : String) : VirtualFile(path) {
|
public class PhysicalVirtualFile(path : String) : VirtualFile(path) {
|
||||||
override fun kind() : String = "Physical"
|
override public fun kind() : String = "Physical"
|
||||||
|
|
||||||
private val ioFile : File
|
private val ioFile : File
|
||||||
get() = File(this.path.toSystemDependentPath())
|
get() = File(this.path.toSystemDependentPath())
|
||||||
|
|
||||||
override fun exists(): Boolean {
|
override public fun exists(): Boolean {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return ioFile.exists()
|
return ioFile.exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun size(): Long {
|
override public fun size(): Long {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return ioFile.length()
|
return ioFile.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun modificationTime(): Long {
|
override public fun modificationTime(): Long {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return ioFile.lastModified()
|
return ioFile.lastModified()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isDirectory(): Boolean {
|
override public fun isDirectory(): Boolean {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return ioFile.isDirectory()
|
return ioFile.isDirectory()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun children(): List<VirtualFile> {
|
override public fun children(): List<VirtualFile> {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return (ioFile.listFiles() ?: Array<File>(0)).
|
return (ioFile.listFiles() ?: array<File?>()).
|
||||||
map{ FileSystem.getFileByIoFile(it.sure()) }?.toList()
|
map{ FileSystem.getFileByIoFile(it.sure()) }?.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openInputStream(): InputStream {
|
override public fun openInputStream(): InputStream {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
if (isDirectory()) {
|
if (isDirectory()) {
|
||||||
throw IllegalArgumentException("Can't open directory for reading");
|
throw IllegalArgumentException("Can't open directory for reading");
|
||||||
@@ -117,47 +117,47 @@ private fun String.toSystemIndependentPath() : String {
|
|||||||
* InputStream wrapper which checks that file system read lock is acquired on each operation.
|
* InputStream wrapper which checks that file system read lock is acquired on each operation.
|
||||||
*/
|
*/
|
||||||
private class CheckedInputStream(private val wrapped : InputStream) : InputStream() {
|
private class CheckedInputStream(private val wrapped : InputStream) : InputStream() {
|
||||||
override fun read(): Int {
|
override public fun read(): Int {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.read()
|
return wrapped.read()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(b: ByteArray?, off: Int, len: Int) : Int {
|
override public fun read(b: ByteArray?, off: Int, len: Int) : Int {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.read(b, off, len)
|
return wrapped.read(b, off, len)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun markSupported(): Boolean {
|
override public fun markSupported(): Boolean {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.markSupported()
|
return wrapped.markSupported()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun skip(n: Long): Long {
|
override public fun skip(n: Long): Long {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.skip(n)
|
return wrapped.skip(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override public fun close() {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.close()
|
return wrapped.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mark(readlimit: Int) {
|
override public fun mark(readlimit: Int) {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.mark(readlimit)
|
return wrapped.mark(readlimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(b: ByteArray?): Int {
|
override public fun read(b: ByteArray?): Int {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.read(b)
|
return wrapped.read(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reset() {
|
override public fun reset() {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.reset()
|
return wrapped.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun available(): Int {
|
override public fun available(): Int {
|
||||||
FileSystem.assertCanRead()
|
FileSystem.assertCanRead()
|
||||||
return wrapped.available()
|
return wrapped.available()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ public trait VirtualFileListener : java.util.EventListener {
|
|||||||
fun eventHappened(val event : VirtualFileEvent)
|
fun eventHappened(val event : VirtualFileEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME using this wrapper because of codegen bug KT-1737, should be replaced with
|
||||||
|
private class SimpleVirtualFileListener(val listenerFunction : (VirtualFileEvent)->Unit) : VirtualFileListener {
|
||||||
|
override fun eventHappened(event : VirtualFileEvent) {
|
||||||
|
val f = listenerFunction // FIXME saving to local variable because of the bug in codegen (KT-1739)
|
||||||
|
f(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base type of virtual file events
|
* Base type of virtual file events
|
||||||
* @property file affected by event
|
* @property file affected by event
|
||||||
@@ -18,7 +26,7 @@ public abstract class VirtualFileEvent(val file : VirtualFile) : Object() {
|
|||||||
* Event of creating file
|
* Event of creating file
|
||||||
*/
|
*/
|
||||||
public class VirtualFileCreateEvent(file : VirtualFile) : VirtualFileEvent(file) {
|
public class VirtualFileCreateEvent(file : VirtualFile) : VirtualFileEvent(file) {
|
||||||
override fun toString(): String? {
|
override public fun toString(): String? {
|
||||||
return "created ${file}"
|
return "created ${file}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,7 +35,7 @@ public class VirtualFileCreateEvent(file : VirtualFile) : VirtualFileEvent(file)
|
|||||||
* Event of deleting file
|
* Event of deleting file
|
||||||
*/
|
*/
|
||||||
public class VirtualFileDeletedEvent(file : VirtualFile) : VirtualFileEvent(file) {
|
public class VirtualFileDeletedEvent(file : VirtualFile) : VirtualFileEvent(file) {
|
||||||
override fun toString(): String? {
|
override public fun toString(): String? {
|
||||||
return "deleted ${file}"
|
return "deleted ${file}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +44,7 @@ public class VirtualFileDeletedEvent(file : VirtualFile) : VirtualFileEvent(file
|
|||||||
* Event of changing file contents
|
* Event of changing file contents
|
||||||
*/
|
*/
|
||||||
public class VirtualFileChangedEvent(file : VirtualFile) : VirtualFileEvent(file) {
|
public class VirtualFileChangedEvent(file : VirtualFile) : VirtualFileEvent(file) {
|
||||||
override fun toString(): String? {
|
override public fun toString(): String? {
|
||||||
return "changed ${file}"
|
return "changed ${file}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user