extHostTypeConverters.ts 17.4 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

import Severity from 'vs/base/common/severity';
8
import * as modes from 'vs/editor/common/modes';
9
import * as types from './extHostTypes';
10
import { Position as EditorPosition } from 'vs/platform/editor/common/editor';
A
Alex Dima 已提交
11
import { IDecorationOptions, EndOfLineSequence } from 'vs/editor/common/editorCommon';
J
Johannes Rieken 已提交
12
import * as vscode from 'vscode';
13
import URI from 'vs/base/common/uri';
J
Johannes Rieken 已提交
14
import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress';
15
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
16 17 18
import { IPosition } from 'vs/editor/common/core/position';
import { IRange } from 'vs/editor/common/core/range';
import { ISelection } from 'vs/editor/common/core/selection';
19
import * as htmlContent from 'vs/base/common/htmlContent';
E
Erich Gamma 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

export interface PositionLike {
	line: number;
	character: number;
}

export interface RangeLike {
	start: PositionLike;
	end: PositionLike;
}

export interface SelectionLike extends RangeLike {
	anchor: PositionLike;
	active: PositionLike;
}

36
export function toSelection(selection: ISelection): types.Selection {
37
	let { selectionStartLineNumber, selectionStartColumn, positionLineNumber, positionColumn } = selection;
38 39 40
	let start = new types.Position(selectionStartLineNumber - 1, selectionStartColumn - 1);
	let end = new types.Position(positionLineNumber - 1, positionColumn - 1);
	return new types.Selection(start, end);
E
Erich Gamma 已提交
41 42 43
}

export function fromSelection(selection: SelectionLike): ISelection {
44
	let { anchor, active } = selection;
E
Erich Gamma 已提交
45 46 47 48 49 50 51 52 53
	return {
		selectionStartLineNumber: anchor.line + 1,
		selectionStartColumn: anchor.character + 1,
		positionLineNumber: active.line + 1,
		positionColumn: active.character + 1
	};
}

export function fromRange(range: RangeLike): IRange {
J
Johannes Rieken 已提交
54 55 56
	if (!range) {
		return undefined;
	}
57
	let { start, end } = range;
E
Erich Gamma 已提交
58 59 60 61 62 63 64 65
	return {
		startLineNumber: start.line + 1,
		startColumn: start.character + 1,
		endLineNumber: end.line + 1,
		endColumn: end.character + 1
	};
}

66
export function toRange(range: IRange): types.Range {
J
Johannes Rieken 已提交
67 68 69
	if (!range) {
		return undefined;
	}
70
	let { startLineNumber, startColumn, endLineNumber, endColumn } = range;
71
	return new types.Range(startLineNumber - 1, startColumn - 1, endLineNumber - 1, endColumn - 1);
E
Erich Gamma 已提交
72 73
}

74 75
export function toPosition(position: IPosition): types.Position {
	return new types.Position(position.lineNumber - 1, position.column - 1);
E
Erich Gamma 已提交
76 77
}

78 79
export function fromPosition(position: types.Position): IPosition {
	return { lineNumber: position.line + 1, column: position.character + 1 };
80 81
}

E
Erich Gamma 已提交
82 83
export function fromDiagnosticSeverity(value: number): Severity {
	switch (value) {
84
		case types.DiagnosticSeverity.Error:
E
Erich Gamma 已提交
85
			return Severity.Error;
86
		case types.DiagnosticSeverity.Warning:
E
Erich Gamma 已提交
87
			return Severity.Warning;
88
		case types.DiagnosticSeverity.Information:
E
Erich Gamma 已提交
89
			return Severity.Info;
90
		case types.DiagnosticSeverity.Hint:
E
Erich Gamma 已提交
91 92 93 94 95
			return Severity.Ignore;
	}
	return Severity.Error;
}

