chore(vscode): update to 1.53.2
These conflicts will be resolved in the following commits. We do it this way so that PR review is possible.
This commit is contained in:
@ -7,7 +7,7 @@ import {
|
||||
Connection, TextDocuments, InitializeParams, InitializeResult, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, DocumentSelector, TextDocumentPositionParams, ServerCapabilities,
|
||||
ConfigurationRequest, ConfigurationParams, DidChangeWorkspaceFoldersNotification,
|
||||
DocumentColorRequest, ColorPresentationRequest, TextDocumentSyncKind, NotificationType
|
||||
DocumentColorRequest, ColorPresentationRequest, TextDocumentSyncKind, NotificationType, RequestType0
|
||||
} from 'vscode-languageserver';
|
||||
import {
|
||||
getLanguageModes, LanguageModes, Settings, TextDocument, Position, Diagnostic, WorkspaceFolder, ColorInformation,
|
||||
@ -31,10 +31,7 @@ namespace CustomDataChangedNotification {
|
||||
}
|
||||
|
||||
namespace TagCloseRequest {
|
||||
export const type: RequestType<TextDocumentPositionParams, string | null, any, any> = new RequestType('html/tag');
|
||||
}
|
||||
namespace LinkedEditingRequest {
|
||||
export const type: RequestType<TextDocumentPositionParams, Range[] | null, any, any> = new RequestType('html/linkedEditing');
|
||||
export const type: RequestType<TextDocumentPositionParams, string | null, any> = new RequestType('html/tag');
|
||||
}
|
||||
|
||||
// experimental: semantic tokens
|
||||
@ -43,10 +40,10 @@ interface SemanticTokenParams {
|
||||
ranges?: Range[];
|
||||
}
|
||||
namespace SemanticTokenRequest {
|
||||
export const type: RequestType<SemanticTokenParams, number[] | null, any, any> = new RequestType('html/semanticTokens');
|
||||
export const type: RequestType<SemanticTokenParams, number[] | null, any> = new RequestType('html/semanticTokens');
|
||||
}
|
||||
namespace SemanticTokenLegendRequest {
|
||||
export const type: RequestType<void, { types: string[]; modifiers: string[] } | null, any, any> = new RequestType('html/semanticTokenLegend');
|
||||
export const type: RequestType0<{ types: string[]; modifiers: string[] } | null, any> = new RequestType0('html/semanticTokenLegend');
|
||||
}
|
||||
|
||||
export interface RuntimeEnvironment {
|
||||
@ -164,7 +161,8 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
colorProvider: {},
|
||||
foldingRangeProvider: true,
|
||||
selectionRangeProvider: true,
|
||||
renameProvider: true
|
||||
renameProvider: true,
|
||||
linkedEditingRangeProvider: true
|
||||
};
|
||||
return { capabilities };
|
||||
});
|
||||
@ -501,24 +499,28 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
const position: Position = params.position;
|
||||
|
||||
if (document) {
|
||||
const htmlMode = languageModes.getMode('html');
|
||||
if (htmlMode && htmlMode.doRename) {
|
||||
return htmlMode.doRename(document, position, params.newName);
|
||||
const mode = languageModes.getModeAtPosition(document, params.position);
|
||||
|
||||
if (mode && mode.doRename) {
|
||||
return mode.doRename(document, position, params.newName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, null, `Error while computing rename for ${params.textDocument.uri}`, token);
|
||||
});
|
||||
|
||||
connection.onRequest(LinkedEditingRequest.type, (params, token) => {
|
||||
return runSafe(async () => {
|
||||
connection.languages.onLinkedEditingRange((params, token) => {
|
||||
return <any> /* todo remove when microsoft/vscode-languageserver-node#700 fixed */ runSafe(async () => {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
const pos = params.position;
|
||||
if (pos.character > 0) {
|
||||
const mode = languageModes.getModeAtPosition(document, Position.create(pos.line, pos.character - 1));
|
||||
if (mode && mode.doLinkedEditing) {
|
||||
return mode.doLinkedEditing(document, pos);
|
||||
const ranges = await mode.doLinkedEditing(document, pos);
|
||||
if (ranges) {
|
||||
return { ranges };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -544,7 +546,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
}, null, `Error while computing semantic tokens for ${params.textDocument.uri}`, token);
|
||||
});
|
||||
|
||||
connection.onRequest(SemanticTokenLegendRequest.type, (_params, token) => {
|
||||
connection.onRequest(SemanticTokenLegendRequest.type, token => {
|
||||
return runSafe(async () => {
|
||||
return getSemanticTokenProvider().legend;
|
||||
}, null, `Error while computing semantic tokens legend`, token);
|
||||
|
@ -188,6 +188,28 @@ export function getJavaScriptMode(documentRegions: LanguageModelCache<HTMLDocume
|
||||
}
|
||||
return null;
|
||||
},
|
||||
async doRename(document: TextDocument, position: Position, newName: string) {
|
||||
const jsDocument = jsDocuments.get(document);
|
||||
const jsLanguageService = await host.getLanguageService(jsDocument);
|
||||
const jsDocumentPosition = jsDocument.offsetAt(position);
|
||||
const { canRename } = jsLanguageService.getRenameInfo(jsDocument.uri, jsDocumentPosition);
|
||||
if (!canRename) {
|
||||
return null;
|
||||
}
|
||||
const renameInfos = jsLanguageService.findRenameLocations(jsDocument.uri, jsDocumentPosition, false, false);
|
||||
|
||||
const edits: TextEdit[] = [];
|
||||
renameInfos?.map(renameInfo => {
|
||||
edits.push({
|
||||
range: convertRange(jsDocument, renameInfo.textSpan),
|
||||
newText: newName,
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
changes: { [document.uri]: edits },
|
||||
};
|
||||
},
|
||||
async findDocumentHighlight(document: TextDocument, position: Position): Promise<DocumentHighlight[]> {
|
||||
const jsDocument = jsDocuments.get(document);
|
||||
const jsLanguageService = await host.getLanguageService(jsDocument);
|
||||
|
@ -45,7 +45,7 @@ export function newSemanticTokenProvider(languageModes: LanguageModes): Semantic
|
||||
}
|
||||
}
|
||||
}
|
||||
return encodeTokens(allTokens, ranges);
|
||||
return encodeTokens(allTokens, ranges, document);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -94,15 +94,13 @@ function applyModifiersMapping(tokens: SemanticTokenData[], modifiersMapping: nu
|
||||
}
|
||||
}
|
||||
|
||||
const fullRange = [Range.create(Position.create(0, 0), Position.create(Number.MAX_VALUE, 0))];
|
||||
|
||||
function encodeTokens(tokens: SemanticTokenData[], ranges?: Range[]): number[] {
|
||||
function encodeTokens(tokens: SemanticTokenData[], ranges: Range[] | undefined, document: TextDocument): number[] {
|
||||
|
||||
const resultTokens = tokens.sort((d1, d2) => d1.start.line - d2.start.line || d1.start.character - d2.start.character);
|
||||
if (ranges) {
|
||||
ranges = ranges.sort((d1, d2) => d1.start.line - d2.start.line || d1.start.character - d2.start.character);
|
||||
} else {
|
||||
ranges = fullRange;
|
||||
ranges = [Range.create(Position.create(0, 0), Position.create(document.lineCount, 0))];
|
||||
}
|
||||
|
||||
let rangeIndex = 0;
|
||||
|
@ -8,14 +8,14 @@ import { RequestType, Connection } from 'vscode-languageserver';
|
||||
import { RuntimeEnvironment } from './htmlServer';
|
||||
|
||||
export namespace FsContentRequest {
|
||||
export const type: RequestType<{ uri: string; encoding?: string; }, string, any, any> = new RequestType('fs/content');
|
||||
export const type: RequestType<{ uri: string; encoding?: string; }, string, any> = new RequestType('fs/content');
|
||||
}
|
||||
export namespace FsStatRequest {
|
||||
export const type: RequestType<string, FileStat, any, any> = new RequestType('fs/stat');
|
||||
export const type: RequestType<string, FileStat, any> = new RequestType('fs/stat');
|
||||
}
|
||||
|
||||
export namespace FsReadDirRequest {
|
||||
export const type: RequestType<string, [string, FileType][], any, any> = new RequestType('fs/readDir');
|
||||
export const type: RequestType<string, [string, FileType][], any> = new RequestType('fs/readDir');
|
||||
}
|
||||
|
||||
export enum FileType {
|
||||
|
@ -0,0 +1,205 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { WorkspaceEdit, TextDocument, getLanguageModes, ClientCapabilities } from '../modes/languageModes';
|
||||
import { getNodeFSRequestService } from '../node/nodeFs';
|
||||
|
||||
|
||||
async function testRename(value: string, newName: string, expectedDocContent: string): Promise<void> {
|
||||
const offset = value.indexOf('|');
|
||||
value = value.substr(0, offset) + value.substr(offset + 1);
|
||||
|
||||
const document = TextDocument.create('test://test/test.html', 'html', 0, value);
|
||||
const workspace = {
|
||||
settings: {},
|
||||
folders: [{ name: 'foo', uri: 'test://foo' }]
|
||||
};
|
||||
const languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST, getNodeFSRequestService());
|
||||
const javascriptMode = languageModes.getMode('javascript')
|
||||
const position = document.positionAt(offset);
|
||||
|
||||
if (javascriptMode) {
|
||||
const workspaceEdit: WorkspaceEdit | null = await javascriptMode.doRename!(document, position, newName);
|
||||
|
||||
if (!workspaceEdit || !workspaceEdit.changes) {
|
||||
assert.fail('No workspace edits');
|
||||
}
|
||||
|
||||
const edits = workspaceEdit.changes[document.uri.toString()];
|
||||
if (!edits) {
|
||||
assert.fail(`No edits for file at ${document.uri.toString()}`);
|
||||
}
|
||||
|
||||
const newDocContent = TextDocument.applyEdits(document, edits);
|
||||
assert.equal(newDocContent, expectedDocContent, `Expected: ${expectedDocContent}\nActual: ${newDocContent}`);
|
||||
} else {
|
||||
assert.fail('should have javascriptMode but no')
|
||||
}
|
||||
}
|
||||
|
||||
async function testNoRename(value: string, newName: string): Promise<void> {
|
||||
const offset = value.indexOf('|');
|
||||
value = value.substr(0, offset) + value.substr(offset + 1);
|
||||
|
||||
const document = TextDocument.create('test://test/test.html', 'html', 0, value);
|
||||
const workspace = {
|
||||
settings: {},
|
||||
folders: [{ name: 'foo', uri: 'test://foo' }]
|
||||
};
|
||||
const languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST, getNodeFSRequestService());
|
||||
const javascriptMode = languageModes.getMode('javascript')
|
||||
const position = document.positionAt(offset);
|
||||
|
||||
if (javascriptMode) {
|
||||
const workspaceEdit: WorkspaceEdit | null = await javascriptMode.doRename!(document, position, newName);
|
||||
|
||||
assert.ok(workspaceEdit?.changes === undefined, 'Should not rename but rename happened')
|
||||
} else {
|
||||
assert.fail('should have javascriptMode but no')
|
||||
}
|
||||
}
|
||||
|
||||
suite('HTML Javascript Rename', () => {
|
||||
test('Rename Variable', async () => {
|
||||
const input = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
'const |a = 2;',
|
||||
'const b = a + 2',
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
const output = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
'const h = 2;',
|
||||
'const b = h + 2',
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
await testRename(input.join('\n'), 'h', output.join('\n'))
|
||||
})
|
||||
|
||||
test('Rename Function', async () => {
|
||||
const input = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
`const name = 'cjg';`,
|
||||
'function |sayHello(name) {',
|
||||
`console.log('hello', name)`,
|
||||
'}',
|
||||
'sayHello(name)',
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
const output = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
`const name = 'cjg';`,
|
||||
'function sayName(name) {',
|
||||
`console.log('hello', name)`,
|
||||
'}',
|
||||
'sayName(name)',
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
await testRename(input.join('\n'), 'sayName', output.join('\n'))
|
||||
})
|
||||
|
||||
test('Rename Function Params', async () => {
|
||||
const input = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
`const name = 'cjg';`,
|
||||
'function sayHello(|name) {',
|
||||
`console.log('hello', name)`,
|
||||
'}',
|
||||
'sayHello(name)',
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
const output = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
`const name = 'cjg';`,
|
||||
'function sayHello(newName) {',
|
||||
`console.log('hello', newName)`,
|
||||
'}',
|
||||
'sayHello(name)',
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
await testRename(input.join('\n'), 'newName', output.join('\n'))
|
||||
})
|
||||
|
||||
test('Rename Class', async () => {
|
||||
const input = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
`class |Foo {}`,
|
||||
`const foo = new Foo()`,
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
const output = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
`class Bar {}`,
|
||||
`const foo = new Bar()`,
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
await testRename(input.join('\n'), 'Bar', output.join('\n'))
|
||||
})
|
||||
|
||||
test('Cannot Rename literal', async () => {
|
||||
const stringLiteralInput = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
`const name = |'cjg';`,
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
const numberLiteralInput = [
|
||||
'<html>',
|
||||
'<head>',
|
||||
'<script>',
|
||||
`const num = |2;`,
|
||||
'</script>',
|
||||
'</head>',
|
||||
'</html>'
|
||||
]
|
||||
|
||||
await testNoRename(stringLiteralInput.join('\n'), 'something')
|
||||
await testNoRename(numberLiteralInput.join('\n'), 'hhhh')
|
||||
})
|
||||
});
|
@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ResponseError, ErrorCodes, CancellationToken } from 'vscode-languageserver';
|
||||
import { ResponseError, CancellationToken, LSPErrorCodes } from 'vscode-languageserver';
|
||||
|
||||
export function formatError(message: string, err: any): string {
|
||||
if (err instanceof Error) {
|
||||
@ -41,5 +41,5 @@ export function runSafe<T>(func: () => Thenable<T>, errorVal: T, errorMessage: s
|
||||
|
||||
|
||||
function cancelValue<E>() {
|
||||
return new ResponseError<E>(ErrorCodes.RequestCancelled, 'Request cancelled');
|
||||
return new ResponseError<E>(LSPErrorCodes.RequestCancelled, 'Request cancelled');
|
||||
}
|
||||
|
Reference in New Issue
Block a user