Merge branch 'master' into octref/pathCompletion
8
.vscode/launch.json
vendored
|
@ -165,12 +165,12 @@
|
|||
"name": "VS Code Markdown Extension Tests",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"${workspaceFolder}/extensions/markdown/test-fixtures",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/extensions/markdown",
|
||||
"--extensionTestsPath=${workspaceFolder}/extensions/markdown/out/test"
|
||||
"${workspaceFolder}/extensions/markdown-language-features/test-fixtures",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/extensions/markdown-language-features",
|
||||
"--extensionTestsPath=${workspaceFolder}/extensions/markdown-language-features/out/test"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/extensions/markdown/out/**/*.js"
|
||||
"${workspaceFolder}/extensions/markdown-language-features/out/**/*.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
1
.vscode/settings.json
vendored
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"editor.insertSpaces": false,
|
||||
"files.eol": "\n",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"files.exclude": {
|
||||
".git": true,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
[
|
||||
{
|
||||
"name": "ms-vscode.node-debug",
|
||||
"version": "1.22.5",
|
||||
"version": "1.22.7",
|
||||
"repo": "https://github.com/Microsoft/vscode-node-debug"
|
||||
},
|
||||
{
|
||||
"name": "ms-vscode.node-debug2",
|
||||
"version": "1.22.2",
|
||||
"version": "1.22.3",
|
||||
"repo": "https://github.com/Microsoft/vscode-node-debug2"
|
||||
}
|
||||
]
|
|
@ -82,7 +82,7 @@ const indentationFilter = [
|
|||
'!build/**/*.sh',
|
||||
'!build/tfs/**/*.js',
|
||||
'!**/Dockerfile',
|
||||
'!extensions/markdown/media/*.js'
|
||||
'!extensions/markdown-language-features/media/*.js'
|
||||
];
|
||||
|
||||
const copyrightFilter = [
|
||||
|
@ -104,7 +104,7 @@ const copyrightFilter = [
|
|||
'!build/**/*.init',
|
||||
'!resources/linux/snap/snapcraft.yaml',
|
||||
'!resources/win32/bin/code.js',
|
||||
'!extensions/markdown/media/tomorrow.css',
|
||||
'!extensions/markdown-language-features/media/tomorrow.css',
|
||||
'!extensions/html-language-features/server/src/modes/typescript/*'
|
||||
];
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import { getCSSLanguageService, getSCSSLanguageService } from 'vscode-css-langua
|
|||
import { TextDocument, CompletionList } from 'vscode-languageserver-types';
|
||||
import { getEmmetCompletionParticipants } from 'vscode-emmet-helper';
|
||||
|
||||
suite('Emmet Support', () => {
|
||||
suite('CSS Emmet Support', () => {
|
||||
|
||||
const cssLanguageService = getCSSLanguageService();
|
||||
const scssLanguageService = getSCSSLanguageService();
|
||||
|
@ -44,6 +44,8 @@ suite('Emmet Support', () => {
|
|||
}
|
||||
|
||||
test('Css Emmet Completions', function (): any {
|
||||
this.skip(); // disabled again (see #29113)
|
||||
|
||||
assertCompletions('css', '.foo { display: none; m10| }', 'margin: 10px;', 'margin: 10px;');
|
||||
assertCompletions('css', 'foo { display: none; pos:f| }', 'position: fixed;', 'position: fixed;');
|
||||
assertCompletions('css', 'foo { display: none; margin: a| }', null, null);
|
||||
|
@ -55,6 +57,8 @@ suite('Emmet Support', () => {
|
|||
});
|
||||
|
||||
test('Scss Emmet Completions', function (): any {
|
||||
this.skip(); // disabled again (see #29113)
|
||||
|
||||
assertCompletions('scss', '.foo { display: none; .bar { m10| } }', 'margin: 10px;', 'margin: 10px;');
|
||||
assertCompletions('scss', 'foo { display: none; .bar { pos:f| } }', 'position: fixed;', 'position: fixed;');
|
||||
assertCompletions('scss', 'foo { display: none; margin: a| .bar {}}', null, null);
|
||||
|
@ -64,5 +68,4 @@ suite('Emmet Support', () => {
|
|||
assertCompletions('scss', 'foo { display: none|; }', null, null);
|
||||
assertCompletions('scss', '.foo { display: none; -m-m10| }', 'margin: 10px;', '-moz-margin: 10px;\nmargin: 10px;');
|
||||
});
|
||||
|
||||
});
|
|
@ -6,37 +6,55 @@
|
|||
'use strict';
|
||||
|
||||
import { Model } from './model';
|
||||
import { Uri } from 'vscode';
|
||||
import { Repository as ModelRepository } from './repository';
|
||||
import { Uri, SourceControlInputBox } from 'vscode';
|
||||
|
||||
export interface InputBox {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export class InputBoxImpl implements InputBox {
|
||||
set value(value: string) { this.inputBox.value = value; }
|
||||
get value(): string { return this.inputBox.value; }
|
||||
constructor(private inputBox: SourceControlInputBox) { }
|
||||
}
|
||||
|
||||
export interface Repository {
|
||||
readonly rootUri: Uri;
|
||||
readonly inputBox: InputBox;
|
||||
}
|
||||
|
||||
export interface API {
|
||||
getRepositories(): Promise<Repository[]>;
|
||||
export class RepositoryImpl implements Repository {
|
||||
|
||||
readonly rootUri: Uri;
|
||||
readonly inputBox: InputBox;
|
||||
|
||||
constructor(repository: ModelRepository) {
|
||||
this.rootUri = Uri.file(repository.root);
|
||||
this.inputBox = new InputBoxImpl(repository.inputBox);
|
||||
}
|
||||
}
|
||||
|
||||
export function createApi(modelPromise: Promise<Model>) {
|
||||
return {
|
||||
async getRepositories(): Promise<Repository[]> {
|
||||
const model = await modelPromise;
|
||||
export interface API {
|
||||
getRepositories(): Promise<Repository[]>;
|
||||
getGitPath(): Promise<string>;
|
||||
}
|
||||
|
||||
return model.repositories.map(repository => ({
|
||||
rootUri: Uri.file(repository.root),
|
||||
inputBox: {
|
||||
set value(value: string) {
|
||||
repository.inputBox.value = value;
|
||||
},
|
||||
get value(): string {
|
||||
return repository.inputBox.value;
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
export class APIImpl implements API {
|
||||
|
||||
constructor(private modelPromise: Promise<Model>) { }
|
||||
|
||||
async getGitPath(): Promise<string> {
|
||||
const model = await this.modelPromise;
|
||||
return model.git.path;
|
||||
}
|
||||
|
||||
async getRepositories(): Promise<Repository[]> {
|
||||
const model = await this.modelPromise;
|
||||
return model.repositories.map(repository => new RepositoryImpl(repository));
|
||||
}
|
||||
}
|
||||
|
||||
export function createApi(modelPromise: Promise<Model>): API {
|
||||
return new APIImpl(modelPromise);
|
||||
}
|
|
@ -366,14 +366,14 @@ function getGitErrorCode(stderr: string): string | undefined {
|
|||
|
||||
export class Git {
|
||||
|
||||
private gitPath: string;
|
||||
readonly path: string;
|
||||
private env: any;
|
||||
|
||||
private _onOutput = new EventEmitter();
|
||||
get onOutput(): EventEmitter { return this._onOutput; }
|
||||
|
||||
constructor(options: IGitOptions) {
|
||||
this.gitPath = options.gitPath;
|
||||
this.path = options.gitPath;
|
||||
this.env = options.env || {};
|
||||
}
|
||||
|
||||
|
@ -447,7 +447,7 @@ export class Git {
|
|||
}
|
||||
|
||||
spawn(args: string[], options: SpawnOptions = {}): cp.ChildProcess {
|
||||
if (!this.gitPath) {
|
||||
if (!this.path) {
|
||||
throw new Error('git could not be found in the system.');
|
||||
}
|
||||
|
||||
|
@ -469,7 +469,7 @@ export class Git {
|
|||
this.log(`> git ${args.join(' ')}\n`);
|
||||
}
|
||||
|
||||
return cp.spawn(this.gitPath, args, options);
|
||||
return cp.spawn(this.path, args, options);
|
||||
}
|
||||
|
||||
private log(output: string): void {
|
||||
|
|
|
@ -66,7 +66,7 @@ export class Model {
|
|||
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(private git: Git, private globalState: Memento, private outputChannel: OutputChannel) {
|
||||
constructor(readonly git: Git, private globalState: Memento, private outputChannel: OutputChannel) {
|
||||
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
|
||||
this.onDidChangeWorkspaceFolders({ added: workspace.workspaceFolders || [], removed: [] });
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import * as path from 'path';
|
|||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, FoldingRangeList, FoldingRange, workspace, FoldingContext } from 'vscode';
|
||||
import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, FoldingRangeList, FoldingRange, FoldingContext } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams, Disposable, CancellationToken } from 'vscode-languageclient';
|
||||
import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
|
||||
import { activateTagClosing } from './tagClosing';
|
||||
|
@ -28,8 +28,6 @@ interface IPackageInfo {
|
|||
|
||||
let telemetryReporter: TelemetryReporter | null;
|
||||
|
||||
let foldingProviderRegistration: Disposable | undefined = void 0;
|
||||
const foldingSetting = 'html.experimental.syntaxFolding';
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
let toDispose = context.subscriptions;
|
||||
|
@ -83,14 +81,7 @@ export function activate(context: ExtensionContext) {
|
|||
}
|
||||
});
|
||||
toDispose.push(disposable);
|
||||
|
||||
initFoldingProvider();
|
||||
toDispose.push(workspace.onDidChangeConfiguration(c => {
|
||||
if (c.affectsConfiguration(foldingSetting)) {
|
||||
initFoldingProvider();
|
||||
}
|
||||
}));
|
||||
toDispose.push({ dispose: () => foldingProviderRegistration && foldingProviderRegistration.dispose() });
|
||||
toDispose.push(initFoldingProvider());
|
||||
});
|
||||
|
||||
languages.setLanguageConfiguration('html', {
|
||||
|
@ -167,34 +158,24 @@ export function activate(context: ExtensionContext) {
|
|||
}
|
||||
});
|
||||
|
||||
function initFoldingProvider() {
|
||||
let enable = workspace.getConfiguration().get(foldingSetting);
|
||||
if (enable) {
|
||||
if (!foldingProviderRegistration) {
|
||||
foldingProviderRegistration = languages.registerFoldingProvider(documentSelector, {
|
||||
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
|
||||
const param: FoldingRangeRequestParam = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
maxRanges: context.maxRanges
|
||||
};
|
||||
return client.sendRequest(FoldingRangesRequest.type, param, token).then(res => {
|
||||
if (res && Array.isArray(res.ranges)) {
|
||||
return new FoldingRangeList(res.ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.type)));
|
||||
}
|
||||
return null;
|
||||
}, error => {
|
||||
client.logFailedRequest(FoldingRangesRequest.type, error);
|
||||
return null;
|
||||
});
|
||||
function initFoldingProvider(): Disposable {
|
||||
return languages.registerFoldingProvider(documentSelector, {
|
||||
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
|
||||
const param: FoldingRangeRequestParam = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
maxRanges: context.maxRanges
|
||||
};
|
||||
return client.sendRequest(FoldingRangesRequest.type, param, token).then(res => {
|
||||
if (res && Array.isArray(res.ranges)) {
|
||||
return new FoldingRangeList(res.ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.type)));
|
||||
}
|
||||
return null;
|
||||
}, error => {
|
||||
client.logFailedRequest(FoldingRangesRequest.type, error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (foldingProviderRegistration) {
|
||||
foldingProviderRegistration.dispose();
|
||||
foldingProviderRegistration = void 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -154,11 +154,6 @@
|
|||
"default": true,
|
||||
"description": "%html.autoClosingTags%"
|
||||
},
|
||||
"html.experimental.syntaxFolding": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "%html.experimental.syntaxFolding%"
|
||||
},
|
||||
"html.trace.server": {
|
||||
"type": "string",
|
||||
"scope": "window",
|
||||
|
|
|
@ -22,6 +22,5 @@
|
|||
"html.trace.server.desc": "Traces the communication between VS Code and the HTML language server.",
|
||||
"html.validate.scripts": "Configures if the built-in HTML language support validates embedded scripts.",
|
||||
"html.validate.styles": "Configures if the built-in HTML language support validates embedded styles.",
|
||||
"html.experimental.syntaxFolding": "Enables/disables syntax aware folding markers.",
|
||||
"html.autoClosingTags": "Enable/disable autoclosing of HTML tags."
|
||||
}
|
|
@ -21,8 +21,8 @@
|
|||
"@types/node": "7.0.43"
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:html-server",
|
||||
"watch": "gulp watch-extension:html-server",
|
||||
"compile": "gulp compile-extension:html-language-features-server",
|
||||
"watch": "gulp watch-extension:html-language-features-server",
|
||||
"install-service-next": "yarn add vscode-css-languageservice@next && yarn add vscode-html-languageservice@next",
|
||||
"install-service-local": "npm install ../../../../vscode-css-languageservice -f && npm install ../../../../vscode-html-languageservice -f",
|
||||
"install-server-next": "yarn add vscode-languageserver@next",
|
||||
|
|
|
@ -292,9 +292,9 @@ export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocume
|
|||
let endLine = curr.end.line;
|
||||
if (startLine < endLine && startLine >= rangeStartLine && endLine < rangeEndLine) {
|
||||
let foldingRange: FoldingRange = { startLine, endLine };
|
||||
let match = document.getText(curr).match(/^\s*\/(\/\s*#(?:end)?region\b)|([\*\/])/);
|
||||
let match = document.getText(curr).match(/^\s*\/(?:(\/\s*#(?:end)?region\b)|(\*|\/))/);
|
||||
if (match) {
|
||||
foldingRange.type = match[1].length ? FoldingRangeType.Region : FoldingRangeType.Comment;
|
||||
foldingRange.type = match[1] ? FoldingRangeType.Region : FoldingRangeType.Comment;
|
||||
}
|
||||
ranges.push(foldingRange);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ export interface ItemDescription {
|
|||
}
|
||||
|
||||
|
||||
suite('Completions', () => {
|
||||
suite('HTML Completions', () => {
|
||||
|
||||
let assertCompletion = function (completions: CompletionList, expected: ItemDescription, document: TextDocument, offset: number) {
|
||||
let matches = completions.items.filter(completion => {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import * as assert from 'assert';
|
||||
import { getDocumentContext } from '../utils/documentContext';
|
||||
|
||||
suite('Document Context', () => {
|
||||
suite('HTML Document Context', () => {
|
||||
|
||||
test('Context', function (): any {
|
||||
const docURI = 'file:///users/test/folder/test.html';
|
||||
|
|
|
@ -15,7 +15,7 @@ import * as embeddedSupport from '../modes/embeddedSupport';
|
|||
import { getEmmetCompletionParticipants } from 'vscode-emmet-helper';
|
||||
import { getCSSMode } from '../modes/cssMode';
|
||||
|
||||
suite('Emmet Support', () => {
|
||||
suite('HTML Emmet Support', () => {
|
||||
|
||||
const htmlLanguageService = getLanguageService();
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ function r(startLine: number, endLine: number, type?: string): ExpectedIndentRan
|
|||
return { startLine, endLine, type };
|
||||
}
|
||||
|
||||
suite('Object Folding', () => {
|
||||
suite('HTML Folding', () => {
|
||||
test('Fold one level', () => {
|
||||
let input = [
|
||||
/*0*/'<html>',
|
||||
|
@ -130,7 +130,7 @@ suite('Object Folding', () => {
|
|||
/* 6*/' };',
|
||||
/* 7*/'</script>',
|
||||
/* 8*/'<script>',
|
||||
/* 9*/' test(() => {',
|
||||
/* 9*/' test(() => { // hello',
|
||||
/*10*/' f();',
|
||||
/*11*/' });',
|
||||
/*12*/'</script>',
|
||||
|
@ -206,7 +206,7 @@ suite('Object Folding', () => {
|
|||
/*2*/'</div>',
|
||||
];
|
||||
assertRanges(input, [r(0, 1)]);
|
||||
});
|
||||
});
|
||||
|
||||
test('Fold intersecting region', () => {
|
||||
let input = [
|
||||
|
@ -218,7 +218,7 @@ suite('Object Folding', () => {
|
|||
/*5*/'<!-- #endregion -->',
|
||||
];
|
||||
assertRanges(input, [r(0, 3)]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('Test limit', () => {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import * as assert from 'assert';
|
||||
import * as words from '../utils/strings';
|
||||
|
||||
suite('Words', () => {
|
||||
suite('HTML Words', () => {
|
||||
|
||||
let wordRegex = /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g;
|
||||
|
||||
|
|
|
@ -62,7 +62,8 @@
|
|||
"tokenTypes": {
|
||||
"entity.name.type.instance.jsdoc": "other",
|
||||
"entity.name.function.tagged-template.js": "other",
|
||||
"entity.name.function.tagged-template.js.jsx": "other"
|
||||
"entity.name.function.tagged-template.js.jsx": "other",
|
||||
"meta.import string.quoted": "other"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -78,7 +79,8 @@
|
|||
"tokenTypes": {
|
||||
"entity.name.type.instance.jsdoc": "other",
|
||||
"entity.name.function.tagged-template.js": "other",
|
||||
"entity.name.function.tagged-template.js.jsx": "other"
|
||||
"entity.name.function.tagged-template.js.jsx": "other",
|
||||
"meta.import string.quoted": "other"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -57,9 +57,6 @@ interface JSONSchemaSettings {
|
|||
|
||||
let telemetryReporter: TelemetryReporter | undefined;
|
||||
|
||||
let foldingProviderRegistration: Disposable | undefined = void 0;
|
||||
const foldingSetting = 'json.experimental.syntaxFolding';
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
|
||||
let toDispose = context.subscriptions;
|
||||
|
@ -130,13 +127,7 @@ export function activate(context: ExtensionContext) {
|
|||
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
|
||||
|
||||
initFoldingProvider();
|
||||
toDispose.push(workspace.onDidChangeConfiguration(c => {
|
||||
if (c.affectsConfiguration(foldingSetting)) {
|
||||
initFoldingProvider();
|
||||
}
|
||||
}));
|
||||
toDispose.push({ dispose: () => foldingProviderRegistration && foldingProviderRegistration.dispose() });
|
||||
toDispose.push(initFoldingProvider());
|
||||
});
|
||||
|
||||
let languageConfiguration: LanguageConfiguration = {
|
||||
|
@ -149,34 +140,24 @@ export function activate(context: ExtensionContext) {
|
|||
languages.setLanguageConfiguration('json', languageConfiguration);
|
||||
languages.setLanguageConfiguration('jsonc', languageConfiguration);
|
||||
|
||||
function initFoldingProvider() {
|
||||
let enable = workspace.getConfiguration().get(foldingSetting);
|
||||
if (enable) {
|
||||
if (!foldingProviderRegistration) {
|
||||
foldingProviderRegistration = languages.registerFoldingProvider(documentSelector, {
|
||||
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
|
||||
const param: FoldingRangeRequestParam = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
maxRanges: context.maxRanges
|
||||
};
|
||||
return client.sendRequest(FoldingRangesRequest.type, param, token).then(res => {
|
||||
if (res && Array.isArray(res.ranges)) {
|
||||
return new FoldingRangeList(res.ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.type)));
|
||||
}
|
||||
return null;
|
||||
}, error => {
|
||||
client.logFailedRequest(FoldingRangesRequest.type, error);
|
||||
return null;
|
||||
});
|
||||
function initFoldingProvider(): Disposable {
|
||||
return languages.registerFoldingProvider(documentSelector, {
|
||||
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
|
||||
const param: FoldingRangeRequestParam = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
maxRanges: context.maxRanges
|
||||
};
|
||||
return client.sendRequest(FoldingRangesRequest.type, param, token).then(res => {
|
||||
if (res && Array.isArray(res.ranges)) {
|
||||
return new FoldingRangeList(res.ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.type)));
|
||||
}
|
||||
return null;
|
||||
}, error => {
|
||||
client.logFailedRequest(FoldingRangesRequest.type, error);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (foldingProviderRegistration) {
|
||||
foldingProviderRegistration.dispose();
|
||||
foldingProviderRegistration = void 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,11 +85,6 @@
|
|||
"default": true,
|
||||
"description": "%json.colorDecorators.enable.desc%",
|
||||
"deprecationMessage": "%json.colorDecorators.enable.deprecationMessage%"
|
||||
},
|
||||
"json.experimental.syntaxFolding": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "%json.experimental.syntaxFolding%"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -9,6 +9,5 @@
|
|||
"json.format.enable.desc": "Enable/disable default JSON formatter (requires restart)",
|
||||
"json.tracing.desc": "Traces the communication between VS Code and the JSON language server.",
|
||||
"json.colorDecorators.enable.desc": "Enables or disables color decorators",
|
||||
"json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.",
|
||||
"json.experimental.syntaxFolding": "Enables/disables syntax aware folding markers."
|
||||
"json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`."
|
||||
}
|
|
@ -20,8 +20,8 @@
|
|||
"@types/mocha": "2.2.33"
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:json-server",
|
||||
"watch": "gulp watch-extension:json-server",
|
||||
"compile": "gulp compile-extension:json-language-features-server",
|
||||
"watch": "gulp watch-extension:json-language-features-server",
|
||||
"install-service-next": "yarn add vscode-json-languageservice@next",
|
||||
"install-service-local": "yarn link vscode-json-languageservice",
|
||||
"install-server-next": "yarn add vscode-languageserver@next",
|
||||
|
|
|
@ -32,7 +32,7 @@ function r(startLine: number, endLine: number, type?: string): ExpectedIndentRan
|
|||
return { startLine, endLine, type };
|
||||
}
|
||||
|
||||
suite('Object Folding', () => {
|
||||
suite('JSON Folding', () => {
|
||||
test('Fold one level', () => {
|
||||
let input = [
|
||||
/*0*/'{',
|
||||
|
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 857 B |
Before Width: | Height: | Size: 819 B After Width: | Height: | Size: 819 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 417 B |
Before Width: | Height: | Size: 262 B After Width: | Height: | Size: 262 B |
|
@ -529,26 +529,26 @@ module.exports = throttle;
|
|||
/*! no static exports found */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
var g;
|
||||
|
||||
// This works in non-strict mode
|
||||
g = (function() {
|
||||
return this;
|
||||
})();
|
||||
|
||||
try {
|
||||
// This works if eval is allowed (see CSP)
|
||||
g = g || Function("return this")() || (1, eval)("this");
|
||||
} catch (e) {
|
||||
// This works if the window reference is available
|
||||
if (typeof window === "object") g = window;
|
||||
}
|
||||
|
||||
// g can still be undefined, but nothing to do about it...
|
||||
// We return undefined, instead of nothing here, so it's
|
||||
// easier to handle this case. if(!global) { ...}
|
||||
|
||||
module.exports = g;
|
||||
var g;
|
||||
|
||||
// This works in non-strict mode
|
||||
g = (function() {
|
||||
return this;
|
||||
})();
|
||||
|
||||
try {
|
||||
// This works if eval is allowed (see CSP)
|
||||
g = g || Function("return this")() || (1, eval)("this");
|
||||
} catch (e) {
|
||||
// This works if the window reference is available
|
||||
if (typeof window === "object") g = window;
|
||||
}
|
||||
|
||||
// g can still be undefined, but nothing to do about it...
|
||||
// We return undefined, instead of nothing here, so it's
|
||||
// easier to handle this case. if(!global) { ...}
|
||||
|
||||
module.exports = g;
|
||||
|
||||
|
||||
/***/ }),
|
|
@ -277,10 +277,10 @@
|
|||
]
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:markdown && npm run build-preview",
|
||||
"watch": "npm run build-preview && gulp watch-extension:markdown",
|
||||
"compile": "gulp compile-extension:markdown-language-features && npm run build-preview",
|
||||
"watch": "npm run build-preview && gulp watch-extension:markdown-language-features",
|
||||
"vscode:prepublish": "npm run build-ext && npm run build-preview",
|
||||
"build-ext": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown ./tsconfig.json",
|
||||
"build-ext": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown-language-features ./tsconfig.json",
|
||||
"build-preview": "webpack --mode development"
|
||||
},
|
||||
"dependencies": {
|
|
@ -48,6 +48,7 @@ export class MarkdownPreview {
|
|||
previewColumn, {
|
||||
enableScripts: true,
|
||||
enableCommandUris: true,
|
||||
enableFindWidget: true,
|
||||
localResourceRoots: this.getLocalResourceRoots(_resource)
|
||||
});
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
"version": "0.0.1",
|
||||
"description": "Dependencies shared by all extensions",
|
||||
"dependencies": {
|
||||
"typescript": "2.7.2"
|
||||
"typescript": "2.8.0-insiders.20180320"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./postinstall"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"editorSuggestWidget.background": "#F3F3F3",
|
||||
"activityBarBadge.background": "#007ACC",
|
||||
"sideBarTitle.foreground": "#6F6F6F",
|
||||
"list.hoverBackground": "#E8E8E8"
|
||||
"list.hoverBackground": "#E8E8E8",
|
||||
"input.placeholderForeground": "#ADADAD"
|
||||
}
|
||||
}
|
|
@ -46,7 +46,8 @@
|
|||
"tokenTypes": {
|
||||
"entity.name.type.instance.jsdoc": "other",
|
||||
"entity.name.function.tagged-template.ts": "other",
|
||||
"entity.name.function.tagged-template.tsx": "other"
|
||||
"entity.name.function.tagged-template.tsx": "other",
|
||||
"meta.import string.quoted": "other"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -62,7 +63,8 @@
|
|||
"tokenTypes": {
|
||||
"entity.name.type.instance.jsdoc": "other",
|
||||
"entity.name.function.tagged-template.ts": "other",
|
||||
"entity.name.function.tagged-template.tsx": "other"
|
||||
"entity.name.function.tagged-template.tsx": "other",
|
||||
"meta.import string.quoted": "other"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"onCommand:javascript.goToProjectConfig",
|
||||
"onCommand:typescript.goToProjectConfig",
|
||||
"onCommand:typescript.openTsServerLog",
|
||||
"onCommand:typescript.organizeImports",
|
||||
"onCommand:workbench.action.tasks.runTask"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
|
@ -460,6 +461,18 @@
|
|||
"value": "%typescript.restartTsServer%"
|
||||
},
|
||||
"category": "TypeScript"
|
||||
},
|
||||
{
|
||||
"command": "typescript.organizeImports",
|
||||
"title": "%typescript.organizeImports%",
|
||||
"category": "TypeScript"
|
||||
}
|
||||
],
|
||||
"keybindings": [
|
||||
{
|
||||
"command": "typescript.organizeImports",
|
||||
"key": "shift+alt+o",
|
||||
"when": "typescript.isManagedFile && typescript.canOrganizeImports"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
|
@ -507,6 +520,10 @@
|
|||
{
|
||||
"command": "typescript.restartTsServer",
|
||||
"when": "typescript.isManagedFile"
|
||||
},
|
||||
{
|
||||
"command": "typescript.organizeImports",
|
||||
"when": "typescript.isManagedFile && typescript.canOrganizeImports"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -50,5 +50,6 @@
|
|||
"javascript.implicitProjectConfig.experimentalDecorators": "Enable/disable 'experimentalDecorators' for JavaScript files that are not part of a project. Existing jsconfig.json or tsconfig.json files override this setting. Requires TypeScript >=2.3.1.",
|
||||
"typescript.autoImportSuggestions.enabled": "Enable/disable auto import suggestions. Requires TypeScript >=2.6.1",
|
||||
"typescript.experimental.syntaxFolding": "Enables/disables syntax aware folding markers.",
|
||||
"taskDefinition.tsconfig.description": "The tsconfig file that defines the TS build."
|
||||
"taskDefinition.tsconfig.description": "The tsconfig file that defines the TS build.",
|
||||
"typescript.organizeImports": "Organize Imports"
|
||||
}
|
|
@ -19,6 +19,7 @@ import ManagedFileContextManager from './utils/managedFileContext';
|
|||
import { lazy, Lazy } from './utils/lazy';
|
||||
import * as fileSchemes from './utils/fileSchemes';
|
||||
import LogDirectoryProvider from './utils/logDirectoryProvider';
|
||||
import { OrganizeImportsCommand, OrganizeImportsContextManager } from './features/organizeImports';
|
||||
|
||||
export function activate(
|
||||
context: vscode.ExtensionContext
|
||||
|
@ -70,7 +71,14 @@ function createLazyClientHost(
|
|||
plugins,
|
||||
commandManager,
|
||||
logDirectoryProvider);
|
||||
|
||||
context.subscriptions.push(clientHost);
|
||||
|
||||
const organizeImportsContext = new OrganizeImportsContextManager();
|
||||
clientHost.serviceClient.onTsServerStarted(api => {
|
||||
organizeImportsContext.onDidChangeApiVersion(api);
|
||||
}, null, context.subscriptions);
|
||||
|
||||
clientHost.serviceClient.onReady(() => {
|
||||
context.subscriptions.push(
|
||||
ProjectStatus.create(
|
||||
|
@ -79,6 +87,7 @@ function createLazyClientHost(
|
|||
path => new Promise<boolean>(resolve => setTimeout(() => resolve(clientHost.handles(path)), 750)),
|
||||
context.workspaceState));
|
||||
});
|
||||
|
||||
return clientHost;
|
||||
});
|
||||
}
|
||||
|
@ -94,6 +103,7 @@ function registerCommands(
|
|||
commandManager.register(new commands.RestartTsServerCommand(lazyClientHost));
|
||||
commandManager.register(new commands.TypeScriptGoToProjectConfigCommand(lazyClientHost));
|
||||
commandManager.register(new commands.JavaScriptGoToProjectConfigCommand(lazyClientHost));
|
||||
commandManager.register(new OrganizeImportsCommand(lazyClientHost));
|
||||
}
|
||||
|
||||
function isSupportedDocument(
|
||||
|
|
|
@ -7,7 +7,7 @@ import { CodeLensProvider, CodeLens, CancellationToken, TextDocument, Range, Uri
|
|||
import * as Proto from '../protocol';
|
||||
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
import { tsTextSpanToVsRange } from '../utils/convert';
|
||||
import * as typeConverters from '../utils/typeConverters';
|
||||
import { escapeRegExp } from '../utils/regexp';
|
||||
|
||||
export class ReferencesCodeLens extends CodeLens {
|
||||
|
@ -136,7 +136,7 @@ export abstract class TypeScriptBaseCodeLensProvider implements CodeLensProvider
|
|||
return null;
|
||||
}
|
||||
|
||||
const range = tsTextSpanToVsRange(span);
|
||||
const range = typeConverters.Range.fromTextSpan(span);
|
||||
const text = document.getText(range);
|
||||
|
||||
const identifierMatch = new RegExp(`^(.*?(\\b|\\W))${escapeRegExp(item.text || '')}(\\b|\\W)`, 'gm');
|
||||
|
|
|
@ -153,7 +153,7 @@ export default class BufferSyncSupport {
|
|||
private readonly disposables: Disposable[] = [];
|
||||
private readonly syncedBuffers: SyncedBufferMap;
|
||||
|
||||
private pendingDiagnostics = new Map<string, number>();
|
||||
private readonly pendingDiagnostics = new Map<string, number>();
|
||||
private readonly diagnosticDelayer: Delayer<any>;
|
||||
|
||||
constructor(
|
||||
|
@ -271,16 +271,9 @@ export default class BufferSyncSupport {
|
|||
if (!this._validate) {
|
||||
return;
|
||||
}
|
||||
let files = Array.from(this.pendingDiagnostics.entries()).map(([key, value]) => {
|
||||
return {
|
||||
file: key,
|
||||
time: value
|
||||
};
|
||||
}).sort((a, b) => {
|
||||
return a.time - b.time;
|
||||
}).map((value) => {
|
||||
return value.file;
|
||||
});
|
||||
const files = Array.from(this.pendingDiagnostics.entries())
|
||||
.sort((a, b) => a[1] - b[1])
|
||||
.map(entry => entry[0]);
|
||||
|
||||
// Add all open TS buffers to the geterr request. They might be visible
|
||||
for (const file of this.syncedBuffers.allResources) {
|
||||
|
|
|
@ -11,11 +11,10 @@ import TypingsStatus from '../utils/typingsStatus';
|
|||
import * as Proto from '../protocol';
|
||||
import * as PConst from '../protocol.const';
|
||||
import * as Previewer from '../utils/previewer';
|
||||
import { tsTextSpanToVsRange, vsPositionToTsFileLocation } from '../utils/convert';
|
||||
import * as typeConverters from '../utils/typeConverters';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
import { applyCodeAction } from '../utils/codeAction';
|
||||
import * as languageModeIds from '../utils/languageModeIds';
|
||||
import { CommandManager, Command } from '../utils/commandManager';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
@ -51,14 +50,14 @@ class MyCompletionItem extends vscode.CompletionItem {
|
|||
this.useCodeSnippet = useCodeSnippetsOnMethodSuggest && (this.kind === vscode.CompletionItemKind.Function || this.kind === vscode.CompletionItemKind.Method);
|
||||
|
||||
if (tsEntry.replacementSpan) {
|
||||
this.range = tsTextSpanToVsRange(tsEntry.replacementSpan);
|
||||
this.range = typeConverters.Range.fromTextSpan(tsEntry.replacementSpan);
|
||||
}
|
||||
|
||||
if (tsEntry.insertText) {
|
||||
this.insertText = tsEntry.insertText;
|
||||
|
||||
if (tsEntry.replacementSpan) {
|
||||
this.range = tsTextSpanToVsRange(tsEntry.replacementSpan);
|
||||
this.range = typeConverters.Range.fromTextSpan(tsEntry.replacementSpan);
|
||||
if (this.insertText[0] === '[') { // o.x -> o['x']
|
||||
this.filterText = '.' + this.label;
|
||||
}
|
||||
|
@ -281,7 +280,7 @@ export default class TypeScriptCompletionItemProvider implements vscode.Completi
|
|||
}
|
||||
|
||||
const args: Proto.CompletionsRequestArgs = {
|
||||
...vsPositionToTsFileLocation(file, position),
|
||||
...typeConverters.Position.toFileLocationRequestArgs(file, position),
|
||||
includeExternalModuleExports: completionConfiguration.autoImportSuggestions,
|
||||
includeInsertTextCompletions: true
|
||||
};
|
||||
|
@ -330,7 +329,7 @@ export default class TypeScriptCompletionItemProvider implements vscode.Completi
|
|||
item.resolve();
|
||||
|
||||
const args: Proto.CompletionDetailsRequestArgs = {
|
||||
...vsPositionToTsFileLocation(filepath, item.position),
|
||||
...typeConverters.Position.toFileLocationRequestArgs(filepath, item.position),
|
||||
entryNames: [
|
||||
item.tsEntry.source ? { name: item.tsEntry.name, source: item.tsEntry.source } : item.tsEntry.name
|
||||
]
|
||||
|
@ -351,34 +350,74 @@ export default class TypeScriptCompletionItemProvider implements vscode.Completi
|
|||
item.detail = detail.displayParts.length ? Previewer.plain(detail.displayParts) : undefined;
|
||||
item.documentation = this.getDocumentation(detail, item);
|
||||
|
||||
if (detail.codeActions && detail.codeActions.length) {
|
||||
item.command = {
|
||||
title: '',
|
||||
command: ApplyCompletionCodeActionCommand.ID,
|
||||
arguments: [filepath, detail.codeActions]
|
||||
};
|
||||
}
|
||||
const { command, additionalTextEdits } = this.getCodeActions(detail, filepath);
|
||||
item.command = command;
|
||||
item.additionalTextEdits = additionalTextEdits;
|
||||
|
||||
if (detail && item.useCodeSnippet) {
|
||||
const shouldCompleteFunction = await this.isValidFunctionCompletionContext(filepath, item.position);
|
||||
if (shouldCompleteFunction) {
|
||||
item.insertText = this.snippetForFunctionCall(item, detail);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private getCodeActions(
|
||||
detail: Proto.CompletionEntryDetails,
|
||||
filepath: string
|
||||
): { command?: vscode.Command, additionalTextEdits?: vscode.TextEdit[] } {
|
||||
if (!detail.codeActions || !detail.codeActions.length) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Try to extract out the additionalTextEdits for the current file.
|
||||
// Also check if we still have to apply other workspace edits and commands
|
||||
// using a vscode command
|
||||
const additionalTextEdits: vscode.TextEdit[] = [];
|
||||
let hasReaminingCommandsOrEdits = false;
|
||||
for (const tsAction of detail.codeActions) {
|
||||
if (tsAction.commands) {
|
||||
hasReaminingCommandsOrEdits = true;
|
||||
}
|
||||
|
||||
// Apply all edits in the current file using `additionalTextEdits`
|
||||
if (tsAction.changes) {
|
||||
for (const change of tsAction.changes) {
|
||||
if (change.fileName === filepath) {
|
||||
additionalTextEdits.push(...change.textChanges.map(typeConverters.TextEdit.fromCodeEdit));
|
||||
} else {
|
||||
hasReaminingCommandsOrEdits = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let command: vscode.Command | undefined = undefined;
|
||||
if (hasReaminingCommandsOrEdits) {
|
||||
// Create command that applies all edits not in the current file.
|
||||
command = {
|
||||
title: '',
|
||||
command: ApplyCompletionCodeActionCommand.ID,
|
||||
arguments: [filepath, detail.codeActions.map((x): Proto.CodeAction => ({
|
||||
commands: x.commands,
|
||||
description: x.description,
|
||||
changes: x.changes.filter(x => x.fileName !== filepath)
|
||||
}))]
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
command,
|
||||
additionalTextEdits: additionalTextEdits.length ? additionalTextEdits : undefined
|
||||
};
|
||||
}
|
||||
|
||||
private shouldEnableDotCompletions(
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position
|
||||
): boolean {
|
||||
// Only enable dot completions in TS files for now
|
||||
if (document.languageId !== languageModeIds.typescript && document.languageId === languageModeIds.typescriptreact) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Workaround for https://github.com/Microsoft/TypeScript/issues/13456
|
||||
// Only enable dot completions when previous character is an identifier.
|
||||
// Prevents incorrectly completing while typing spread operators.
|
||||
|
@ -455,7 +494,7 @@ export default class TypeScriptCompletionItemProvider implements vscode.Completi
|
|||
// Workaround for https://github.com/Microsoft/TypeScript/issues/12677
|
||||
// Don't complete function calls inside of destructive assigments or imports
|
||||
try {
|
||||
const infoResponse = await this.client.execute('quickinfo', vsPositionToTsFileLocation(filepath, position));
|
||||
const infoResponse = await this.client.execute('quickinfo', typeConverters.Position.toFileLocationRequestArgs(filepath, position));
|
||||
const info = infoResponse.body;
|
||||
switch (info && info.kind) {
|
||||
case 'var':
|
||||
|
|
|
@ -7,11 +7,11 @@ import { TextDocument, Position, CancellationToken, Location } from 'vscode';
|
|||
|
||||
import * as Proto from '../protocol';
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
import { tsTextSpanToVsRange, vsPositionToTsFileLocation } from '../utils/convert';
|
||||
import * as typeConverters from '../utils/typeConverters';
|
||||
|
||||
export default class TypeScriptDefinitionProviderBase {
|
||||
constructor(
|
||||
private client: ITypeScriptServiceClient
|
||||
private readonly client: ITypeScriptServiceClient
|
||||
) { }
|
||||
|
||||
protected async getSymbolLocations(
|
||||
|
@ -25,19 +25,12 @@ export default class TypeScriptDefinitionProviderBase {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const args = vsPositionToTsFileLocation(filepath, position);
|
||||
const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position);
|
||||
try {
|
||||
const response = await this.client.execute(definitionType, args, token);
|
||||
const locations: Proto.FileSpan[] = (response && response.body) || [];
|
||||
if (!locations || locations.length === 0) {
|
||||
return [];
|
||||
}
|
||||
return locations.map(location => {
|
||||
const resource = this.client.asUrl(location.file);
|
||||
return resource
|
||||
? new Location(resource, tsTextSpanToVsRange(location))
|
||||
: undefined;
|
||||
}).filter(x => x) as Location[];
|
||||
return locations.map(location =>
|
||||
typeConverters.Location.fromTextSpan(this.client.asUrl(location.file), location));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -30,18 +30,27 @@ class DiagnosticSet {
|
|||
}
|
||||
}
|
||||
|
||||
export default class DiagnosticsManager {
|
||||
export enum DiagnosticKind {
|
||||
Syntax,
|
||||
Semantic,
|
||||
Suggestion
|
||||
}
|
||||
|
||||
private readonly syntaxDiagnostics: DiagnosticSet;
|
||||
private readonly semanticDiagnostics: DiagnosticSet;
|
||||
const allDiagnosticKinds = [DiagnosticKind.Syntax, DiagnosticKind.Semantic, DiagnosticKind.Suggestion];
|
||||
|
||||
export class DiagnosticsManager {
|
||||
|
||||
private readonly diagnostics = new Map<DiagnosticKind, DiagnosticSet>();
|
||||
private readonly currentDiagnostics: DiagnosticCollection;
|
||||
private _validate: boolean = true;
|
||||
|
||||
constructor(
|
||||
language: string
|
||||
) {
|
||||
this.syntaxDiagnostics = new DiagnosticSet();
|
||||
this.semanticDiagnostics = new DiagnosticSet();
|
||||
for (const kind of allDiagnosticKinds) {
|
||||
this.diagnostics.set(kind, new DiagnosticSet());
|
||||
}
|
||||
|
||||
this.currentDiagnostics = languages.createDiagnosticCollection(language);
|
||||
}
|
||||
|
||||
|
@ -51,8 +60,10 @@ export default class DiagnosticsManager {
|
|||
|
||||
public reInitialize(): void {
|
||||
this.currentDiagnostics.clear();
|
||||
this.syntaxDiagnostics.clear();
|
||||
this.semanticDiagnostics.clear();
|
||||
|
||||
for (const diagnosticSet of this.diagnostics.values()) {
|
||||
diagnosticSet.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public set validate(value: boolean) {
|
||||
|
@ -65,14 +76,16 @@ export default class DiagnosticsManager {
|
|||
}
|
||||
}
|
||||
|
||||
public syntaxDiagnosticsReceived(file: Uri, syntaxDiagnostics: Diagnostic[]): void {
|
||||
this.syntaxDiagnostics.set(file, syntaxDiagnostics);
|
||||
this.updateCurrentDiagnostics(file);
|
||||
}
|
||||
|
||||
public semanticDiagnosticsReceived(file: Uri, semanticDiagnostics: Diagnostic[]): void {
|
||||
this.semanticDiagnostics.set(file, semanticDiagnostics);
|
||||
this.updateCurrentDiagnostics(file);
|
||||
public diagnosticsReceived(
|
||||
kind: DiagnosticKind,
|
||||
file: Uri,
|
||||
syntaxDiagnostics: Diagnostic[]
|
||||
): void {
|
||||
const diagnostics = this.diagnostics.get(kind);
|
||||
if (diagnostics) {
|
||||
diagnostics.set(file, syntaxDiagnostics);
|
||||
this.updateCurrentDiagnostics(file);
|
||||
}
|
||||
}
|
||||
|
||||
public configFileDiagnosticsReceived(file: Uri, diagnostics: Diagnostic[]): void {
|
||||
|
@ -88,9 +101,11 @@ export default class DiagnosticsManager {
|
|||
return;
|
||||
}
|
||||
|
||||
const semanticDiagnostics = this.semanticDiagnostics.get(file);
|
||||
const syntaxDiagnostics = this.syntaxDiagnostics.get(file);
|
||||
this.currentDiagnostics.set(file, semanticDiagnostics.concat(syntaxDiagnostics));
|
||||
const allDiagnostics = allDiagnosticKinds.reduce((sum, kind) => {
|
||||
sum.push(...this.diagnostics.get(kind)!.get(file));
|
||||
return sum;
|
||||
}, [] as Diagnostic[]);
|
||||
this.currentDiagnostics.set(file, allDiagnostics);
|
||||
}
|
||||
|
||||
public getDiagnostics(file: Uri): Diagnostic[] {
|
||||
|
|
|
@ -36,7 +36,7 @@ const directives: Directive[] = [
|
|||
|
||||
export default class DirectiveCommentCompletionProvider implements CompletionItemProvider {
|
||||
constructor(
|
||||
private client: ITypeScriptServiceClient,
|
||||
private readonly client: ITypeScriptServiceClient,
|
||||
) { }
|
||||
|
||||
public provideCompletionItems(
|
||||
|
|