96
export function toDiagnosticSeverty(value: Severity): types.DiagnosticSeverity {
E
Erich Gamma 已提交
97 98
	switch (value) {
		case Severity.Info:
99
			return types.DiagnosticSeverity.Information;
E
Erich Gamma 已提交
100
		case Severity.Warning:
101
			return types.DiagnosticSeverity.Warning;
E
Erich Gamma 已提交
102
		case Severity.Error:
103
			return types.DiagnosticSeverity.Error;
E
Erich Gamma 已提交
104
		case Severity.Ignore:
105
			return types.DiagnosticSeverity.Hint;
E
Erich Gamma 已提交
106
	}
107
	return types.DiagnosticSeverity.Error;
E
Erich Gamma 已提交
108 109 110
}

export function fromViewColumn(column?: vscode.ViewColumn): EditorPosition {
B
Benjamin Pasero 已提交
111
	let editorColumn = EditorPosition.ONE;
E
Erich Gamma 已提交
112
	if (typeof column !== 'number') {
B
Benjamin Pasero 已提交
113
		// stick with ONE
114
	} else if (column === <number>types.ViewColumn.Two) {
B
Benjamin Pasero 已提交
115
		editorColumn = EditorPosition.TWO;
116
	} else if (column === <number>types.ViewColumn.Three) {
B
Benjamin Pasero 已提交
117
		editorColumn = EditorPosition.THREE;
E
Erich Gamma 已提交
118 119 120 121
	}
	return editorColumn;
}

122 123
export function toViewColumn(position?: EditorPosition): vscode.ViewColumn {
	if (typeof position !== 'number') {
M
Matt Bierner 已提交
124
		return undefined;
125
	}
B
Benjamin Pasero 已提交
126
	if (position === EditorPosition.ONE) {
127
		return <number>types.ViewColumn.One;
B
Benjamin Pasero 已提交
128
	} else if (position === EditorPosition.TWO) {
129
		return <number>types.ViewColumn.Two;
B
Benjamin Pasero 已提交
130
	} else if (position === EditorPosition.THREE) {
131
		return <number>types.ViewColumn.Three;
132
	}
M
Matt Bierner 已提交
133
	return undefined;
134
}
E
Erich Gamma 已提交
135

M
Martin Aeschlimann 已提交
136
function isDecorationOptions(something: any): something is vscode.DecorationOptions {
137
	return (typeof something.range !== 'undefined');
E
Erich Gamma 已提交
138 139
}

140
function isDecorationOptionsArr(something: vscode.Range[] | vscode.DecorationOptions[]): something is vscode.DecorationOptions[] {
E
Erich Gamma 已提交
141 142 143
	if (something.length === 0) {
		return true;
	}
M
Martin Aeschlimann 已提交
144
	return isDecorationOptions(something[0]) ? true : false;
E
Erich Gamma 已提交
145 146
}

147 148 149 150 151 152
export namespace MarkdownString {

	export function fromMany(markup: (vscode.MarkdownString | vscode.MarkedString)[]): htmlContent.IMarkdownString[] {
		return markup.map(MarkdownString.from);
	}

J
Johannes Rieken 已提交
153 154 155 156 157 158 159 160 161 162 163
	interface Codeblock {
		language: string;
		value: string;
	}

	function isCodeblock(thing: any): thing is Codeblock {
		return typeof thing === 'object'
			&& typeof (<Codeblock>thing).language === 'string'
			&& typeof (<Codeblock>thing).value === 'string';
	}

164
	export function from(markup: vscode.MarkdownString | vscode.MarkedString): htmlContent.IMarkdownString {
J
Johannes Rieken 已提交
165 166 167 168
		if (isCodeblock(markup)) {
			const { language, value } = markup;
			return { value: '```' + language + '\n' + value + '\n```\n' };
		} else if (htmlContent.isMarkdownString(markup)) {
169
			return markup;
J
Johannes Rieken 已提交
170 171
		} else if (typeof markup === 'string') {
			return { value: <string>markup, isTrusted: true };
172
		} else {
J
Johannes Rieken 已提交
173
			return { value: '' };
174 175
		}
	}
176 177 178 179
	export function to(value: htmlContent.IMarkdownString): vscode.MarkdownString {
		const ret = new htmlContent.MarkdownString(value.value);
		ret.isTrusted = value.isTrusted;
		return ret;
180
	}
181 182
}

