mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into fix_lookup_regression_again_and_again
This commit is contained in:
@@ -13076,6 +13076,14 @@ namespace ts {
|
||||
const paramCount = targetRestType ? Math.min(targetCount - 1, sourceCount) :
|
||||
sourceRestType ? targetCount :
|
||||
Math.min(sourceCount, targetCount);
|
||||
|
||||
const sourceThisType = getThisTypeOfSignature(source);
|
||||
if (sourceThisType) {
|
||||
const targetThisType = getThisTypeOfSignature(target);
|
||||
if (targetThisType) {
|
||||
callback(sourceThisType, targetThisType);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < paramCount; i++) {
|
||||
callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
|
||||
}
|
||||
|
||||
@@ -1272,7 +1272,7 @@ namespace ts {
|
||||
if (!left || !right) return false;
|
||||
for (const key in left) {
|
||||
if (hasOwnProperty.call(left, key)) {
|
||||
if (!hasOwnProperty.call(right, key) === undefined) return false;
|
||||
if (!hasOwnProperty.call(right, key)) return false;
|
||||
if (!equalityComparer(left[key], right[key])) return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,6 +507,7 @@ namespace ts {
|
||||
const configFileCache = createConfigFileCache(host);
|
||||
let context = createBuildContext(defaultOptions);
|
||||
let timerToBuildInvalidatedProject: any;
|
||||
let reportFileChangeDetected = false;
|
||||
|
||||
const existingWatchersForWildcards = createMap<WildcardDirectoryWatcher>();
|
||||
return {
|
||||
@@ -584,7 +585,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName) {
|
||||
reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation);
|
||||
reportFileChangeDetected = true;
|
||||
invalidateProject(resolved);
|
||||
scheduleBuildInvalidatedProject();
|
||||
}
|
||||
@@ -817,6 +818,10 @@ namespace ts {
|
||||
|
||||
function buildInvalidatedProject() {
|
||||
timerToBuildInvalidatedProject = undefined;
|
||||
if (reportFileChangeDetected) {
|
||||
reportFileChangeDetected = false;
|
||||
reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation);
|
||||
}
|
||||
const buildProject = context.getNextInvalidatedProject();
|
||||
buildSomeProjects(p => p === buildProject);
|
||||
if (context.hasPendingInvalidatedProjects()) {
|
||||
|
||||
Vendored
+10
@@ -1378,6 +1378,16 @@ type Extract<T, U> = T extends U ? T : never;
|
||||
*/
|
||||
type NonNullable<T> = T extends null | undefined ? never : T;
|
||||
|
||||
/**
|
||||
* Obtain the parameters of a function type in a tuple
|
||||
*/
|
||||
type Parameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;
|
||||
|
||||
/**
|
||||
* Obtain the parameters of a constructor function type in a tuple
|
||||
*/
|
||||
type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never;
|
||||
|
||||
/**
|
||||
* Obtain the return type of a function type
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,7 +42,18 @@ namespace ts.codefix {
|
||||
|
||||
function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void {
|
||||
// get the function declaration - returns a promise
|
||||
const functionToConvert: FunctionLikeDeclaration = getContainingFunction(getTokenAtPosition(sourceFile, position)) as FunctionLikeDeclaration;
|
||||
const tokenAtPosition = getTokenAtPosition(sourceFile, position);
|
||||
let functionToConvert: FunctionLikeDeclaration | undefined;
|
||||
|
||||
// if the parent of a FunctionLikeDeclaration is a variable declaration, the convertToAsync diagnostic will be reported on the variable name
|
||||
if (isIdentifier(tokenAtPosition) && isVariableDeclaration(tokenAtPosition.parent) &&
|
||||
tokenAtPosition.parent.initializer && isFunctionLikeDeclaration(tokenAtPosition.parent.initializer)) {
|
||||
functionToConvert = tokenAtPosition.parent.initializer;
|
||||
}
|
||||
else {
|
||||
functionToConvert = tryCast(getContainingFunction(getTokenAtPosition(sourceFile, position)), isFunctionLikeDeclaration);
|
||||
}
|
||||
|
||||
if (!functionToConvert) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ namespace ts {
|
||||
export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] {
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken);
|
||||
const diags: DiagnosticWithLocation[] = [];
|
||||
const checker = program.getDiagnosticsProducingTypeChecker();
|
||||
const checker = program.getTypeChecker();
|
||||
|
||||
if (sourceFile.commonJsModuleIndicator &&
|
||||
(programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) &&
|
||||
@@ -115,11 +115,12 @@ namespace ts {
|
||||
|
||||
function addConvertToAsyncFunctionDiagnostics(node: FunctionLikeDeclaration, checker: TypeChecker, diags: DiagnosticWithLocation[]): void {
|
||||
|
||||
const functionType = node.type ? checker.getTypeFromTypeNode(node.type) : undefined;
|
||||
if (isAsyncFunction(node) || !node.body || !functionType) {
|
||||
if (isAsyncFunction(node) || !node.body) {
|
||||
return;
|
||||
}
|
||||
|
||||
const functionType = checker.getTypeAtLocation(node);
|
||||
|
||||
const callSignatures = checker.getSignaturesOfType(functionType, SignatureKind.Call);
|
||||
const returnType = callSignatures.length ? checker.getReturnTypeOfSignature(callSignatures[0]) : undefined;
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
"unittests/cancellableLanguageServiceOperations.ts",
|
||||
"unittests/commandLineParsing.ts",
|
||||
"unittests/compileOnSave.ts",
|
||||
"unittests/compilerCore.ts",
|
||||
"unittests/configurationExtension.ts",
|
||||
"unittests/convertCompilerOptionsFromJson.ts",
|
||||
"unittests/convertToAsyncFunction.ts",
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace ts {
|
||||
describe("compilerCore", () => {
|
||||
describe("equalOwnProperties", () => {
|
||||
it("correctly equates objects", () => {
|
||||
assert.isTrue(equalOwnProperties({}, {}));
|
||||
assert.isTrue(equalOwnProperties({ a: 1 }, { a: 1 }));
|
||||
assert.isTrue(equalOwnProperties({ a: 1, b: 2 }, { b: 2, a: 1 }));
|
||||
});
|
||||
it("correctly identifies unmatched objects", () => {
|
||||
assert.isFalse(equalOwnProperties({}, { a: 1 }), "missing left property");
|
||||
assert.isFalse(equalOwnProperties({ a: 1 }, {}), "missing right property");
|
||||
assert.isFalse(equalOwnProperties({ a: 1 }, { a: 2 }), "differing property");
|
||||
});
|
||||
it("correctly identifies undefined vs hasOwnProperty", () => {
|
||||
assert.isFalse(equalOwnProperties({}, { a: undefined }), "missing left property");
|
||||
assert.isFalse(equalOwnProperties({ a: undefined }, {}), "missing right property");
|
||||
});
|
||||
it("truthiness", () => {
|
||||
const trythyTest = (l: any, r: any) => !!l === !!r;
|
||||
assert.isFalse(equalOwnProperties({}, { a: 1 }, trythyTest), "missing left truthy property");
|
||||
assert.isFalse(equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property");
|
||||
assert.isFalse(equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property");
|
||||
assert.isFalse(equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property");
|
||||
assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" }, trythyTest), "valid equality");
|
||||
});
|
||||
it("all equal", () => {
|
||||
assert.isFalse(equalOwnProperties({}, { a: 1 }, () => true), "missing left property");
|
||||
assert.isFalse(equalOwnProperties({ a: 1 }, {}, () => true), "missing right property");
|
||||
assert.isTrue(equalOwnProperties({ a: 1 }, { a: 2 }, () => true), "valid equality");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -319,7 +319,7 @@ interface String { charAt: any; }
|
||||
interface Array<T> {}`
|
||||
};
|
||||
|
||||
function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) {
|
||||
function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, diagnosticDescription: DiagnosticMessage, codeFixDescription: DiagnosticMessage, includeLib?: boolean) {
|
||||
const t = getTest(text);
|
||||
const selectionRange = t.ranges.get("selection")!;
|
||||
if (!selectionRange) {
|
||||
@@ -361,12 +361,14 @@ interface Array<T> {}`
|
||||
};
|
||||
|
||||
const diagnostics = languageService.getSuggestionDiagnostics(f.path);
|
||||
const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === description.message);
|
||||
assert.isNotNull(diagnostic);
|
||||
const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === diagnosticDescription.message);
|
||||
assert.exists(diagnostic);
|
||||
assert.equal(diagnostic!.start, context.span.start);
|
||||
assert.equal(diagnostic!.length, context.span.length);
|
||||
|
||||
const actions = codefix.getFixes(context);
|
||||
const action = find(actions, action => action.description === description.message)!;
|
||||
assert.isNotNull(action);
|
||||
const action = find(actions, action => action.description === codeFixDescription.message)!;
|
||||
assert.exists(action);
|
||||
|
||||
const data: string[] = [];
|
||||
data.push(`// ==ORIGINAL==`);
|
||||
@@ -423,6 +425,10 @@ interface Array<T> {}`
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_basic", `
|
||||
function [#|f|](): Promise<void>{
|
||||
return fetch('https://typescriptlang.org').then(result => { console.log(result) });
|
||||
}`);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_basicNoReturnTypeAnnotation", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(result => { console.log(result) });
|
||||
}`);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_basicWithComments", `
|
||||
function [#|f|](): Promise<void>{
|
||||
@@ -436,6 +442,10 @@ function [#|f|](): Promise<void>{
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunction", `
|
||||
[#|():Promise<void> => {|]
|
||||
return fetch('https://typescriptlang.org').then(result => console.log(result));
|
||||
}`);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunctionNoAnnotation", `
|
||||
[#|() => {|]
|
||||
return fetch('https://typescriptlang.org').then(result => console.log(result));
|
||||
}`);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_Catch", `
|
||||
function [#|f|]():Promise<void> {
|
||||
@@ -1178,11 +1188,17 @@ function [#|f|]() {
|
||||
}
|
||||
`);
|
||||
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_simpleFunctionExpression", `
|
||||
const [#|foo|] = function () {
|
||||
return fetch('https://typescriptlang.org').then(result => { console.log(result) });
|
||||
}
|
||||
`);
|
||||
|
||||
|
||||
});
|
||||
|
||||
function _testConvertToAsyncFunction(caption: string, text: string) {
|
||||
testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", Diagnostics.Convert_to_async_function, /*includeLib*/ true);
|
||||
testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", Diagnostics.This_may_be_converted_to_an_async_function, Diagnostics.Convert_to_async_function, /*includeLib*/ true);
|
||||
}
|
||||
|
||||
function _testConvertToAsyncFunctionFailed(caption: string, text: string) {
|
||||
|
||||
@@ -112,9 +112,22 @@ export class someClass { }`);
|
||||
// Another change requeues and builds it
|
||||
verifyChange(core[1].content);
|
||||
|
||||
// Two changes together report only single time message: File change detected. Starting incremental compilation...
|
||||
const outputFileStamps = getOutputFileStamps(host);
|
||||
const change1 = `${core[1].content}
|
||||
export class someClass { }`;
|
||||
host.writeFile(core[1].path, change1);
|
||||
host.writeFile(core[1].path, `${change1}
|
||||
export class someClass2 { }`);
|
||||
verifyChangeAfterTimeout(outputFileStamps);
|
||||
|
||||
function verifyChange(coreContent: string) {
|
||||
const outputFileStamps = getOutputFileStamps(host);
|
||||
host.writeFile(core[1].path, coreContent);
|
||||
verifyChangeAfterTimeout(outputFileStamps);
|
||||
}
|
||||
|
||||
function verifyChangeAfterTimeout(outputFileStamps: OutputFileStamp[]) {
|
||||
host.checkTimeoutQueueLengthAndRun(1); // Builds core
|
||||
const changedCore = getOutputFileStamps(host);
|
||||
verifyChangedFiles(changedCore, outputFileStamps, [
|
||||
|
||||
Reference in New Issue
Block a user