Skip to content

Commit

Permalink
backup
Browse files Browse the repository at this point in the history
  • Loading branch information
Loïc Mangeonjean committed Feb 27, 2024
1 parent 2317d58 commit ab37d54
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 25 deletions.
36 changes: 35 additions & 1 deletion src/customRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,32 @@ export interface GetTextDocumentParams {

export interface GetTextDocumentResult {
text: string
mtime?: number
}

export const getTextDocumentRequestType = new ProtocolRequestType<GetTextDocumentParams, GetTextDocumentResult, never, void, void>('textDocument/get')

export interface StatFileParams {
uri: string
}
export interface StatFileResult {
type: 'directory' | 'file'
size: number
name: string
mtime: number
}

export const getFileStatsRequestType = new ProtocolRequestType<StatFileParams, StatFileResult, never, void, void>('file/stats')

export interface ListFilesParams {
directory: string
}
export interface ListFilesResult {
files: string[]
}

export const listFileRequestType = new ProtocolRequestType<ListFilesParams, ListFilesResult, never, void, void>('file/list')

export function updateFile (uri: string, text: string, languageClient: LanguageClient): Promise<void> {
return languageClient.sendRequest(saveTextDocumentRequestType, {
textDocument: {
Expand All @@ -36,10 +58,22 @@ export function updateFile (uri: string, text: string, languageClient: LanguageC
})
}

export function getFile (uri: string, languageClient: LanguageClient): Promise<{ text: string }> {
export function getFileContent (uri: string, languageClient: LanguageClient): Promise<GetTextDocumentResult> {
return languageClient.sendRequest(getTextDocumentRequestType, {
textDocument: {
uri
}
})
}

export function getFileStats (uri: string, languageClient: LanguageClient): Promise<StatFileResult> {
return languageClient.sendRequest(getFileStatsRequestType, {
uri
})
}

export function listFiles (directory: string, languageClient: LanguageClient): Promise<ListFilesResult> {
return languageClient.sendRequest(listFileRequestType, {
directory
})
}
54 changes: 35 additions & 19 deletions src/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,24 @@ class InfrastructureTextFileSystemProvider implements IFileSystemProviderWithFil
constructor (private infrastructure: Infrastructure, private languageClientManager: LanguageClientManager) {
}

private cachedContent: Map<string, Promise<string | undefined>> = new Map()
private async getFileContent (resource: monaco.Uri): Promise<string | undefined> {
private isBlacklisted (resource: monaco.Uri) {
const REMOTE_FILE_BLACKLIST = ['.git/config', '.vscode', monaco.Uri.parse(this.infrastructure.rootUri).path]

const blacklisted = REMOTE_FILE_BLACKLIST.some(blacklisted => resource.path.endsWith(blacklisted))
if (blacklisted) {
return undefined
}
if (!this.cachedContent.has(resource.toString())) {
this.cachedContent.set(resource.toString(), this.infrastructure.getFileContent!(resource, this.languageClientManager))
}
return await this.cachedContent.get(resource.toString())
return blacklisted
}

async readFile (resource: monaco.Uri): Promise<Uint8Array> {
const content = await this.getFileContent(resource)
return encoder.encode(content)
if (this.isBlacklisted(resource)) {
throw FileSystemProviderError.create('Not allowed', FileSystemProviderErrorCode.NoPermissions)
}
try {
const file = await this.infrastructure.getFileContent!(resource, this.languageClientManager)

return encoder.encode(file)
} catch (err) {
throw FileSystemProviderError.create(err as Error, FileSystemProviderErrorCode.Unknown)
}
}

async writeFile (): Promise<void> {
Expand All @@ -116,13 +117,16 @@ class InfrastructureTextFileSystemProvider implements IFileSystemProviderWithFil

async stat (resource: monaco.Uri): Promise<IStat> {
try {
const content = await this.getFileContent(resource)
if (content != null) {
if (this.isBlacklisted(resource)) {
throw FileSystemProviderError.create('Not allowed', FileSystemProviderErrorCode.NoPermissions)
}
const fileStats = await this.infrastructure.getFileStats?.(resource, this.languageClientManager)
if (fileStats != null) {
return {
type: FileType.File,
size: encoder.encode(content).length,
mtime: Date.now(),
ctime: Date.now()
type: fileStats.type === 'directory' ? FileType.Directory : FileType.File,
size: fileStats.size,
mtime: fileStats.mtime,
ctime: 0
}
}
} catch (err) {
Expand All @@ -134,8 +138,20 @@ class InfrastructureTextFileSystemProvider implements IFileSystemProviderWithFil
async mkdir (): Promise<void> {
}

async readdir () {
return []
async readdir (resource: monaco.Uri) {
const result = await this.infrastructure.listFiles?.(resource, this.languageClientManager)
if (result == null) {
return []
}
return result.map(file => {
let name = file
let type = FileType.File
if (file.endsWith('/')) {
type = FileType.Directory
name = file.slice(0, -1)
}
return <[string, FileType]>[name, type]
})
}

delete (): Promise<void> {
Expand Down
28 changes: 26 additions & 2 deletions src/infrastructure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MessageTransports } from 'vscode-languageclient'
import * as monaco from 'monaco-editor'
import * as vscode from 'vscode'
import { LSPAny } from 'vscode-languageserver-protocol'
import { getFile, updateFile } from './customRequests'
import { StatFileResult, getFileContent, getFileStats, listFiles, updateFile } from './customRequests'
import { LanguageClientManager } from './languageClient'
import { LanguageClientId, LanguageClientOptions } from './languageClientOptions'

Expand Down Expand Up @@ -41,6 +41,18 @@ export interface Infrastructure {
* @param languageClient The languageclient we're trying to get the file from
*/
getFileContent? (resource: monaco.Uri, languageClient: LanguageClientManager): Promise<string | undefined>
/**
* List the files of a directory
* @param resource the Uri of the directory
* @param languageClient The languageclient we're trying to get the file from
*/
getFileStats? (resource: monaco.Uri, languageClient: LanguageClientManager): Promise<StatFileResult>
/**
* List the files of a directory
* @param resource the Uri of the directory
* @param languageClient The languageclient we're trying to get the file from
*/
listFiles? (resource: monaco.Uri, languageClient: LanguageClientManager): Promise<string[]>

/**
* Open a connection to the language server
Expand Down Expand Up @@ -114,12 +126,24 @@ export abstract class CodinGameInfrastructure implements Infrastructure {

public async getFileContent (resource: monaco.Uri, languageClient: LanguageClientManager): Promise<string | undefined> {
try {
return (await getFile(resource.toString(true), languageClient)).text
return (await getFileContent(resource.toString(true), languageClient)).text
} catch (error) {
return undefined
}
}

public async getFileStats (directory: monaco.Uri, languageClient: LanguageClientManager): Promise<StatFileResult> {
return (await getFileStats(directory.toString(true), languageClient))
}

public async listFiles (directory: monaco.Uri, languageClient: LanguageClientManager): Promise<string[]> {
try {
return (await listFiles(directory.toString(true), languageClient)).files
} catch (error) {
return []
}
}

/**
* A function which returns a valid JWT token to use to connect to the server
*/
Expand Down
16 changes: 15 additions & 1 deletion src/tests/infrastructure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createModelReference } from 'vscode/monaco'
import * as vscode from 'vscode'
import { RegisteredFileSystemProvider, RegisteredMemoryFile, registerFileSystemOverlay } from '@codingame/monaco-vscode-files-service-override'
import pDefer, { TestInfrastructure, waitClientNotification, waitClientRequest } from './tools'
import { GetTextDocumentParams, getTextDocumentRequestType, GetTextDocumentResult, saveTextDocumentRequestType } from '../customRequests'
import { getFileStatsRequestType, GetTextDocumentParams, getTextDocumentRequestType, GetTextDocumentResult, saveTextDocumentRequestType, StatFileParams, StatFileResult } from '../customRequests'
import { createLanguageClientManager, LanguageClientManager, getLanguageClientOptions, StaticLanguageClientId } from '..'

async function initializeLanguageClientAndGetConnection (
Expand Down Expand Up @@ -182,6 +182,20 @@ async function testLanguageClient (
return editor
})

const [getFileStatsRequest, sendGetFileStatsRequestResponse] = await waitClientRequest<StatFileParams, StatFileResult, never>(handler => connection.onRequest(getFileStatsRequestType, handler))
expect(getFileStatsRequest).toEqual({
textDocument: {
uri: 'file:///tmp/project/src/main/Otherfile.java'
}
})

sendGetFileStatsRequestResponse({
mtime: 0,
name: 'Otherfile.java',
size: 50,
type: 'file'
})

const [getDocumentRequest, sendGetDocumentRequestResponse] = await waitClientRequest<GetTextDocumentParams, GetTextDocumentResult, never>(handler => connection.onRequest(getTextDocumentRequestType, handler))
expect(getDocumentRequest).toEqual({
textDocument: {
Expand Down
4 changes: 2 additions & 2 deletions src/tests/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from 'vscode-languageserver/lib/common/api'
import { monaco } from '@codingame/monaco-editor-wrapper'
import { MessageTransports } from 'vscode-languageclient'
import { getFile, updateFile } from '../customRequests'
import { getFileContent, updateFile } from '../customRequests'
import { Infrastructure, LanguageClientId, LanguageClientManager, LanguageClientOptions } from '../'

class PipedMessageReader extends AbstractMessageReader {
Expand Down Expand Up @@ -133,7 +133,7 @@ export class TestInfrastructure implements Infrastructure {
// use same method as CodinGameInfrastructure to be able to simply catch it
async getFileContent (resource: Uri, languageClient: LanguageClientManager): Promise<string | undefined> {
try {
return (await getFile(resource.toString(true), languageClient)).text
return (await getFileContent(resource.toString(true), languageClient)).text
} catch (error) {
return undefined
}
Expand Down

0 comments on commit ab37d54

Please sign in to comment.