183
export function fromRangeOrRangeWithMessage(ranges: vscode.Range[] | vscode.DecorationOptions[]): IDecorationOptions[] {
M
Martin Aeschlimann 已提交
184
	if (isDecorationOptionsArr(ranges)) {
185
		return ranges.map(r => {
E
Erich Gamma 已提交
186 187
			return {
				range: fromRange(r.range),
188
				hoverMessage: Array.isArray(r.hoverMessage) ? MarkdownString.fromMany(r.hoverMessage) : r.hoverMessage && MarkdownString.from(r.hoverMessage),
189
				renderOptions: <any> /* URI vs Uri */r.renderOptions
E
Erich Gamma 已提交
190 191 192
			};
		});
	} else {
M
Martin Aeschlimann 已提交
193
		return ranges.map((r): IDecorationOptions => {
E
Erich Gamma 已提交
194 195
			return {
				range: fromRange(r)
B
Benjamin Pasero 已提交
196
			};
E
Erich Gamma 已提交
197 198 199
		});
	}
}
200

201
export const TextEdit = {
202

J
Johannes Rieken 已提交
203 204
	from(edit: vscode.TextEdit): modes.TextEdit {
		return <modes.TextEdit>{
205
			text: edit.newText,
J
Johannes Rieken 已提交
206
			eol: EndOfLine.from(edit.newEol),
207
			range: fromRange(edit.range)
B
Benjamin Pasero 已提交
208
		};
209
	},
J
Johannes Rieken 已提交
210 211 212 213
	to(edit: modes.TextEdit): vscode.TextEdit {
		let result = new types.TextEdit(toRange(edit.range), edit.text);
		result.newEol = EndOfLine.to(edit.eol);
		return result;
214
	}
B
Benjamin Pasero 已提交
215
};
216

217

218 219 220
export namespace SymbolKind {

	const _fromMapping: { [kind: number]: modes.SymbolKind } = Object.create(null);
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
	_fromMapping[types.SymbolKind.File] = modes.SymbolKind.File;
	_fromMapping[types.SymbolKind.Module] = modes.SymbolKind.Module;
	_fromMapping[types.SymbolKind.Namespace] = modes.SymbolKind.Namespace;
	_fromMapping[types.SymbolKind.Package] = modes.SymbolKind.Package;
	_fromMapping[types.SymbolKind.Class] = modes.SymbolKind.Class;
	_fromMapping[types.SymbolKind.Method] = modes.SymbolKind.Method;
	_fromMapping[types.SymbolKind.Property] = modes.SymbolKind.Property;
	_fromMapping[types.SymbolKind.Field] = modes.SymbolKind.Field;
	_fromMapping[types.SymbolKind.Constructor] = modes.SymbolKind.Constructor;
	_fromMapping[types.SymbolKind.Enum] = modes.SymbolKind.Enum;
	_fromMapping[types.SymbolKind.Interface] = modes.SymbolKind.Interface;
	_fromMapping[types.SymbolKind.Function] = modes.SymbolKind.Function;
	_fromMapping[types.SymbolKind.Variable] = modes.SymbolKind.Variable;
	_fromMapping[types.SymbolKind.Constant] = modes.SymbolKind.Constant;
	_fromMapping[types.SymbolKind.String] = modes.SymbolKind.String;
	_fromMapping[types.SymbolKind.Number] = modes.SymbolKind.Number;
	_fromMapping[types.SymbolKind.Boolean] = modes.SymbolKind.Boolean;
	_fromMapping[types.SymbolKind.Array] = modes.SymbolKind.Array;
	_fromMapping[types.SymbolKind.Object] = modes.SymbolKind.Object;
	_fromMapping[types.SymbolKind.Key] = modes.SymbolKind.Key;
	_fromMapping[types.SymbolKind.Null] = modes.SymbolKind.Null;
	_fromMapping[types.SymbolKind.EnumMember] = modes.SymbolKind.EnumMember;
	_fromMapping[types.SymbolKind.Struct] = modes.SymbolKind.Struct;
244 245
	_fromMapping[types.SymbolKind.Event] = modes.SymbolKind.Event;
	_fromMapping[types.SymbolKind.Operator] = modes.SymbolKind.Operator;
246
	_fromMapping[types.SymbolKind.TypeParameter] = modes.SymbolKind.TypeParameter;
247 248

