Skip to content

Commit

Permalink
Merge pull request #11713 from Microsoft/PortSkipSemanticCheckToRelea…
Browse files Browse the repository at this point in the history
…se-2-0-5

Port skip semantic check to release-2.0.5
  • Loading branch information
jramsay committed Oct 18, 2016
2 parents cca3c1f + c63b69d commit 3ab3d95
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ namespace ts {
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {

const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json"
? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true }
? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true }
: {};
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
return options;
Expand Down
8 changes: 6 additions & 2 deletions src/harness/unittests/convertCompilerOptionsFromJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ namespace ts {
allowJs: true,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true,
skipLibCheck: true,
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
Expand Down Expand Up @@ -433,6 +434,7 @@ namespace ts {
allowJs: false,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true,
skipLibCheck: true,
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
Expand All @@ -456,7 +458,8 @@ namespace ts {
{
allowJs: true,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true
allowSyntheticDefaultImports: true,
skipLibCheck: true
},
errors: [{
file: undefined,
Expand All @@ -477,7 +480,8 @@ namespace ts {
{
allowJs: true,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true
allowSyntheticDefaultImports: true,
skipLibCheck: true
},
errors: <Diagnostic[]>[]
}
Expand Down
92 changes: 84 additions & 8 deletions src/harness/unittests/tsserverProjectSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace ts.projectSystem {
import TI = server.typingsInstaller;
import protocol = server.protocol;
import CommandNames = server.CommandNames;

const safeList = {
Expand Down Expand Up @@ -125,7 +126,7 @@ namespace ts.projectSystem {
return combinePaths(getDirectoryPath(libFile.path), "tsc.js");
}

export function toExternalFile(fileName: string): server.protocol.ExternalFile {
export function toExternalFile(fileName: string): protocol.ExternalFile {
return { fileName };
}

Expand Down Expand Up @@ -551,7 +552,7 @@ namespace ts.projectSystem {
}

export function makeSessionRequest<T>(command: string, args: T) {
const newRequest: server.protocol.Request = {
const newRequest: protocol.Request = {
seq: 0,
type: "request",
command,
Expand All @@ -562,7 +563,7 @@ namespace ts.projectSystem {

export function openFilesForSession(files: FileOrFolder[], session: server.Session) {
for (const file of files) {
const request = makeSessionRequest<server.protocol.OpenRequestArgs>(CommandNames.Open, { file: file.path });
const request = makeSessionRequest<protocol.OpenRequestArgs>(CommandNames.Open, { file: file.path });
session.executeCommand(request);
}
}
Expand Down Expand Up @@ -1775,7 +1776,7 @@ namespace ts.projectSystem {
});

describe("navigate-to for javascript project", () => {
function containsNavToItem(items: server.protocol.NavtoItem[], itemName: string, itemKind: string) {
function containsNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) {
return find(items, item => item.name === itemName && item.kind === itemKind) !== undefined;
}

Expand All @@ -1793,12 +1794,12 @@ namespace ts.projectSystem {
openFilesForSession([file1], session);

// Try to find some interface type defined in lib.d.ts
const libTypeNavToRequest = makeSessionRequest<server.protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path });
const items: server.protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response;
const libTypeNavToRequest = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path });
const items: protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response;
assert.isFalse(containsNavToItem(items, "Document", "interface"), `Found lib.d.ts symbol in JavaScript project nav to request result.`);

const localFunctionNavToRequst = makeSessionRequest<server.protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
const items2: server.protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response;
const localFunctionNavToRequst = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
const items2: protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response;
assert.isTrue(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`);
});
});
Expand Down Expand Up @@ -2245,7 +2246,82 @@ namespace ts.projectSystem {
// verify content
const snap2 = projectServiice.getScriptInfo(f1.path).snap();
assert.equal(snap2.getText(0, snap2.getLength()), f1.content, "content should be equal to the content of original file");
});
});

describe("skipLibCheck", () => {
it("should be turned on for js-only inferred projects", () => {
const file1 = {
path: "/a/b/file1.js",
content: `
/// <reference path="file2.d.ts" />
var x = 1;`
};
const file2 = {
path: "/a/b/file2.d.ts",
content: `
interface T {
name: string;
};
interface T {
name: number;
};`
};
const host = createServerHost([file1, file2]);
const session = createSession(host);
openFilesForSession([file1, file2], session);

const file2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
CommandNames.SemanticDiagnosticsSync,
{ file: file2.path }
);
let errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length === 0);

const closeFileRequest = makeSessionRequest<protocol.FileRequestArgs>(CommandNames.Close, { file: file1.path });
session.executeCommand(closeFileRequest);
errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length !== 0);

openFilesForSession([file1], session);
errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length === 0);
});

it("should be turned on for js-only external projects", () => {
const jsFile = {
path: "/a/b/file1.js",
content: "let x =1;"
};
const dTsFile = {
path: "/a/b/file2.d.ts",
content: `
interface T {
name: string;
};
interface T {
name: number;
};`
};
const host = createServerHost([jsFile, dTsFile]);
const session = createSession(host);

const openExternalProjectRequest = makeSessionRequest<protocol.OpenExternalProjectArgs>(
CommandNames.OpenExternalProject,
{
projectFileName: "project1",
rootFiles: toExternalFiles([jsFile.path, dTsFile.path]),
options: {}
}
);
session.executeCommand(openExternalProjectRequest);

const dTsFileGetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
CommandNames.SemanticDiagnosticsSync,
{ file: dTsFile.path }
);
const errorResult = <protocol.Diagnostic[]>session.executeCommand(dTsFileGetErrRequest).response;
assert.isTrue(errorResult.length === 0);
});
});
}
34 changes: 32 additions & 2 deletions src/server/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,41 @@ namespace ts.server {
}

getSyntacticDiagnostics(fileName: string): Diagnostic[] {
throw new Error("Not Implemented Yet.");
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName, includeLinePosition: true };

const request = this.processRequest<protocol.SyntacticDiagnosticsSyncRequest>(CommandNames.SyntacticDiagnosticsSync, args);
const response = this.processResponse<protocol.SyntacticDiagnosticsSyncResponse>(request);

return (<protocol.DiagnosticWithLinePosition[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
}

getSemanticDiagnostics(fileName: string): Diagnostic[] {
throw new Error("Not Implemented Yet.");
const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName, includeLinePosition: true };

const request = this.processRequest<protocol.SemanticDiagnosticsSyncRequest>(CommandNames.SemanticDiagnosticsSync, args);
const response = this.processResponse<protocol.SemanticDiagnosticsSyncResponse>(request);

return (<protocol.DiagnosticWithLinePosition[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
}

convertDiagnostic(entry: protocol.DiagnosticWithLinePosition, fileName: string): Diagnostic {
let category: DiagnosticCategory;
for (const id in DiagnosticCategory) {
if (typeof id === "string" && entry.category === id.toLowerCase()) {
category = (<any>DiagnosticCategory)[id];
}
}

Debug.assert(category !== undefined, "convertDiagnostic: category should not be undefined");

return {
file: undefined,
start: entry.start,
length: entry.length,
messageText: entry.message,
category: category,
code: entry.code
};
}

getCompilerOptionsDiagnostics(): Diagnostic[] {
Expand Down
41 changes: 36 additions & 5 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,42 @@ namespace ts.server {
}
}

function isJsOrDtsFile(info: ScriptInfo) {
return info.scriptKind === ScriptKind.JS || info.scriptKind == ScriptKind.JSX || fileExtensionIs(info.fileName, ".d.ts");
function countEachFileTypes(infos: ScriptInfo[]): { js: number, jsx: number, ts: number, tsx: number, dts: number } {
const result = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0 };
for (const info of infos) {
switch (info.scriptKind) {
case ScriptKind.JS:
result.js += 1;
break;
case ScriptKind.JSX:
result.jsx += 1;
break;
case ScriptKind.TS:
fileExtensionIs(info.fileName, ".d.ts")
? result.dts += 1
: result.ts += 1;
break;
case ScriptKind.TSX:
result.tsx += 1;
break;
}
}
return result;
}

function hasOneOrMoreJsAndNoTsFiles(project: Project) {
const counts = countEachFileTypes(project.getScriptInfos());
return counts.js > 0 && counts.ts === 0 && counts.tsx === 0;
}

export function allRootFilesAreJsOrDts(project: Project): boolean {
return project.getRootScriptInfos().every(isJsOrDtsFile);
const counts = countEachFileTypes(project.getRootScriptInfos());
return counts.ts === 0 && counts.tsx === 0;
}

export function allFilesAreJsOrDts(project: Project): boolean {
return project.getScriptInfos().every(isJsOrDtsFile);
const counts = countEachFileTypes(project.getScriptInfos());
return counts.ts === 0 && counts.tsx === 0;
}

export interface ProjectFilesWithTSDiagnostics extends protocol.ProjectFiles {
Expand Down Expand Up @@ -71,11 +97,16 @@ namespace ts.server {

public typesVersion = 0;

public isJsOnlyProject() {
public isNonTsProject() {
this.updateGraph();
return allFilesAreJsOrDts(this);
}

public isJsOnlyProject() {
this.updateGraph();
return hasOneOrMoreJsAndNoTsFiles(this);
}

constructor(
readonly projectKind: ProjectKind,
readonly projectService: ProjectService,
Expand Down
35 changes: 25 additions & 10 deletions src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ namespace ts.server {
return ((1e9 * seconds) + nanoseconds) / 1000000.0;
}

function shouldSkipSemanticCheck(project: Project) {
if (project.getCompilerOptions().skipLibCheck !== undefined) {
return false;
}

if ((project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) && project.isJsOnlyProject()) {
return true;
}
return false;
}

interface FileStart {
file: string;
start: ILineInfo;
Expand Down Expand Up @@ -255,12 +266,13 @@ namespace ts.server {

private semanticCheck(file: NormalizedPath, project: Project) {
try {
const diags = project.getLanguageService().getSemanticDiagnostics(file);

if (diags) {
const bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag");
let diags: Diagnostic[] = [];
if (!shouldSkipSemanticCheck(project)) {
diags = project.getLanguageService().getSemanticDiagnostics(file);
}

const bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag");
}
catch (err) {
this.logError(err, "semantic check");
Expand Down Expand Up @@ -371,8 +383,11 @@ namespace ts.server {
});
}

private getDiagnosticsWorker(args: protocol.FileRequestArgs, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
private getDiagnosticsWorker(args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
const { project, file } = this.getFileAndProject(args);
if (isSemantic && shouldSkipSemanticCheck(project)) {
return [];
}
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const diagnostics = selector(project, file);
return includeLinePosition
Expand Down Expand Up @@ -451,11 +466,11 @@ namespace ts.server {
}

private getSyntacticDiagnosticsSync(args: protocol.SyntacticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
return this.getDiagnosticsWorker(args, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
}

private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): protocol.Diagnostic[] | protocol.DiagnosticWithLinePosition[] {
return this.getDiagnosticsWorker(args, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
}

private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): protocol.DocumentHighlightsItem[] | DocumentHighlights[] {
Expand Down Expand Up @@ -1122,7 +1137,7 @@ namespace ts.server {
return combineProjectOutput(
projects,
project => {
const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, /*excludeDts*/ project.isJsOnlyProject());
const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, /*excludeDts*/ project.isNonTsProject());
if (!navItems) {
return [];
}
Expand Down Expand Up @@ -1160,7 +1175,7 @@ namespace ts.server {
else {
return combineProjectOutput(
projects,
project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, /*excludeDts*/ project.isJsOnlyProject()),
project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, /*excludeDts*/ project.isNonTsProject()),
/*comparer*/ undefined,
navigateToItemIsEqualTo);
}
Expand Down

0 comments on commit 3ab3d95

Please sign in to comment.