@@ -6,7 +6,8 @@ import { Directory } from "./Directory";
66import { File } from "./File" ;
77import { fireOtherStudioAction , OtherStudioAction } from "../../commands/studio" ;
88import { StudioOpenDialog } from "../../queries" ;
9- import { redirectDotvscodeRoot } from "../../utils/index" ;
9+ import { redirectDotvscodeRoot , workspaceFolderOfUri } from "../../utils/index" ;
10+ import { workspaceState } from "../../extension" ;
1011
1112declare function setTimeout ( callback : ( ...args : any [ ] ) => void , ms : number , ...args : any [ ] ) : NodeJS . Timeout ;
1213
@@ -146,7 +147,12 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
146147 }
147148
148149 public async readFile ( uri : vscode . Uri ) : Promise < Uint8Array > {
149- return this . _lookupAsFile ( uri ) . then ( ( file : File ) => file . data ) ;
150+ return this . _lookupAsFile ( uri ) . then ( ( file : File ) => {
151+ // Update cache entry
152+ const uniqueId = `${ workspaceFolderOfUri ( uri ) } :${ file . fileName } ` ;
153+ workspaceState . update ( `${ uniqueId } :mtime` , file . mtime ) ;
154+ return file . data ;
155+ } ) ;
150156 }
151157
152158 private generateFileContent ( fileName : string , content : Buffer ) : { content : string [ ] ; enc : boolean } {
@@ -197,12 +203,16 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
197203 // The actual writing is done by our workspace.onDidSaveTextDocument handler.
198204 // But first check a case for which we should fail the write and leave the document dirty if changed.
199205 if ( fileName . split ( "." ) . pop ( ) . toLowerCase ( ) === "cls" ) {
200- return api . actionIndex ( [ fileName ] ) . then ( ( result ) => {
206+ api . actionIndex ( [ fileName ] ) . then ( ( result ) => {
201207 if ( result . result . content [ 0 ] . content . depl ) {
202208 throw new Error ( "Cannot overwrite a deployed class" ) ;
203209 }
204210 } ) ;
205211 }
212+ // Set a -1 mtime cache entry so the actual write by the workspace.onDidSaveTextDocument handler always overwrites.
213+ // By the time we get here VS Code's built-in conflict resolution mechanism will already have interacted with the user.
214+ const uniqueId = `${ workspaceFolderOfUri ( uri ) } :${ fileName } ` ;
215+ workspaceState . update ( `${ uniqueId } :mtime` , - 1 ) ;
206216 return ;
207217 } ,
208218 ( error ) => {
@@ -307,8 +317,12 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
307317 } else {
308318 throw vscode . FileSystemError . FileNotFound ( uri ) ;
309319 }
320+ } else if ( child instanceof File ) {
321+ // Return cached copy unless changed, in which case return updated one
322+ return this . _lookupAsFile ( uri , child ) ;
323+ } else {
324+ entry = child ;
310325 }
311- entry = child ;
312326 }
313327 return entry ;
314328 }
@@ -325,8 +339,8 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
325339 throw vscode . FileSystemError . FileNotADirectory ( uri ) ;
326340 }
327341
328- // Fetch from server and cache it
329- private async _lookupAsFile ( uri : vscode . Uri ) : Promise < File > {
342+ // Fetch from server and cache it, optionally the passed cached copy if unchanged on server
343+ private async _lookupAsFile ( uri : vscode . Uri , cachedFile ?: File ) : Promise < File > {
330344 uri = redirectDotvscodeRoot ( uri ) ;
331345 if ( uri . path . startsWith ( "/." ) ) {
332346 throw vscode . FileSystemError . NoPermissions ( "dot-folders not supported by server" ) ;
@@ -338,7 +352,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
338352 const name = path . basename ( uri . path ) ;
339353 const api = new AtelierAPI ( uri ) ;
340354 return api
341- . getDoc ( fileName )
355+ . getDoc ( fileName , undefined , cachedFile ?. mtime )
342356 . then ( ( data ) => data . result )
343357 . then ( ( result ) => {
344358 const fileSplit = fileName . split ( "." ) ;
@@ -373,6 +387,9 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
373387 } )
374388 )
375389 . catch ( ( error ) => {
390+ if ( error ?. statusCode === 304 && cachedFile ) {
391+ return cachedFile ;
392+ }
376393 throw vscode . FileSystemError . FileNotFound ( uri ) ;
377394 } ) ;
378395 }
0 commit comments