	export function from(kind: vscode.SymbolKind): modes.SymbolKind {
249
		return _fromMapping[kind] || modes.SymbolKind.Property;
250 251
	}

252 253 254 255
	export function to(kind: modes.SymbolKind): vscode.SymbolKind {
		for (let k in _fromMapping) {
			if (_fromMapping[k] === kind) {
				return Number(k);
256
			}
257 258
		}
		return types.SymbolKind.Property;
259 260 261
	}
}

262 263
export function fromSymbolInformation(info: vscode.SymbolInformation): modes.SymbolInformation {
	return <modes.SymbolInformation>{
264
		name: info.name,
265
		kind: SymbolKind.from(info.kind),
266
		containerName: info.containerName,
267
		location: location.from(info.location)
268 269 270
	};
}

271 272 273 274
export function toSymbolInformation(bearing: modes.SymbolInformation): types.SymbolInformation {
	return new types.SymbolInformation(
		bearing.name,
		SymbolKind.to(bearing.kind),
275
		bearing.containerName,
276
		location.to(bearing.location)
277
	);
278 279 280
}


281
export const location = {
J
Johannes Rieken 已提交
282
	from(value: vscode.Location): modes.Location {
283
		return {
J
Johannes Rieken 已提交
284 285
			range: value.range && fromRange(value.range),
			uri: <URI>value.uri
J
Johannes Rieken 已提交
286
		};
287
	},
288 289
	to(value: modes.Location): types.Location {
		return new types.Location(value.uri, toRange(value.range));
290
	}
J
Johannes Rieken 已提交
291
};
292

293 294
export function fromHover(hover: vscode.Hover): modes.Hover {
	return <modes.Hover>{
295
		range: fromRange(hover.range),
296
		contents: MarkdownString.fromMany(hover.contents)
B
Benjamin Pasero 已提交
297
	};
298 299
}

300
export function toHover(info: modes.Hover): types.Hover {
301
	return new types.Hover(info.contents.map(MarkdownString.to), toRange(info.range));
302 303
}

304 305
export function toDocumentHighlight(occurrence: modes.DocumentHighlight): types.DocumentHighlight {
	return new types.DocumentHighlight(toRange(occurrence.range), occurrence.kind);
306 307
}

