提交 fe114f8f 编写于 作者: M Matt Bierner

Split toPath and normalizedPath

Break up the concept of normalizing a path and trying to get the on disk path of a resource. Needed for handling case insensitivity
上级 6e76f2fb
......@@ -119,7 +119,7 @@ async function goToProjectConfig(
return;
}
const file = client.normalizePath(resource);
const file = client.toPath(resource);
// TSServer errors when 'projectInfo' is invoked on a non js/ts file
if (!file || !clientHost.handles(resource)) {
vscode.window.showWarningMessage(
......
......@@ -41,7 +41,7 @@ export function activate(
void lazyClientHost.value;
context.subscriptions.push(new ManagedFileContextManager(resource => {
return lazyClientHost.value.serviceClient.normalizePath(resource);
return lazyClientHost.value.serviceClient.toPath(resource);
}));
return true;
}
......
......@@ -64,7 +64,7 @@ export abstract class TypeScriptBaseCodeLensProvider implements CodeLensProvider
}
async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
const filepath = this.client.normalizePath(document.uri);
const filepath = this.client.toPath(document.uri);
if (!filepath) {
return [];
}
......
......@@ -77,14 +77,9 @@ class SyncedBuffer {
}
public onContentChanged(events: TextDocumentContentChangeEvent[]): void {
const filePath = this.client.normalizePath(this.document.uri);
if (!filePath) {
return;
}
for (const { range, text } of events) {
const args: Proto.ChangeRequestArgs = {
file: filePath,
file: this.filepath,
line: range.start.line + 1,
offset: range.start.character + 1,
endLine: range.end.line + 1,
......@@ -166,7 +161,7 @@ export default class BufferSyncSupport {
this.diagnosticDelayer = new Delayer<any>(300);
this.syncedBuffers = new SyncedBufferMap(path => this.client.normalizePath(path));
this.syncedBuffers = new SyncedBufferMap(path => this.client.normalizedPath(path));
}
private readonly _onDelete = new EventEmitter<Uri>();
......@@ -203,7 +198,7 @@ export default class BufferSyncSupport {
return;
}
const resource = document.uri;
const filepath = this.client.normalizePath(resource);
const filepath = this.client.normalizedPath(resource);
if (!filepath) {
return;
}
......@@ -237,12 +232,14 @@ export default class BufferSyncSupport {
private onDidChangeTextDocument(e: TextDocumentChangeEvent): void {
const syncedBuffer = this.syncedBuffers.get(e.document.uri);
if (syncedBuffer) {
syncedBuffer.onContentChanged(e.contentChanges);
if (this.pendingGetErr) {
this.pendingGetErr.token.cancel();
this.pendingGetErr = undefined;
}
if (!syncedBuffer) {
return;
}
syncedBuffer.onContentChanged(e.contentChanges);
if (this.pendingGetErr) {
this.pendingGetErr.token.cancel();
this.pendingGetErr = undefined;
}
}
......@@ -265,7 +262,7 @@ export default class BufferSyncSupport {
}
for (const resource of handledResources) {
const file = this.client.normalizePath(resource);
const file = this.client.normalizedPath(resource);
if (file) {
this.pendingDiagnostics.set(file, Date.now());
}
......@@ -281,7 +278,7 @@ export default class BufferSyncSupport {
return;
}
const file = this.client.normalizePath(resource);
const file = this.client.normalizedPath(resource);
if (!file) {
return;
}
......@@ -299,7 +296,7 @@ export default class BufferSyncSupport {
}
public hasPendingDiagnostics(resource: Uri): boolean {
const file = this.client.normalizePath(resource);
const file = this.client.normalizedPath(resource);
return !file || this.pendingDiagnostics.has(file);
}
......
......@@ -275,7 +275,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider
});
}
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return [];
}
......@@ -332,7 +332,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider
return undefined;
}
const filepath = this.client.normalizePath(item.document.uri);
const filepath = this.client.toPath(item.document.uri);
if (!filepath) {
return undefined;
}
......
......@@ -20,7 +20,7 @@ export default class TypeScriptDefinitionProviderBase {
position: Position,
token: CancellationToken | boolean
): Promise<Location[] | undefined> {
const filepath = this.client.normalizePath(document.uri);
const filepath = this.client.toPath(document.uri);
if (!filepath) {
return undefined;
}
......@@ -30,7 +30,7 @@ export default class TypeScriptDefinitionProviderBase {
const response = await this.client.execute(definitionType, args, token);
const locations: Proto.FileSpan[] = (response && response.body) || [];
return locations.map(location =>
typeConverters.Location.fromTextSpan(this.client.asUrl(location.file), location));
typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location));
} catch {
return [];
}
......
......@@ -45,7 +45,7 @@ class DirectiveCommentCompletionProvider implements vscode.CompletionItemProvide
position: vscode.Position,
_token: vscode.CancellationToken
): vscode.CompletionItem[] {
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return [];
}
......
......@@ -20,7 +20,7 @@ class TypeScriptDocumentHighlightProvider implements vscode.DocumentHighlightPro
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.DocumentHighlight[]> {
const file = this.client.normalizePath(resource.uri);
const file = this.client.toPath(resource.uri);
if (!file) {
return [];
}
......
......@@ -36,7 +36,7 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider
private readonly client: ITypeScriptServiceClient) { }
public async provideDocumentSymbols(resource: vscode.TextDocument, token: vscode.CancellationToken): Promise<any> { // todo@joh `any[]` temporary hack to make typescript happy...
const filepath = this.client.normalizePath(resource.uri);
const filepath = this.client.toPath(resource.uri);
if (!filepath) {
return [];
}
......
......@@ -76,7 +76,7 @@ export default class FileConfigurationManager {
options: FormattingOptions,
token: CancellationToken | undefined
): Promise<void> {
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return;
}
......
......@@ -20,7 +20,7 @@ class TypeScriptFoldingProvider implements vscode.FoldingRangeProvider {
_context: vscode.FoldingContext,
token: vscode.CancellationToken
): Promise<vscode.FoldingRange[] | undefined> {
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return;
}
......
......@@ -51,7 +51,7 @@ class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEdit
options: vscode.FormattingOptions,
token: vscode.CancellationToken
): Promise<vscode.TextEdit[]> {
const absPath = this.client.normalizePath(document.uri);
const absPath = this.client.toPath(document.uri);
if (!absPath) {
return [];
}
......@@ -72,7 +72,7 @@ class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEdit
options: vscode.FormattingOptions,
token: vscode.CancellationToken
): Promise<vscode.TextEdit[]> {
const filepath = this.client.normalizePath(document.uri);
const filepath = this.client.toPath(document.uri);
if (!filepath) {
return [];
}
......
......@@ -21,7 +21,7 @@ class TypeScriptHoverProvider implements vscode.HoverProvider {
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.Hover | undefined> {
const filepath = this.client.normalizePath(document.uri);
const filepath = this.client.toPath(document.uri);
if (!filepath) {
return undefined;
}
......
......@@ -27,7 +27,7 @@ export default class TypeScriptImplementationsCodeLensProvider extends TypeScrip
const locations = response.body
.map(reference =>
// Only take first line on implementation: https://github.com/Microsoft/vscode/issues/23924
new vscode.Location(this.client.asUrl(reference.file),
new vscode.Location(this.client.toResource(reference.file),
reference.start.line === reference.end.line
? typeConverters.Range.fromTextSpan(reference)
: new vscode.Range(
......
......@@ -54,7 +54,7 @@ class JsDocCompletionProvider implements CompletionItemProvider {
position: Position,
token: CancellationToken
): Promise<CompletionItem[]> {
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return [];
}
......@@ -130,7 +130,7 @@ class TryCompleteJsDocCommand implements Command {
* if possible, otherwise falling back to a default comment format.
*/
public async execute(resource: Uri, start: Position): Promise<boolean> {
const file = this.client.normalizePath(resource);
const file = this.client.toPath(resource);
if (!file) {
return false;
}
......
......@@ -63,7 +63,7 @@ export class OrganizeImportsCodeActionProvider implements vscode.CodeActionProvi
_context: vscode.CodeActionContext,
token: vscode.CancellationToken
): vscode.CodeAction[] {
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return [];
}
......
......@@ -184,7 +184,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider {
return [];
}
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return [];
}
......
......@@ -122,7 +122,7 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider {
return undefined;
}
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return undefined;
}
......
......@@ -19,7 +19,7 @@ class TypeScriptReferenceSupport implements vscode.ReferenceProvider {
options: vscode.ReferenceContext,
token: vscode.CancellationToken
): Promise<vscode.Location[]> {
const filepath = this.client.normalizePath(document.uri);
const filepath = this.client.toPath(document.uri);
if (!filepath) {
return [];
}
......@@ -36,7 +36,7 @@ class TypeScriptReferenceSupport implements vscode.ReferenceProvider {
if (!options.includeDeclaration && has203Features && ref.isDefinition) {
continue;
}
const url = this.client.asUrl(ref.file);
const url = this.client.toResource(ref.file);
const location = typeConverters.Location.fromTextSpan(url, ref);
result.push(location);
}
......
......@@ -27,7 +27,7 @@ class TypeScriptReferencesCodeLensProvider extends TypeScriptBaseCodeLensProvide
const locations = response.body.refs
.map(reference =>
typeConverters.Location.fromTextSpan(this.client.asUrl(reference.file), reference))
typeConverters.Location.fromTextSpan(this.client.toResource(reference.file), reference))
.filter(location =>
// Exclude original definition from references
!(location.uri.toString() === codeLens.document.toString() &&
......
......@@ -20,7 +20,7 @@ class TypeScriptRenameProvider implements vscode.RenameProvider {
newName: string,
token: vscode.CancellationToken
): Promise<vscode.WorkspaceEdit | null> {
const file = this.client.normalizePath(document.uri);
const file = this.client.toPath(document.uri);
if (!file) {
return null;
}
......@@ -55,7 +55,7 @@ class TypeScriptRenameProvider implements vscode.RenameProvider {
) {
const result = new vscode.WorkspaceEdit();
for (const spanGroup of locations) {
const resource = this.client.asUrl(spanGroup.file);
const resource = this.client.toResource(spanGroup.file);
if (resource) {
for (const textSpan of spanGroup.locs) {
result.replace(resource, typeConverters.Range.fromTextSpan(textSpan), newName);
......
......@@ -22,7 +22,7 @@ class TypeScriptSignatureHelpProvider implements vscode.SignatureHelpProvider {
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.SignatureHelp | undefined> {
const filepath = this.client.normalizePath(document.uri);
const filepath = this.client.toPath(document.uri);
if (!filepath) {
return undefined;
}
......
......@@ -167,7 +167,7 @@ class TscTaskProvider implements vscode.TaskProvider {
if (editor) {
const document = editor.document;
if (document && (document.languageId === 'typescript' || document.languageId === 'typescriptreact')) {
return this.client.value.normalizePath(document.uri);
return this.client.value.toPath(document.uri);
}
}
return null;
......
......@@ -54,12 +54,12 @@ export class UpdateImportsOnFileRenameHandler {
return;
}
const newFile = this.client.normalizePath(newResource);
const newFile = this.client.toPath(newResource);
if (!newFile) {
return;
}
const oldFile = this.client.normalizePath(oldResource);
const oldFile = this.client.toPath(oldResource);
if (!oldFile) {
return;
}
......
......@@ -35,7 +35,7 @@ class TypeScriptWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvide
return [];
}
const filepath = this.client.normalizePath(uri);
const filepath = this.client.toPath(uri);
if (!filepath) {
return [];
}
......@@ -56,7 +56,7 @@ class TypeScriptWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvide
}
const label = TypeScriptWorkspaceSymbolProvider.getLabel(item);
result.push(new vscode.SymbolInformation(label, getSymbolKind(item), item.containerName || '',
typeConverters.Location.fromTextSpan(this.client.asUrl(item.file), item)));
typeConverters.Location.fromTextSpan(this.client.toResource(item.file), item)));
}
return result;
}
......
......@@ -89,7 +89,7 @@ export default class TypeScriptServiceClientHost {
}
}, null, this.disposables);
this.versionStatus = new VersionStatus(resource => this.client.normalizePath(resource));
this.versionStatus = new VersionStatus(resource => this.client.toPath(resource));
this.disposables.push(this.versionStatus);
this.typingsStatus = new TypingsStatus(this.client);
......@@ -211,12 +211,12 @@ export default class TypeScriptServiceClientHost {
return;
}
(this.findLanguage(this.client.asUrl(body.configFile))).then(language => {
(this.findLanguage(this.client.toResource(body.configFile))).then(language => {
if (!language) {
return;
}
if (body.diagnostics.length === 0) {
language.configFileDiagnosticsReceived(this.client.asUrl(body.configFile), []);
language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), []);
} else if (body.diagnostics.length >= 1) {
workspace.openTextDocument(Uri.file(body.configFile)).then((document) => {
let curly: [number, number, number] | undefined = undefined;
......@@ -246,10 +246,10 @@ export default class TypeScriptServiceClientHost {
}
if (diagnostic) {
diagnostic.source = language.diagnosticSource;
language.configFileDiagnosticsReceived(this.client.asUrl(body.configFile), [diagnostic]);
language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), [diagnostic]);
}
}, _error => {
language.configFileDiagnosticsReceived(this.client.asUrl(body.configFile), [new Diagnostic(new Range(0, 0, 0, 0), body.diagnostics[0].text)]);
language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), [new Diagnostic(new Range(0, 0, 0, 0), body.diagnostics[0].text)]);
});
}
});
......
......@@ -11,8 +11,25 @@ import { TypeScriptServiceConfiguration } from './utils/configuration';
import Logger from './utils/logger';
export interface ITypeScriptServiceClient {
normalizePath(resource: Uri): string | null;
asUrl(filepath: string): Uri;
/**
* Convert a resource (VS Code) to a normalized path (TypeScript).
*
* Does not try handling case insensitivity.
*/
normalizedPath(resource: Uri): string | null;
/**
* Map a resource to a normalized path
*
* This will attempt to handle case insensitivity.
*/
toPath(resource: Uri): string | null;
/**
* Convert a path to a resource.
*/
toResource(filepath: string): Uri;
getWorkspaceRootForResource(resource: Uri): string | undefined;
onTsServerStarted: Event<API>;
......
......@@ -618,7 +618,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
}
}
public normalizePath(resource: Uri): string | null {
public normalizedPath(resource: Uri): string | null {
if (this._apiVersion.gte(API.v213)) {
if (resource.scheme === fileSchemes.walkThroughSnippet || resource.scheme === fileSchemes.untitled) {
const dirName = path.dirname(resource.path);
......@@ -640,11 +640,15 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
return result.replace(new RegExp('\\' + this.pathSeparator, 'g'), '/');
}
public toPath(resource: Uri): string | null {
return this.normalizedPath(resource);
}
private get inMemoryResourcePrefix(): string {
return this._apiVersion.gte(API.v270) ? '^' : '';
}
public asUrl(filepath: string): Uri {
public toResource(filepath: string): Uri {
if (this._apiVersion.gte(API.v213)) {
if (filepath.startsWith(TypeScriptServiceClient.WALK_THROUGH_SNIPPET_SCHEME_COLON) || (filepath.startsWith(fileSchemes.untitled + ':'))
) {
......@@ -851,7 +855,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
if (diagnosticEvent.body && diagnosticEvent.body.diagnostics) {
this._onDiagnosticsReceived.fire({
kind: getDignosticsKind(event),
resource: this.asUrl(diagnosticEvent.body.file),
resource: this.toResource(diagnosticEvent.body.file),
diagnostics: diagnosticEvent.body.diagnostics
});
}
......
......@@ -57,7 +57,7 @@ export namespace WorkspaceEdit {
const workspaceEdit = new vscode.WorkspaceEdit();
for (const edit of edits) {
for (const textChange of edit.textChanges) {
workspaceEdit.replace(client.asUrl(edit.fileName),
workspaceEdit.replace(client.toResource(edit.fileName),
Range.fromTextSpan(textChange),
textChange.newText);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册