@@ -13,7 +13,14 @@ import {
1313 redirectDotvscodeRoot ,
1414 workspaceFolderOfUri ,
1515} from "../../utils/index" ;
16- import { config , FILESYSTEM_SCHEMA , intLangId , macLangId , workspaceState } from "../../extension" ;
16+ import {
17+ config ,
18+ FILESYSTEM_READONLY_SCHEMA ,
19+ FILESYSTEM_SCHEMA ,
20+ intLangId ,
21+ macLangId ,
22+ workspaceState ,
23+ } from "../../extension" ;
1724import { addIsfsFileToProject , modifyProject } from "../../commands/project" ;
1825import { DocumentContentProvider } from "../DocumentContentProvider" ;
1926import { Document , UserAction } from "../../api/atelier" ;
@@ -184,13 +191,55 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
184191 this . _fireSoon ( { type : vscode . FileChangeType . Changed , uri } ) ;
185192 }
186193
187- public stat ( uri : vscode . Uri ) : Promise < vscode . FileStat > {
194+ public async stat ( uri : vscode . Uri ) : Promise < vscode . FileStat > {
195+ let entryPromise : Promise < Entry > ;
196+ let result : Entry ;
188197 const redirectedUri = redirectDotvscodeRoot ( uri ) ;
189198 if ( redirectedUri . path !== uri . path ) {
190199 // When redirecting the /.vscode subtree we must fill in as-yet-unvisited folders to fix https://github.com/intersystems-community/vscode-objectscript/issues/1143
191- return this . _lookup ( redirectedUri , true ) ;
200+ entryPromise = this . _lookup ( redirectedUri , true ) ;
201+ } else {
202+ entryPromise = this . _lookup ( uri ) ;
203+ }
204+
205+ // If this is our readonly variant there's no point checking server-side whether the file sould be marked readonly
206+ if ( uri . scheme === FILESYSTEM_READONLY_SCHEMA ) {
207+ return entryPromise ;
208+ }
209+
210+ if ( entryPromise instanceof File ) {
211+ // previously resolved as a file
212+ result = entryPromise ;
213+ } else if ( entryPromise instanceof Promise && uri . path . split ( "/" ) . pop ( ) ?. split ( "." ) . length > 1 ) {
214+ // apparently a file, so resolve ahead of adding permissions
215+ result = await entryPromise ;
216+ } else {
217+ // otherwise return the promise
218+ return entryPromise ;
219+ }
220+
221+ //
222+ if ( result instanceof File ) {
223+ const api = new AtelierAPI ( uri ) ;
224+ const serverName = isCSPFile ( uri ) ? uri . path : uri . path . slice ( 1 ) . replace ( / \/ / g, "." ) ;
225+ if ( serverName . slice ( - 4 ) . toLowerCase ( ) == ".cls" ) {
226+ if ( await isClassDeployed ( serverName , api ) ) {
227+ result . permissions |= vscode . FilePermission . Readonly ;
228+ return result ;
229+ }
230+ }
231+
232+ // Does server-side source control report it as editable?
233+ if ( vscode . workspace . getConfiguration ( "objectscript.serverSourceControl" , uri ) ?. get ( "respectEditableStatus" ) ) {
234+ const query = "select * from %Atelier_v1_Utils.Extension_GetStatus(?)" ;
235+ const statusObj = await api . actionQuery ( query , [ serverName ] ) ;
236+ const docStatus = statusObj . result ?. content ?. pop ( ) ;
237+ if ( docStatus ) {
238+ result . permissions = docStatus . editable ? undefined : result . permissions | vscode . FilePermission . Readonly ;
239+ }
240+ }
192241 }
193- return this . _lookup ( uri ) ;
242+ return result ;
194243 }
195244
196245 public async readDirectory ( uri : vscode . Uri ) : Promise < [ string , vscode . FileType ] [ ] > {
0 commit comments