J
Johannes Rieken 已提交
308 309 310 311
export const CompletionItemKind = {

	from(kind: types.CompletionItemKind): modes.SuggestionType {
		switch (kind) {
312
			case types.CompletionItemKind.Method: return 'method';
J
Johannes Rieken 已提交
313 314 315 316 317 318
			case types.CompletionItemKind.Function: return 'function';
			case types.CompletionItemKind.Constructor: return 'constructor';
			case types.CompletionItemKind.Field: return 'field';
			case types.CompletionItemKind.Variable: return 'variable';
			case types.CompletionItemKind.Class: return 'class';
			case types.CompletionItemKind.Interface: return 'interface';
319
			case types.CompletionItemKind.Struct: return 'struct';
J
Johannes Rieken 已提交
320 321 322 323
			case types.CompletionItemKind.Module: return 'module';
			case types.CompletionItemKind.Property: return 'property';
			case types.CompletionItemKind.Unit: return 'unit';
			case types.CompletionItemKind.Value: return 'value';
324
			case types.CompletionItemKind.Constant: return 'constant';
J
Johannes Rieken 已提交
325
			case types.CompletionItemKind.Enum: return 'enum';
326
			case types.CompletionItemKind.EnumMember: return 'enum-member';
J
Johannes Rieken 已提交
327 328 329 330 331 332
			case types.CompletionItemKind.Keyword: return 'keyword';
			case types.CompletionItemKind.Snippet: return 'snippet';
			case types.CompletionItemKind.Text: return 'text';
			case types.CompletionItemKind.Color: return 'color';
			case types.CompletionItemKind.File: return 'file';
			case types.CompletionItemKind.Reference: return 'reference';
333
			case types.CompletionItemKind.Folder: return 'folder';
334 335
			case types.CompletionItemKind.Event: return 'event';
			case types.CompletionItemKind.Operator: return 'operator';
336
			case types.CompletionItemKind.TypeParameter: return 'type-parameter';
J
Johannes Rieken 已提交
337
		}
338
		return 'property';
J
Johannes Rieken 已提交
339 340 341 342
	},

	to(type: modes.SuggestionType): types.CompletionItemKind {
		if (!type) {
343
			return types.CompletionItemKind.Property;
J
Johannes Rieken 已提交
344 345 346 347 348 349
		} else {
			return types.CompletionItemKind[type.charAt(0).toUpperCase() + type.substr(1)];
		}
	}
};

350
export namespace Suggest {
351

352
	export function to(position: types.Position, suggestion: modes.ISuggestion): types.CompletionItem {
353
		const result = new types.CompletionItem(suggestion.label);
354
		result.insertText = suggestion.insertText;
J
Johannes Rieken 已提交
355
		result.kind = CompletionItemKind.to(suggestion.type);
356
		result.detail = suggestion.detail;
357
		result.documentation = htmlContent.isMarkdownString(suggestion.documentation) ? MarkdownString.to(suggestion.documentation) : suggestion.documentation;
358 359
		result.sortText = suggestion.sortText;
		result.filterText = suggestion.filterText;
360

361
		// 'overwrite[Before|After]'-logic
362
		let overwriteBefore = (typeof suggestion.overwriteBefore === 'number') ? suggestion.overwriteBefore : 0;
M
Martin Aeschlimann 已提交
363 364 365
		let startPosition = new types.Position(position.line, Math.max(0, position.character - overwriteBefore));
		let endPosition = position;
		if (typeof suggestion.overwriteAfter === 'number') {
366 367
			endPosition = new types.Position(position.line, position.character + suggestion.overwriteAfter);
		}
368 369 370 371 372 373 374 375 376 377 378
		result.range = new types.Range(startPosition, endPosition);

		// 'inserText'-logic
		if (suggestion.snippetType === 'textmate') {
			result.insertText = new types.SnippetString(suggestion.insertText);
		} else {
			result.insertText = suggestion.insertText;
			result.textEdit = new types.TextEdit(result.range, result.insertText);
		}

		// TODO additionalEdits, command
379

380 381
		return result;
	}
B
Benjamin Pasero 已提交
382
};
383

384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
export namespace ParameterInformation {
	export function from(info: types.ParameterInformation): modes.ParameterInformation {
		return {
			label: info.label,
			documentation: info.documentation && MarkdownString.from(info.documentation)
		};
	}
	export function to(info: modes.ParameterInformation): types.ParameterInformation {
		return {
			label: info.label,
			documentation: htmlContent.isMarkdownString(info.documentation) ? MarkdownString.to(info.documentation) : info.documentation
		};
	}
}

export namespace SignatureInformation {

	export function from(info: types.SignatureInformation): modes.SignatureInformation {
		return {
			label: info.label,
			documentation: info.documentation && MarkdownString.from(info.documentation),
			parameters: info.parameters && info.parameters.map(ParameterInformation.from)
		};
	}

	export function to(info: modes.SignatureInformation): types.SignatureInformation {
		return {
			label: info.label,
			documentation: htmlContent.isMarkdownString(info.documentation) ? MarkdownString.to(info.documentation) : info.documentation,
			parameters: info.parameters && info.parameters.map(ParameterInformation.to)
		};
	}
}

