@@ -17,10 +17,10 @@ import {
1717 classNameRegex ,
1818 compileErrorMsg ,
1919 cspAppsForUri ,
20- CurrentBinaryFile ,
2120 currentFile ,
2221 currentFileFromContent ,
2322 CurrentTextFile ,
23+ EitherCurrentFile ,
2424 exportedUris ,
2525 getWsFolder ,
2626 handleError ,
@@ -57,7 +57,7 @@ async function compileFlags(): Promise<string> {
5757 * @param force If passed true, use server mtime.
5858 * @return mtime timestamp or -1.
5959 */
60- export async function checkChangedOnServer ( file : CurrentTextFile | CurrentBinaryFile , force = false ) : Promise < number > {
60+ export async function checkChangedOnServer ( file : EitherCurrentFile , force = false ) : Promise < number > {
6161 if ( ! file || ! file . uri || schemas . includes ( file . uri . scheme ) ) {
6262 return - 1 ;
6363 }
@@ -88,7 +88,7 @@ export async function checkChangedOnServer(file: CurrentTextFile | CurrentBinary
8888}
8989
9090export async function importFile (
91- file : CurrentTextFile | CurrentBinaryFile ,
91+ file : EitherCurrentFile ,
9292 ignoreConflict ?: boolean ,
9393 skipDeplCheck = false
9494) : Promise < any > {
@@ -213,61 +213,79 @@ function updateOthers(others: string[], baseUri: vscode.Uri) {
213213 } ) ;
214214}
215215
216- export async function loadChanges ( files : ( CurrentTextFile | CurrentBinaryFile ) [ ] ) : Promise < any > {
217- if ( ! files . length ) {
218- return ;
219- }
216+ /**
217+ * Reload the contents of `files` from the server. This will also a trigger a
218+ * refresh of in-memory copies of "other" documents related to `files`. Files
219+ * in the `onlyUpdateOthersFiles` array will not have their contents reloaded.
220+ * Only their "other" documents will be refreshed.
221+ */
222+ export async function loadChanges (
223+ files : EitherCurrentFile [ ] ,
224+ onlyUpdateOthersFiles : EitherCurrentFile [ ] = [ ]
225+ ) : Promise < void > {
226+ if ( ! files ?. length ) return ;
220227 const api = new AtelierAPI ( files [ 0 ] . uri ) ;
221228 // Use allSettled so we attempt to load changes for all files, even if some fail
222- return api . actionIndex ( files . map ( ( f ) => f . name ) ) . then ( ( data ) =>
223- Promise . allSettled (
224- data . result . content . map ( async ( doc ) => {
225- if ( doc . status . length ) return ;
226- const file = files . find ( ( f ) => f . name == doc . name ) ;
227- const mtime = Number ( new Date ( doc . ts + "Z" ) ) ;
228- workspaceState . update ( `${ file . uniqueId } :mtime` , mtime > 0 ? mtime : undefined ) ;
229- if ( notIsfs ( file . uri ) ) {
230- const content = await api . getDoc ( file . name , file . uri ) . then ( ( data ) => data . result . content ) ;
231- exportedUris . add ( file . uri . toString ( ) ) ; // Set optimistically
232- await vscode . workspace . fs
233- . writeFile (
234- file . uri ,
235- Buffer . isBuffer ( content )
236- ? content
237- : new TextEncoder ( ) . encode (
238- content . join (
239- ( ( < CurrentTextFile > file ) ?. eol ?? vscode . EndOfLine . LF ) == vscode . EndOfLine . CRLF ? "\r\n" : "\n"
240- )
241- )
242- )
243- . then ( undefined , ( e ) => {
244- // Save failed, so remove this URI from the set
245- exportedUris . delete ( file . uri . toString ( ) ) ;
246- // Re-throw the error
247- throw e ;
248- } ) ;
249- if ( isClassOrRtn ( file . uri ) ) {
250- // Update the document index
251- updateIndexForDocument ( file . uri , undefined , undefined , content ) ;
229+ await api
230+ . actionIndex ( Array . from ( new Set ( files . map ( ( f ) => f . name ) . concat ( onlyUpdateOthersFiles . map ( ( f ) => f . name ) ) ) ) )
231+ . then ( ( data ) =>
232+ Promise . allSettled (
233+ data . result . content . map ( async ( doc ) => {
234+ if ( doc . status . length ) return ;
235+ let file = files . find ( ( f ) => f . name == doc . name ) ;
236+ if ( file ) {
237+ // This is a file that requires a content reload
238+ if ( notIsfs ( file . uri ) ) {
239+ const mtime = Number ( new Date ( doc . ts + "Z" ) ) ;
240+ workspaceState . update ( `${ file . uniqueId } :mtime` , mtime > 0 ? mtime : undefined ) ;
241+ const content = await api . getDoc ( file . name , file . uri ) . then ( ( data ) => data . result . content ) ;
242+ exportedUris . add ( file . uri . toString ( ) ) ; // Set optimistically
243+ await vscode . workspace . fs
244+ . writeFile (
245+ file . uri ,
246+ Buffer . isBuffer ( content )
247+ ? content
248+ : new TextEncoder ( ) . encode (
249+ content . join (
250+ ( ( < CurrentTextFile > file ) ?. eol ?? vscode . EndOfLine . LF ) == vscode . EndOfLine . CRLF ? "\r\n" : "\n"
251+ )
252+ )
253+ )
254+ . then ( undefined , ( e ) => {
255+ // Save failed, so remove this URI from the set
256+ exportedUris . delete ( file . uri . toString ( ) ) ;
257+ // Re-throw the error
258+ throw e ;
259+ } ) ;
260+ if ( isClassOrRtn ( file . uri ) ) {
261+ // Update the document index
262+ updateIndexForDocument ( file . uri , undefined , undefined , content ) ;
263+ }
264+ } else {
265+ fileSystemProvider . fireFileChanged ( file . uri ) ;
266+ }
267+ } else {
268+ // The contents of this file did not change, but its "other" documents still need to be updated
269+ file = onlyUpdateOthersFiles . find ( ( f ) => f . name == doc . name ) ;
270+ if ( ! file ) return ;
252271 }
253- } else if ( filesystemSchemas . includes ( file . uri . scheme ) ) {
254- fileSystemProvider . fireFileChanged ( file . uri ) ;
255- }
256- updateOthers ( doc . others , file . uri ) ;
257- } )
258- )
259- ) ;
272+ updateOthers ( doc . others , file . uri ) ;
273+ } )
274+ )
275+ ) ;
260276}
261277
262- export async function compile ( docs : ( CurrentTextFile | CurrentBinaryFile ) [ ] , flags ?: string ) : Promise < any > {
278+ export async function compile ( docs : EitherCurrentFile [ ] , flags ?: string ) : Promise < any > {
263279 const wsFolder = vscode . workspace . getWorkspaceFolder ( docs [ 0 ] . uri ) ;
264280 const conf = vscode . workspace . getConfiguration ( "objectscript" , wsFolder || docs [ 0 ] . uri ) ;
265281 flags = flags || conf . get ( "compileFlags" ) ;
266282 const api = new AtelierAPI ( docs [ 0 ] . uri ) ;
267283 const docNames = docs . map ( ( d ) => d . name ) ;
268- // Determine the line ending to use for other documents affected
284+ // Determine the line ending to use for documents affected
269285 // by compilation so we don't need to read their contents
270286 const eol = ( < CurrentTextFile > docs . find ( ( d ) => ( < CurrentTextFile > d ) ?. eol ) ) ?. eol ?? vscode . EndOfLine . LF ;
287+ const docsToReload : EitherCurrentFile [ ] = [ ] ;
288+ const docsToRefreshOthers : EitherCurrentFile [ ] = [ ...docs ] ;
271289 return vscode . window
272290 . withProgress (
273291 {
@@ -285,13 +303,18 @@ export async function compile(docs: (CurrentTextFile | CurrentBinaryFile)[], fla
285303 } else if ( ! conf . get ( "suppressCompileMessages" ) ) {
286304 vscode . window . showInformationMessage ( `${ info } Compilation succeeded.` , "Dismiss" ) ;
287305 }
288- if ( wsFolder ) {
289- // Make sure that we update the content for any
290- // other documents affected by this compilation
291- data . result . content . forEach ( ( f ) => {
292- if ( docNames . includes ( f . name ) ) return ;
306+ data . result . content . forEach ( ( f ) => {
307+ // Reload the contents of files that were changed by compilation
308+ if ( docNames . includes ( f . name ) ) {
309+ docsToReload . push (
310+ ...docsToRefreshOthers . splice (
311+ docsToRefreshOthers . findIndex ( ( d ) => d . name == f . name ) ,
312+ 1
313+ )
314+ ) ;
315+ } else if ( wsFolder ) {
293316 getUrisForDocument ( f . name , wsFolder ) . forEach ( ( u ) => {
294- docs . push ( {
317+ docsToReload . push ( {
295318 name : f . name ,
296319 uri : u ,
297320 uniqueId : `${ wsFolder . name } :${ f . name } ` ,
@@ -302,17 +325,14 @@ export async function compile(docs: (CurrentTextFile | CurrentBinaryFile)[], fla
302325 content : "" ,
303326 } ) ;
304327 } ) ;
305- } ) ;
306- }
307- return docs ;
308- } )
309- . catch ( ( ) => {
310- compileErrorMsg ( conf ) ;
311- // Always fetch server changes, even when compile failed or got cancelled
312- return docs ;
328+ }
329+ } ) ;
313330 } )
331+ . catch ( ( ) => compileErrorMsg ( conf ) )
314332 )
315- . then ( loadChanges ) ;
333+ . then ( ( ) => {
334+ return loadChanges ( docsToReload , docsToRefreshOthers ) ;
335+ } ) ;
316336}
317337
318338export async function importAndCompile (
@@ -429,7 +449,7 @@ export async function namespaceCompile(askFlags = false): Promise<any> {
429449}
430450
431451async function importFiles ( files : vscode . Uri [ ] , noCompile = false ) {
432- const toCompile : ( CurrentTextFile | CurrentBinaryFile ) [ ] = [ ] ;
452+ const toCompile : EitherCurrentFile [ ] = [ ] ;
433453 const rateLimiter = new RateLimiter ( 50 ) ;
434454 await Promise . allSettled < void > (
435455 files . map ( ( uri ) =>
0 commit comments