Skip to content

Commit b74b36b

Browse files
committed
Fixes microsoft#13266: TSC version mismatch shouldn't be shown for JavaScript
1 parent 4a15897 commit b74b36b

3 files changed

Lines changed: 106 additions & 76 deletions

File tree

extensions/typescript/src/features/bufferSyncSupport.ts

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@
44
*--------------------------------------------------------------------------------------------*/
55
'use strict';
66

7+
import * as cp from 'child_process';
78
import * as path from 'path';
89
import * as fs from 'fs';
910

10-
import { workspace, TextDocument, TextDocumentChangeEvent, TextDocumentContentChangeEvent, Disposable } from 'vscode';
11+
import { workspace, window, TextDocument, TextDocumentChangeEvent, TextDocumentContentChangeEvent, Disposable, MessageItem } from 'vscode';
1112
import * as Proto from '../protocol';
1213
import { ITypescriptServiceClient } from '../typescriptService';
1314
import { Delayer } from '../utils/async';
1415
import LinkedMap from './linkedMap';
1516

17+
import * as nls from 'vscode-nls';
18+
let localize = nls.loadMessageBundle();
19+
1620
interface IDiagnosticRequestor {
1721
requestDiagnostic(filepath: string): void;
1822
}
@@ -96,6 +100,7 @@ export interface Diagnostics {
96100
delete(file: string): void;
97101
}
98102