418 419
export namespace SignatureHelp {

420 421 422 423 424 425
	export function from(help: types.SignatureHelp): modes.SignatureHelp {
		return {
			activeSignature: help.activeSignature,
			activeParameter: help.activeParameter,
			signatures: help.signatures && help.signatures.map(SignatureInformation.from)
		};
426 427
	}

428 429 430 431 432 433
	export function to(help: modes.SignatureHelp): types.SignatureHelp {
		return {
			activeSignature: help.activeSignature,
			activeParameter: help.activeParameter,
			signatures: help.signatures && help.signatures.map(SignatureInformation.to)
		};
434
	}
J
Johannes Rieken 已提交
435 436
}

J
Johannes Rieken 已提交
437 438
export namespace DocumentLink {

439
	export function from(link: vscode.DocumentLink): modes.ILink {
J
Johannes Rieken 已提交
440 441
		return {
			range: fromRange(link.range),
442
			url: link.target && link.target.toString()
J
Johannes Rieken 已提交
443 444 445
		};
	}

446
	export function to(link: modes.ILink): vscode.DocumentLink {
447
		return new types.DocumentLink(toRange(link.range), link.url && URI.parse(link.url));
J
Johannes Rieken 已提交
448 449
	}
}
450

451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
export namespace ColorPresentation {
	export function to(colorPresentation: modes.IColorPresentation): vscode.ColorPresentation {
		return {
			label: colorPresentation.label,
			textEdit: colorPresentation.textEdit ? TextEdit.to(colorPresentation.textEdit) : undefined,
			additionalTextEdits: colorPresentation.additionalTextEdits ? colorPresentation.additionalTextEdits.map(value => TextEdit.to(value)) : undefined
		};
	}

	export function from(colorPresentation: vscode.ColorPresentation): modes.IColorPresentation {
		return {
			label: colorPresentation.label,
			textEdit: colorPresentation.textEdit ? TextEdit.from(colorPresentation.textEdit) : undefined,
			additionalTextEdits: colorPresentation.additionalTextEdits ? colorPresentation.additionalTextEdits.map(value => TextEdit.from(value)) : undefined
		};
	}
}

469 470 471 472 473
export namespace TextDocumentSaveReason {

	export function to(reason: SaveReason): vscode.TextDocumentSaveReason {
		switch (reason) {
			case SaveReason.AUTO:
474
				return types.TextDocumentSaveReason.AfterDelay;
475
			case SaveReason.EXPLICIT:
476
				return types.TextDocumentSaveReason.Manual;
477 478 479 480 481
			case SaveReason.FOCUS_CHANGE:
			case SaveReason.WINDOW_CHANGE:
				return types.TextDocumentSaveReason.FocusOut;
		}
	}
482
}
483 484


485 486 487 488 489 490 491 492 493
export namespace EndOfLine {

	export function from(eol: vscode.EndOfLine): EndOfLineSequence {
		if (eol === types.EndOfLine.CRLF) {
			return EndOfLineSequence.CRLF;
		} else if (eol === types.EndOfLine.LF) {
			return EndOfLineSequence.LF;
		}
		return undefined;
494
	}
J
Johannes Rieken 已提交
495 496 497 498 499 500 501 502 503

	export function to(eol: EndOfLineSequence): vscode.EndOfLine {
		if (eol === EndOfLineSequence.CRLF) {
			return types.EndOfLine.CRLF;
		} else if (eol === EndOfLineSequence.LF) {
			return types.EndOfLine.LF;
		}
		return undefined;
	}
504 505
}

J
Johannes Rieken 已提交
506 507 508
export namespace ProgressLocation {
	export function from(loc: vscode.ProgressLocation): MainProgressLocation {
		switch (loc) {
509
			case types.ProgressLocation.SourceControl: return MainProgressLocation.Scm;
J
Johannes Rieken 已提交
510 511 512 513 514
			case types.ProgressLocation.Window: return MainProgressLocation.Window;
		}
		return undefined;
	}
}