Skip to content

Commit 0ff475f

Browse files
committed
Merge remote-tracking branch 'origin/master' into release-2.3
2 parents ea64184 + 24814ec commit 0ff475f

23 files changed

+399
-126
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ namespace ts {
574574
recordMergedSymbol(target, source);
575575
}
576576
else if (target.flags & SymbolFlags.NamespaceModule) {
577-
error(source.valueDeclaration.name, Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
577+
error(source.declarations[0].name, Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
578578
}
579579
else {
580580
const message = target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable

src/compiler/commandLineParser.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,10 +1111,11 @@ namespace ts {
11111111
const jsonOptions = json["typeAcquisition"] || json["typingOptions"];
11121112
const typeAcquisition: TypeAcquisition = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName);
11131113

1114+
let baseCompileOnSave: boolean;
11141115
if (json["extends"]) {
11151116
let [include, exclude, files, baseOptions]: [string[], string[], string[], CompilerOptions] = [undefined, undefined, undefined, {}];
11161117
if (typeof json["extends"] === "string") {
1117-
[include, exclude, files, baseOptions] = (tryExtendsName(json["extends"]) || [include, exclude, files, baseOptions]);
1118+
[include, exclude, files, baseCompileOnSave, baseOptions] = (tryExtendsName(json["extends"]) || [include, exclude, files, baseCompileOnSave, baseOptions]);
11181119
}
11191120
else {
11201121
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
@@ -1135,7 +1136,10 @@ namespace ts {
11351136
options.configFilePath = configFileName;
11361137

11371138
const { fileNames, wildcardDirectories } = getFileNames(errors);
1138-
const compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
1139+
let compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
1140+
if (baseCompileOnSave && json[compileOnSaveCommandLineOption.name] === undefined) {
1141+
compileOnSave = baseCompileOnSave;
1142+
}
11391143

11401144
return {
11411145
options,
@@ -1147,7 +1151,7 @@ namespace ts {
11471151
compileOnSave
11481152
};
11491153

1150-
function tryExtendsName(extendedConfig: string): [string[], string[], string[], CompilerOptions] {
1154+
function tryExtendsName(extendedConfig: string): [string[], string[], string[], boolean, CompilerOptions] {
11511155
// If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future)
11521156
if (!(isRootedDiskPath(extendedConfig) || startsWith(normalizeSlashes(extendedConfig), "./") || startsWith(normalizeSlashes(extendedConfig), "../"))) {
11531157
errors.push(createCompilerDiagnostic(Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig));
@@ -1177,7 +1181,7 @@ namespace ts {
11771181
return map(extendedResult.config[key], updatePath);
11781182
}
11791183
});
1180-
return [include, exclude, files, result.options];
1184+
return [include, exclude, files, result.compileOnSave, result.options];
11811185
}
11821186

11831187
function getFileNames(errors: Diagnostic[]): ExpandResult {
@@ -1245,7 +1249,7 @@ namespace ts {
12451249
}
12461250
}
12471251

1248-
export function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Diagnostic[]): boolean {
1252+
export function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Diagnostic[]): boolean | undefined {
12491253
if (!hasProperty(jsonOption, compileOnSaveCommandLineOption.name)) {
12501254
return false;
12511255
}

src/compiler/program.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,13 @@ namespace ts {
908908

909909
function getSemanticDiagnosticsForFileNoCache(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
910910
return runWithCancellationToken(() => {
911+
// If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
912+
// If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
913+
// '/// <reference no-default-lib="true"/>' directive.
914+
if (options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) {
915+
return emptyArray;
916+
}
917+
911918
const typeChecker = getDiagnosticsProducingTypeChecker();
912919

913920
Debug.assert(!!sourceFile.bindDiagnostics);

src/compiler/transformers/es2015.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2714,9 +2714,8 @@ namespace ts {
27142714
loopBody = createBlock([loopBody], /*multiline*/ true);
27152715
}
27162716

2717-
const isAsyncBlockContainingAwait =
2718-
hierarchyFacts & HierarchyFacts.AsyncFunctionBody
2719-
&& (node.statement.transformFlags & TransformFlags.ContainsYield) !== 0;
2717+
const containsYield = (node.statement.transformFlags & TransformFlags.ContainsYield) !== 0;
2718+
const isAsyncBlockContainingAwait = containsYield && (hierarchyFacts & HierarchyFacts.AsyncFunctionBody) !== 0;
27202719

27212720
let loopBodyFlags: EmitFlags = 0;
27222721
if (currentState.containsLexicalThis) {
@@ -2739,7 +2738,7 @@ namespace ts {
27392738
setEmitFlags(
27402739
createFunctionExpression(
27412740
/*modifiers*/ undefined,
2742-
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
2741+
containsYield ? createToken(SyntaxKind.AsteriskToken) : undefined,
27432742
/*name*/ undefined,
27442743
/*typeParameters*/ undefined,
27452744
loopParameters,
@@ -2833,7 +2832,7 @@ namespace ts {
28332832
));
28342833
}
28352834

2836-
const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, isAsyncBlockContainingAwait);
2835+
const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, containsYield);
28372836

28382837
let loop: Statement;
28392838
if (convert) {

src/harness/unittests/compileOnSave.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,29 @@ namespace ts.projectSystem {
317317
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, []);
318318
});
319319

320+
it("should save when compileOnSave is enabled in base tsconfig.json", () => {
321+
configFile = {
322+
path: "/a/b/tsconfig.json",
323+
content: `{
324+
"extends": "/a/tsconfig.json"
325+
}`
326+
};
327+
328+
const configFile2: FileOrFolder = {
329+
path: "/a/tsconfig.json",
330+
content: `{
331+
"compileOnSave": true
332+
}`
333+
};
334+
335+
const host = createServerHost([moduleFile1, file1Consumer1, file1Consumer2, configFile2, configFile, libFile]);
336+
const typingsInstaller = createTestTypingsInstaller(host);
337+
const session = createSession(host, typingsInstaller);
338+
339+
openFilesForSession([moduleFile1, file1Consumer1], session);
340+
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
341+
});
342+
320343
it("should always return the file itself if '--isolatedModules' is specified", () => {
321344
configFile = {
322345
path: "/a/b/tsconfig.json",

src/harness/unittests/tsserverProjectSystem.ts

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3204,6 +3204,122 @@ namespace ts.projectSystem {
32043204
const errorResult = <protocol.Diagnostic[]>session.executeCommand(dTsFileGetErrRequest).response;
32053205
assert.isTrue(errorResult.length === 0);
32063206
});
3207+
3208+
it("should not report bind errors for declaration files with skipLibCheck=true", () => {
3209+
const jsconfigFile = {
3210+
path: "/a/jsconfig.json",
3211+
content: "{}"
3212+
};
3213+
const jsFile = {
3214+
path: "/a/jsFile.js",
3215+
content: "let x = 1;"
3216+
};
3217+
const dTsFile1 = {
3218+
path: "/a/dTsFile1.d.ts",
3219+
content: `
3220+
declare var x: number;`
3221+
};
3222+
const dTsFile2 = {
3223+
path: "/a/dTsFile2.d.ts",
3224+
content: `
3225+
declare var x: string;`
3226+
};
3227+
const host = createServerHost([jsconfigFile, jsFile, dTsFile1, dTsFile2]);
3228+
const session = createSession(host);
3229+
openFilesForSession([jsFile], session);
3230+
3231+
const dTsFile1GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
3232+
CommandNames.SemanticDiagnosticsSync,
3233+
{ file: dTsFile1.path }
3234+
);
3235+
const error1Result = <protocol.Diagnostic[]>session.executeCommand(dTsFile1GetErrRequest).response;
3236+
assert.isTrue(error1Result.length === 0);
3237+
3238+
const dTsFile2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
3239+
CommandNames.SemanticDiagnosticsSync,
3240+
{ file: dTsFile2.path }
3241+
);
3242+
const error2Result = <protocol.Diagnostic[]>session.executeCommand(dTsFile2GetErrRequest).response;
3243+
assert.isTrue(error2Result.length === 0);
3244+
});
3245+
3246+
it("should report semanitc errors for loose JS files with '// @ts-check' and skipLibCheck=true", () => {
3247+
const jsFile = {
3248+
path: "/a/jsFile.js",
3249+
content: `
3250+
// @ts-check
3251+
let x = 1;
3252+
x === "string";`
3253+
};
3254+
3255+
const host = createServerHost([jsFile]);
3256+
const session = createSession(host);
3257+
openFilesForSession([jsFile], session);
3258+
3259+
const getErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
3260+
CommandNames.SemanticDiagnosticsSync,
3261+
{ file: jsFile.path }
3262+
);
3263+
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
3264+
assert.isTrue(errorResult.length === 1);
3265+
assert.equal(errorResult[0].code, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2.code);
3266+
});
3267+
3268+
it("should report semanitc errors for configured js project with '// @ts-check' and skipLibCheck=true", () => {
3269+
const jsconfigFile = {
3270+
path: "/a/jsconfig.json",
3271+
content: "{}"
3272+
};
3273+
3274+
const jsFile = {
3275+
path: "/a/jsFile.js",
3276+
content: `
3277+
// @ts-check
3278+
let x = 1;
3279+
x === "string";`
3280+
};
3281+
3282+
const host = createServerHost([jsconfigFile, jsFile]);
3283+
const session = createSession(host);
3284+
openFilesForSession([jsFile], session);
3285+
3286+
const getErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
3287+
CommandNames.SemanticDiagnosticsSync,
3288+
{ file: jsFile.path }
3289+
);
3290+
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
3291+
assert.isTrue(errorResult.length === 1);
3292+
assert.equal(errorResult[0].code, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2.code);
3293+
});
3294+
3295+
it("should report semanitc errors for configured js project with checkJs=true and skipLibCheck=true", () => {
3296+
const jsconfigFile = {
3297+
path: "/a/jsconfig.json",
3298+
content: JSON.stringify({
3299+
compilerOptions: {
3300+
checkJs: true,
3301+
skipLibCheck: true
3302+
},
3303+
})
3304+
};
3305+
const jsFile = {
3306+
path: "/a/jsFile.js",
3307+
content: `let x = 1;
3308+
x === "string";`
3309+
};
3310+
3311+
const host = createServerHost([jsconfigFile, jsFile]);
3312+
const session = createSession(host);
3313+
openFilesForSession([jsFile], session);
3314+
3315+
const getErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
3316+
CommandNames.SemanticDiagnosticsSync,
3317+
{ file: jsFile.path }
3318+
);
3319+
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
3320+
assert.isTrue(errorResult.length === 1);
3321+
assert.equal(errorResult[0].code, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2.code);
3322+
});
32073323
});
32083324

32093325
describe("non-existing directories listed in config file input array", () => {
@@ -3493,6 +3609,30 @@ namespace ts.projectSystem {
34933609
});
34943610
});
34953611

3612+
describe("searching for config file", () => {
3613+
it("should stop at projectRootPath if given", () => {
3614+
const f1 = {
3615+
path: "/a/file1.ts",
3616+
content: ""
3617+
};
3618+
const configFile = {
3619+
path: "/tsconfig.json",
3620+
content: "{}"
3621+
};
3622+
const host = createServerHost([f1, configFile]);
3623+
const service = createProjectService(host);
3624+
service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, "/a");
3625+
3626+
checkNumberOfConfiguredProjects(service, 0);
3627+
checkNumberOfInferredProjects(service, 1);
3628+
3629+
service.closeClientFile(f1.path);
3630+
service.openClientFile(f1.path);
3631+
checkNumberOfConfiguredProjects(service, 1);
3632+
checkNumberOfInferredProjects(service, 0);
3633+
});
3634+
});
3635+
34963636
describe("cancellationToken", () => {
34973637
it("is attached to request", () => {
34983638
const f1 = {

src/lib/es2015.collection.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ interface ReadonlySet<T> {
5858
readonly size: number;
5959
}
6060

61-
interface WeakSet<T extends object> {
61+
interface WeakSet<T> {
6262
add(value: T): this;
6363
delete(value: T): boolean;
6464
has(value: T): boolean;

src/lib/es2015.iterable.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ interface SetConstructor {
118118
new <T>(iterable: Iterable<T>): Set<T>;
119119
}
120120

121-
interface WeakSet<T extends object> { }
121+
interface WeakSet<T> { }
122122

123123
interface WeakSetConstructor {
124124
new <T extends object>(iterable: Iterable<T>): WeakSet<T>;

src/lib/es2015.symbol.wellknown.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ interface Set<T> {
118118
readonly [Symbol.toStringTag]: "Set";
119119
}
120120

121-
interface WeakSet<T extends object> {
121+
interface WeakSet<T> {
122122
readonly [Symbol.toStringTag]: "WeakSet";
123123
}
124124

0 commit comments

Comments
 (0)