103+
const checkTscVersionSettingKey = 'check.tscVersion';
99104
export default class BufferSyncSupport {
100105

101106
private client: ITypescriptServiceClient;
@@ -112,6 +117,7 @@ export default class BufferSyncSupport {
112117
private pendingDiagnostics: { [key: string]: number; };
113118
private diagnosticDelayer: Delayer<any>;
114119
private emitQueue: LinkedMap<string>;
120+
private checkGlobalTSCVersion: boolean;
115121

116122
constructor(client: ITypescriptServiceClient, modeIds: string[], diagnostics: Diagnostics, extensions: Map<boolean>, validate: boolean = true) {
117123
this.client = client;
@@ -128,6 +134,9 @@ export default class BufferSyncSupport {
128134

129135
this.syncedBuffers = Object.create(null);
130136
this.emitQueue = new LinkedMap<string>();
137+
138+
const tsConfig = workspace.getConfiguration('typescript');
139+
this.checkGlobalTSCVersion = client.checkGlobalTSCVersion && this.modeIds['typescript'] === true && tsConfig.get(checkTscVersionSettingKey, true);
131140
}
132141

133142
public listen(): void {
@@ -178,6 +187,7 @@ export default class BufferSyncSupport {
178187
this.syncedBuffers[filepath] = syncedBuffer;
179188
syncedBuffer.open();
180189
this.requestDiagnostic(filepath);
190+
this.checkTSCVersion();
181191
}
182192

183193
private onDidCloseTextDocument(document: TextDocument): void {
@@ -276,4 +286,74 @@ export default class BufferSyncSupport {
276286
this.client.execute('geterr', args, false);
277287
this.pendingDiagnostics = Object.create(null);
278288
}
289+
290+
private checkTSCVersion() {
291+
if (!this.checkGlobalTSCVersion) {
292+
return;
293+
}
294+
this.checkGlobalTSCVersion = false;
295+
296+
interface MyMessageItem extends MessageItem {
297+
id: number;
298+
}
299+
300+
function openUrl(url: string) {
301+
let cmd: string;
302+
switch (process.platform) {
303+
case 'darwin':
304+
cmd = 'open';
305+
break;
306+
case 'win32':
307+
cmd = 'start';
308+
break;
309+
default:
310+
cmd = 'xdg-open';
311+
}
312+
return cp.exec(cmd + ' ' + url);
313+
}
314+
315+
let tscVersion: string = undefined;
316+
try {
317+
let out = cp.execSync('tsc --version', { encoding: 'utf8' });
318+
if (out) {
319+
let matches = out.trim().match(/Version\s*(.*)$/);
320+
if (matches && matches.length === 2) {
321+
tscVersion = matches[1];
322+
}
323+
}
324+
} catch (error) {
325+
}
326+
if (tscVersion && tscVersion !== this.client.apiVersion.versionString) {
327+
window.showInformationMessage<MyMessageItem>(
328+
localize('versionMismatch', 'Version mismatch! global tsc ({0}) != VS Code\'s language service ({1}). Inconsistent compile errors might occur', tscVersion, this.client.apiVersion.versionString),
329+
{
330+
title: localize('moreInformation', 'More Information'),
331+
id: 1
332+
},
333+
{
334+
title: localize('doNotCheckAgain', 'Don\'t Check Again'),
335+
id: 2
336+
},
337+
{
338+
title: localize('close', 'Close'),
339+
id: 3,
340+
isCloseAffordance: true
341+
}
342+
).then((selected) => {
343+
if (!selected || selected.id === 3) {
344+
return;
345+
}
346+
switch (selected.id) {
347+
case 1:
348+
openUrl('http://go.microsoft.com/fwlink/?LinkId=826239');
349+
break;
350+
case 2:
351+
const tsConfig = workspace.getConfiguration('typescript');
352+
tsConfig.update(checkTscVersionSettingKey, false, true);
353+
window.showInformationMessage(localize('updateTscCheck', 'Updated user setting \'typescript.check.tscVersion\' to false'));
354+
break;
355+
}
356+
});
357+
}
358+
}
279359
}

extensions/typescript/src/typescriptService.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,36 @@ export interface ITypescriptServiceClientHost {
1818

1919
export class API {
2020

21-
private version: string;
21+
private _version: string;
2222

23-
constructor(version: string) {
24-
this.version = semver.valid(version);
25-
if (!this.version) {
26-
this.version = '1.0.0';
23+
constructor(private _versionString: string) {
24+
this._version = semver.valid(_versionString);
25+
if (!this._version) {
26+
this._version = '1.0.0';
2727
} else {
2828
// Cut of any prerelease tag since we sometimes consume those
2929
// on purpose.
30-
let index = version.indexOf('-');
30+
let index = _versionString.indexOf('-');
3131
if (index >= 0) {
32-
this.version = this.version.substr(0, index);
32+
this._version = this._version.substr(0, index);
3333
}
3434
}
3535
}
3636

37+
public get versionString(): string {
38+
return this._versionString;
39+
}
40+
3741
public has1xFeatures(): boolean {
38-
return semver.gte(this.version, '1.0.0');
42+
return semver.gte(this._version, '1.0.0');
3943
}
4044

4145
public has203Features(): boolean {
42-
return semver.gte(this.version, '2.0.3');
46+
return semver.gte(this._version, '2.0.3');
4347
}
4448

4549
public has206Features(): boolean {
46-
return semver.gte(this.version, '2.0.6');
50+
return semver.gte(this._version, '2.0.6');
4751
}
4852
}
4953

@@ -59,6 +63,7 @@ export interface ITypescriptServiceClient {
5963

6064
experimentalAutoBuild: boolean;
6165
apiVersion: API;
66+
checkGlobalTSCVersion: boolean;
6267

6368
execute(command: 'configure', args: Proto.ConfigureRequestArguments, token?: CancellationToken): Promise<Proto.ConfigureResponse>;
6469
execute(command: 'open', args: Proto.OpenRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise<any>;

extensions/typescript/src/typescriptServiceClient.ts

Lines changed: 10 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,6 @@ interface MyMessageItem extends MessageItem {
7777
id: MessageAction;
7878
}
7979

80-
81-
function openUrl(url: string) {
82-
let cmd: string;
83-
switch (process.platform) {
84-
case 'darwin':
85-
cmd = 'open';
86-
break;
87-
case 'win32':
88-
cmd = 'start';
89-
break;
90-
default:
91-
cmd = 'xdg-open';
92-
}
93-
return cp.exec(cmd + ' ' + url);
94-
}
95-
96-
9780
export default class TypeScriptServiceClient implements ITypescriptServiceClient {
9881

9982
private host: ITypescriptServiceClientHost;
@@ -103,6 +86,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
10386

10487
private _onReady: { promise: Promise<void>; resolve: () => void; reject: () => void; };
10588
private tsdk: string;
89+
private _checkGlobalTSCVersion: boolean;
10690
private _experimentalAutoBuild: boolean;
10791
private trace: Trace;
10892
private _output: OutputChannel;
@@ -148,6 +132,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
148132
this.tsdk = configuration.get<string>('typescript.tsdk', null);
149133
this._experimentalAutoBuild = false; // configuration.get<boolean>('typescript.tsserver.experimentalAutoBuild', false);
150134
this._apiVersion = new API('1.0.0');
135+
this._checkGlobalTSCVersion = true;
151136
this.trace = this.readTrace();
152137
workspace.onDidChangeConfiguration(() => {
153138
this.trace = this.readTrace();
@@ -182,6 +167,10 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
182167
return this._experimentalAutoBuild;
183168
}
184169

170+
public get checkGlobalTSCVersion(): boolean {
171+
return this._checkGlobalTSCVersion;
172+
}
173+
185174
public get apiVersion(): API {
186175
return this._apiVersion;
187176
}
@@ -280,11 +269,10 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
280269

281270
private startService(resendModels: boolean = false): void {
282271
let modulePath = path.join(__dirname, '..', 'node_modules', 'typescript', 'lib', 'tsserver.js');
283-
let checkGlobalVersion = true;
284272
let showVersionStatusItem = false;
285273

286274
if (this.tsdk) {
287-
checkGlobalVersion = false;
275+
this._checkGlobalTSCVersion = false;
288276
if ((<any>path).isAbsolute(this.tsdk)) {
289277
modulePath = path.join(this.tsdk, 'tsserver.js');
290278
} else if (workspace.rootPath) {
@@ -306,7 +294,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
306294
let localVersion = this.getTypeScriptVersion(localModulePath);
307295
let shippedVersion = this.getTypeScriptVersion(modulePath);
308296
if (localVersion && localVersion !== shippedVersion) {
309-
checkGlobalVersion = false;
297+
this._checkGlobalTSCVersion = false;
310298
versionCheckPromise = window.showInformationMessage<MyMessageItem>(
311299
localize(
312300
'localTSFound',
@@ -385,58 +373,15 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
385373
VersionStatus.enable(!!this.tsdk || showVersionStatusItem);
386374
VersionStatus.setInfo(label, tooltip);
387375

376+
// This is backwards compatibility code to move the setting from the local
377+
// store into the workspace setting file.
388378
const doGlobalVersionCheckKey: string = 'doGlobalVersionCheck';
389379
const globalStateValue = this.globalState.get(doGlobalVersionCheckKey, true);
390380
const checkTscVersion = 'check.tscVersion';
391381
if (!globalStateValue) {
392382
tsConfig.update(checkTscVersion, false, true);
393383
this.globalState.update(doGlobalVersionCheckKey, true);
394384
}
395-
if (checkGlobalVersion && tsConfig.get(checkTscVersion)) {
396-
let tscVersion: string = undefined;
397-
try {
398-
let out = cp.execSync('tsc --version', { encoding: 'utf8' });
399-
if (out) {
400-
let matches = out.trim().match(/Version\s*(.*)$/);
401-
if (matches && matches.length === 2) {
402-
tscVersion = matches[1];
403-
}
404-
}
405-
} catch (error) {
406-
}
407-
if (tscVersion && tscVersion !== version) {
408-
window.showInformationMessage<MyMessageItem>(
409-
localize('versionMismatch', 'Version mismatch! global tsc ({0}) != VS Code\'s language service ({1}). Inconsistent compile errors might occur', tscVersion, version),
410-
{
411-
title: localize('moreInformation', 'More Information'),
412-
id: 1
413-
},
414-
{
415-
title: localize('doNotCheckAgain', 'Don\'t Check Again'),
416-
id: 2
417-
},
418-
{
419-
title: localize('close', 'Close'),
420-
id: 3,
421-
isCloseAffordance: true
422-
}
423-
).then((selected) => {
424-
if (!selected || selected.id === 3) {
425-
return;
426-
}
427-
switch (selected.id) {
428-
case 1:
429-
openUrl('http://go.microsoft.com/fwlink/?LinkId=826239');
430-
break;
431-
case 2:
432-
tsConfig.update(checkTscVersion, false, true);
433-
window.showInformationMessage(localize('updateTscCheck', 'Updated user setting \'typescript.check.tscVersion\' to false'));
434-
this.globalState.update(doGlobalVersionCheckKey, false);
435-
break;
436-
}
437-
});
438-
}
439-
}
440385

441386
try {
442387
let options: electron.IForkOptions = {

0 commit comments

Comments
 (0)