diff --git a/scripts/tslint/rules/nextLineRule.ts b/scripts/tslint/rules/nextLineRule.ts index fa03746afc6..9de80793c62 100644 --- a/scripts/tslint/rules/nextLineRule.ts +++ b/scripts/tslint/rules/nextLineRule.ts @@ -52,8 +52,8 @@ function walk(ctx: Lint.WalkContext, checkCatch: boolean, checkElse: boole return; } - const tryClosingBrace = tryBlock.getLastToken(sourceFile); - const catchKeyword = catchClause.getFirstToken(sourceFile); + const tryClosingBrace = tryBlock.getLastToken(sourceFile)!; + const catchKeyword = catchClause.getFirstToken(sourceFile)!; const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd()); const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile)); if (tryClosingBraceLoc.line === catchKeywordLoc.line) { diff --git a/scripts/tslint/rules/noInOperatorRule.ts b/scripts/tslint/rules/noInOperatorRule.ts index 448cf90cacd..95f052ccaa6 100644 --- a/scripts/tslint/rules/noInOperatorRule.ts +++ b/scripts/tslint/rules/noInOperatorRule.ts @@ -12,7 +12,7 @@ export class Rule extends Lint.Rules.AbstractRule { function walk(ctx: Lint.WalkContext): void { ts.forEachChild(ctx.sourceFile, recur); function recur(node: ts.Node): void { - if (node.kind === ts.SyntaxKind.InKeyword && node.parent!.kind === ts.SyntaxKind.BinaryExpression) { + if (node.kind === ts.SyntaxKind.InKeyword && node.parent.kind === ts.SyntaxKind.BinaryExpression) { ctx.addFailureAtNode(node, Rule.FAILURE_STRING); } } diff --git a/scripts/tslint/rules/noIncrementDecrementRule.ts b/scripts/tslint/rules/noIncrementDecrementRule.ts index ff2d81b1962..007d25919e1 100644 --- a/scripts/tslint/rules/noIncrementDecrementRule.ts +++ b/scripts/tslint/rules/noIncrementDecrementRule.ts @@ -28,7 +28,7 @@ function walk(ctx: Lint.WalkContext): void { } function check(node: ts.UnaryExpression): void { - if (!isAllowedLocation(node.parent!)) { + if (!isAllowedLocation(node.parent)) { ctx.addFailureAtNode(node, Rule.POSTFIX_FAILURE_STRING); } } @@ -47,7 +47,7 @@ function isAllowedLocation(node: ts.Node): boolean { // Can be in a comma operator in a for statement (`for (let a = 0, b = 10; a < b; a++, b--)`) case ts.SyntaxKind.BinaryExpression: return (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken && - node.parent!.kind === ts.SyntaxKind.ForStatement; + node.parent.kind === ts.SyntaxKind.ForStatement; default: return false; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 237553141f6..4555f247980 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10592,6 +10592,16 @@ namespace ts { else if (source.symbol && source.flags & TypeFlags.Object && globalObjectType === source) { reportError(Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead); } + else if (getObjectFlags(source) & ObjectFlags.JsxAttributes && target.flags & TypeFlags.Intersection) { + const targetTypes = (target as IntersectionType).types; + const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode); + const intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode); + if (intrinsicAttributes !== unknownType && intrinsicClassAttributes !== unknownType && + (contains(targetTypes, intrinsicAttributes) || contains(targetTypes, intrinsicClassAttributes))) { + // do not report top error + return result; + } + } reportRelationError(headMessage, source, target); } return result; @@ -16274,7 +16284,7 @@ namespace ts { return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode); } - function getJsxType(name: __String, location: Node) { + function getJsxType(name: __String, location: Node | undefined) { const namespace = getJsxNamespaceAt(location); const exports = namespace && getExportsOfSymbol(namespace); const typeSymbol = exports && getSymbol(exports, name, SymbolFlags.Type); @@ -16372,7 +16382,7 @@ namespace ts { return getSignatureInstantiation(signature, args, isJavascript); } - function getJsxNamespaceAt(location: Node): Symbol { + function getJsxNamespaceAt(location: Node | undefined): Symbol { const namespaceName = getJsxNamespace(location); const resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false); if (resolvedNamespace) { @@ -20418,7 +20428,7 @@ namespace ts { if (propType.symbol && propType.symbol.flags & SymbolFlags.Class) { const name = prop.escapedName; const symbol = resolveName(prop.valueDeclaration, name, SymbolFlags.Type, undefined, name, /*isUse*/ false); - if (symbol) { + if (symbol && propType.symbol !== symbol) { grammarErrorOnNode(symbol.declarations[0], Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(name)); return grammarErrorOnNode(prop.valueDeclaration, Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(name)); } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index a0ab03a9731..db6069fd5ac 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -416,7 +416,7 @@ namespace ts { createLogicalNot(getDone) ), /*incrementor*/ undefined, - /*statement*/ convertForOfStatementHead(node, createDownlevelAwait(getValue)) + /*statement*/ convertForOfStatementHead(node, getValue) ), /*location*/ node ), diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 4752f4e4574..a5e10c4b65d 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -3252,8 +3252,8 @@ namespace ts { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 369709c31e5..f6214d4c719 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -868,7 +868,7 @@ namespace FourSlash { for (const entry of actualCompletions.entries) { if (actualByName.has(entry.name)) { // TODO: GH#23587 - if (entry.name !== "undefined" && entry.name !== "require") this.raiseError(`Duplicate completions for ${entry.name}`); + if (entry.name !== "undefined" && entry.name !== "require") this.raiseError(`Duplicate (${actualCompletions.entries.filter(a => a.name === entry.name).length}) completions for ${entry.name}`); } else { actualByName.set(entry.name, entry); diff --git a/src/harness/unittests/forAwaitOfEvaluation.ts b/src/harness/unittests/forAwaitOfEvaluation.ts new file mode 100644 index 00000000000..339e0ca664b --- /dev/null +++ b/src/harness/unittests/forAwaitOfEvaluation.ts @@ -0,0 +1,148 @@ +/// + +namespace ts { + declare var Symbol: SymbolConstructor; + + describe("forAwaitOfEvaluation", () => { + const sourceFile = vpath.combine(vfs.srcFolder, "source.ts"); + + function compile(sourceText: string, options?: CompilerOptions) { + const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false); + fs.writeFileSync(sourceFile, sourceText); + const compilerOptions: CompilerOptions = { target: ScriptTarget.ES5, module: ModuleKind.CommonJS, lib: ["lib.esnext.d.ts"], ...options }; + const host = new fakes.CompilerHost(fs, compilerOptions); + return compiler.compileFiles(host, [sourceFile], compilerOptions); + } + + function noRequire(id: string) { + throw new Error(`Module '${id}' could not be found.`); + } + + // Define a custom "Symbol" constructor to attach missing built-in symbols without + // modifying the global "Symbol" constructor + // tslint:disable-next-line:variable-name + const FakeSymbol: SymbolConstructor = ((description?: string) => Symbol(description)) as any; + (FakeSymbol).prototype = Symbol.prototype; + for (const key of Object.getOwnPropertyNames(Symbol)) { + Object.defineProperty(FakeSymbol, key, Object.getOwnPropertyDescriptor(Symbol, key)!); + } + + // Add "asyncIterator" if missing + if (!hasProperty(FakeSymbol, "asyncIterator")) Object.defineProperty(FakeSymbol, "asyncIterator", { value: Symbol.for("Symbol.asyncIterator"), configurable: true }); + + function evaluate(result: compiler.CompilationResult) { + const output = result.getOutput(sourceFile, "js")!; + assert.isDefined(output); + + const evaluateText = `(function (module, exports, require, __dirname, __filename, Symbol) { ${output.text} })`; + const evaluateThunk = eval(evaluateText) as (module: any, exports: any, require: (id: string) => any, dirname: string, filename: string, symbolConstructor: SymbolConstructor) => void; + const module: { exports: any; } = { exports: {} }; + evaluateThunk(module, module.exports, noRequire, vpath.dirname(output.file), output.file, FakeSymbol); + return module; + } + + it("sync (es5)", async () => { + const module = evaluate(compile(` + let i = 0; + const iterator = { + [Symbol.iterator]() { return this; }, + next() { + switch (i++) { + case 0: return { value: 1, done: false }; + case 1: return { value: Promise.resolve(2), done: false }; + case 2: return { value: new Promise(resolve => setTimeout(resolve, 100, 3)), done: false }; + default: return { value: undefined: done: true }; + } + } + }; + export const output: any[] = []; + export async function main() { + for await (const item of iterator) { + output.push(item); + } + }`)); + await module.exports.main(); + assert.strictEqual(module.exports.output[0], 1); + assert.strictEqual(module.exports.output[1], 2); + assert.strictEqual(module.exports.output[2], 3); + }); + + it("sync (es2015)", async () => { + const module = evaluate(compile(` + let i = 0; + const iterator = { + [Symbol.iterator]() { return this; }, + next() { + switch (i++) { + case 0: return { value: 1, done: false }; + case 1: return { value: Promise.resolve(2), done: false }; + case 2: return { value: new Promise(resolve => setTimeout(resolve, 100, 3)), done: false }; + default: return { value: undefined: done: true }; + } + } + }; + export const output: any[] = []; + export async function main() { + for await (const item of iterator) { + output.push(item); + } + }`, { target: ScriptTarget.ES2015 })); + await module.exports.main(); + assert.strictEqual(module.exports.output[0], 1); + assert.strictEqual(module.exports.output[1], 2); + assert.strictEqual(module.exports.output[2], 3); + }); + + it("async (es5)", async () => { + const module = evaluate(compile(` + let i = 0; + const iterator = { + [Symbol.asyncIterator]() { return this; }, + async next() { + switch (i++) { + case 0: return { value: 1, done: false }; + case 1: return { value: Promise.resolve(2), done: false }; + case 2: return { value: new Promise(resolve => setTimeout(resolve, 100, 3)), done: false }; + default: return { value: undefined: done: true }; + } + } + }; + export const output: any[] = []; + export async function main() { + for await (const item of iterator) { + output.push(item); + } + }`)); + await module.exports.main(); + assert.strictEqual(module.exports.output[0], 1); + assert.instanceOf(module.exports.output[1], Promise); + assert.instanceOf(module.exports.output[2], Promise); + }); + + it("async (es2015)", async () => { + const module = evaluate(compile(` + let i = 0; + const iterator = { + [Symbol.asyncIterator]() { return this; }, + async next() { + switch (i++) { + case 0: return { value: 1, done: false }; + case 1: return { value: Promise.resolve(2), done: false }; + case 2: return { value: new Promise(resolve => setTimeout(resolve, 100, 3)), done: false }; + default: return { value: undefined: done: true }; + } + } + }; + export const output: any[] = []; + export async function main() { + for await (const item of iterator) { + output.push(item); + } + }`, { target: ScriptTarget.ES2015 })); + await module.exports.main(); + assert.strictEqual(module.exports.output[0], 1); + assert.instanceOf(module.exports.output[1], Promise); + assert.instanceOf(module.exports.output[2], Promise); + }); + }); +} \ No newline at end of file diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index e68b3b149ea..7581c49286b 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2394,6 +2394,15 @@ + + + + + + + + + @@ -2559,6 +2568,9 @@ + + + diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index bbedf489c37..0d661980ba6 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2394,6 +2394,15 @@ + + + + + + + + + @@ -2556,6 +2565,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 4d01ea1789c..fc9952d3b43 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2403,6 +2403,15 @@ + + + + + + + + + @@ -2568,6 +2577,9 @@ + + + diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index e076be1b08c..de37564b0cb 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2391,6 +2391,15 @@ + + + + + + + + + @@ -2556,6 +2565,9 @@ + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5604802bcb3..0ea5759d00d 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2406,6 +2406,15 @@ + + + + + + + + + @@ -2568,6 +2577,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 34419b903c1..b49cfdfe469 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2394,6 +2394,15 @@ + + + + + + + + + @@ -2559,6 +2568,9 @@ + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 1c9ee893cc3..e61caabaf99 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2394,6 +2394,15 @@ + + + + + + + + + @@ -2559,6 +2568,9 @@ + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 9d9522d2d38..63032699b0e 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2384,6 +2384,15 @@ + + + + + + + + + @@ -2549,6 +2558,9 @@ + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5ec3b07f2ef..c9be251b033 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2393,6 +2393,15 @@ + + + + + + + + + @@ -2555,6 +2564,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 9480e932325..130887938ee 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2387,6 +2387,15 @@ + + + + + + + + + @@ -2552,6 +2561,9 @@ + + + diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index e2ef6e9ec3c..abff1a5a02f 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -14,7 +14,8 @@ namespace ts.codefix { registerCodeFix({ errorCodes, getCodeActions(context) { - const { errorCode, sourceFile } = context; + const { errorCode, sourceFile, program } = context; + const checker = program.getTypeChecker(); const startToken = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); const importDecl = tryGetFullImport(startToken); @@ -22,7 +23,7 @@ namespace ts.codefix { const changes = textChanges.ChangeTracker.with(context, t => t.deleteNode(sourceFile, importDecl)); return [createCodeFixAction(fixName, changes, [Diagnostics.Remove_import_from_0, showModuleSpecifier(importDecl)], fixIdDelete, Diagnostics.Delete_all_unused_declarations)]; } - const delDestructure = textChanges.ChangeTracker.with(context, t => tryDeleteFullDestructure(t, sourceFile, startToken, /*deleted*/ undefined)); + const delDestructure = textChanges.ChangeTracker.with(context, t => tryDeleteFullDestructure(t, sourceFile, startToken, /*deleted*/ undefined, checker, /*isFixAll*/ false)); if (delDestructure.length) { return [createCodeFixAction(fixName, delDestructure, Diagnostics.Remove_destructuring, fixIdDelete, Diagnostics.Delete_all_unused_declarations)]; } @@ -34,7 +35,7 @@ namespace ts.codefix { const token = getToken(sourceFile, textSpanEnd(context.span)); const result: CodeFixAction[] = []; - const deletion = textChanges.ChangeTracker.with(context, t => tryDeleteDeclaration(t, sourceFile, token, /*deleted*/ undefined)); + const deletion = textChanges.ChangeTracker.with(context, t => tryDeleteDeclaration(t, sourceFile, token, /*deleted*/ undefined, checker, /*isFixAll*/ false)); if (deletion.length) { result.push(createCodeFixAction(fixName, deletion, [Diagnostics.Remove_declaration_for_Colon_0, token.getText(sourceFile)], fixIdDelete, Diagnostics.Delete_all_unused_declarations)); } @@ -50,8 +51,9 @@ namespace ts.codefix { getAllCodeActions: context => { // Track a set of deleted nodes that may be ancestors of other marked for deletion -- only delete the ancestors. const deleted = new NodeSet(); + const { sourceFile, program } = context; + const checker = program.getTypeChecker(); return codeFixAll(context, errorCodes, (changes, diag) => { - const { sourceFile } = context; const startToken = getTokenAtPosition(sourceFile, diag.start, /*includeJsDocComment*/ false); const token = findPrecedingToken(textSpanEnd(diag), diag.file)!; switch (context.fixId) { @@ -68,8 +70,9 @@ namespace ts.codefix { if (importDecl) { changes.deleteNode(sourceFile, importDecl); } - else if (!tryDeleteFullDestructure(changes, sourceFile, startToken, deleted) && !tryDeleteFullVariableStatement(changes, sourceFile, startToken, deleted)) { - tryDeleteDeclaration(changes, sourceFile, token, deleted); + else if (!tryDeleteFullDestructure(changes, sourceFile, startToken, deleted, checker, /*isFixAll*/ true) && + !tryDeleteFullVariableStatement(changes, sourceFile, startToken, deleted)) { + tryDeleteDeclaration(changes, sourceFile, token, deleted, checker, /*isFixAll*/ true); } break; default: @@ -84,7 +87,7 @@ namespace ts.codefix { return startToken.kind === SyntaxKind.ImportKeyword ? tryCast(startToken.parent, isImportDeclaration) : undefined; } - function tryDeleteFullDestructure(changes: textChanges.ChangeTracker, sourceFile: SourceFile, startToken: Node, deletedAncestors: NodeSet | undefined): boolean { + function tryDeleteFullDestructure(changes: textChanges.ChangeTracker, sourceFile: SourceFile, startToken: Node, deletedAncestors: NodeSet | undefined, checker: TypeChecker, isFixAll: boolean): boolean { if (startToken.kind !== SyntaxKind.OpenBraceToken || !isObjectBindingPattern(startToken.parent)) return false; const decl = cast(startToken.parent, isObjectBindingPattern).parent; switch (decl.kind) { @@ -92,6 +95,7 @@ namespace ts.codefix { tryDeleteVariableDeclaration(changes, sourceFile, decl, deletedAncestors); break; case SyntaxKind.Parameter: + if (!mayDeleteParameter(decl, checker, isFixAll)) break; if (deletedAncestors) deletedAncestors.add(decl); changes.deleteNodeInList(sourceFile, decl); break; @@ -144,10 +148,10 @@ namespace ts.codefix { return false; } - function tryDeleteDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, deletedAncestors: NodeSet | undefined): void { + function tryDeleteDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, deletedAncestors: NodeSet | undefined, checker: TypeChecker, isFixAll: boolean): void { switch (token.kind) { case SyntaxKind.Identifier: - tryDeleteIdentifier(changes, sourceFile, token, deletedAncestors); + tryDeleteIdentifier(changes, sourceFile, token, deletedAncestors, checker, isFixAll); break; case SyntaxKind.PropertyDeclaration: case SyntaxKind.NamespaceImport: @@ -170,7 +174,7 @@ namespace ts.codefix { } } - function tryDeleteIdentifier(changes: textChanges.ChangeTracker, sourceFile: SourceFile, identifier: Identifier, deletedAncestors: NodeSet | undefined): void { + function tryDeleteIdentifier(changes: textChanges.ChangeTracker, sourceFile: SourceFile, identifier: Identifier, deletedAncestors: NodeSet | undefined, checker: TypeChecker, isFixAll: boolean): void { const parent = identifier.parent; switch (parent.kind) { case SyntaxKind.VariableDeclaration: @@ -194,11 +198,8 @@ namespace ts.codefix { break; case SyntaxKind.Parameter: + if (!mayDeleteParameter(parent as ParameterDeclaration, checker, isFixAll)) break; const oldFunction = parent.parent; - if (isSetAccessor(oldFunction)) { - // Setter must have a parameter - break; - } if (isArrowFunction(oldFunction) && oldFunction.parameters.length === 1) { // Lambdas with exactly one parameter are special because, after removal, there @@ -347,4 +348,35 @@ namespace ts.codefix { } } } + + function mayDeleteParameter(p: ParameterDeclaration, checker: TypeChecker, isFixAll: boolean) { + const parent = p.parent; + switch (parent.kind) { + case SyntaxKind.MethodDeclaration: + // Don't remove a parameter if this overrides something + const symbol = checker.getSymbolAtLocation(parent.name)!; + if (isMemberSymbolInBaseType(symbol, checker)) return false; + // falls through + + case SyntaxKind.Constructor: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: { + // Can't remove a non-last parameter. Can remove a parameter in code-fix-all if future parameters are also unused. + const { parameters } = parent; + const index = parameters.indexOf(p); + Debug.assert(index !== -1); + return isFixAll + ? parameters.slice(index + 1).every(p => p.name.kind === SyntaxKind.Identifier && !p.symbol.isReferenced) + : index === parameters.length - 1; + } + + case SyntaxKind.SetAccessor: + // Setter must have a parameter + return false; + + default: + return Debug.failBadSyntaxKind(parent); + } + } } diff --git a/src/services/codefixes/moduleSpecifiers.ts b/src/services/codefixes/moduleSpecifiers.ts index 5279c3cb84f..5a08f7d3dea 100644 --- a/src/services/codefixes/moduleSpecifiers.ts +++ b/src/services/codefixes/moduleSpecifiers.ts @@ -16,15 +16,18 @@ namespace ts.moduleSpecifiers { const getCanonicalFileName = hostGetCanonicalFileName(host); const sourceDirectory = getDirectoryPath(importingSourceFile.fileName); - return getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()).map(moduleFileName => { - const global = tryGetModuleNameFromAmbientModule(moduleSymbol) - || tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) - || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) - || rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); - if (global) { - return [global]; - } + const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); + if (ambient) return [[ambient]]; + const modulePaths = getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()); + + const global = mapDefined(modulePaths, moduleFileName => + tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) || + tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) || + rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName)); + if (global.length) return global.map(g => [g]); + + return modulePaths.map(moduleFileName => { const relativePath = removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { return [relativePath]; @@ -191,11 +194,12 @@ namespace ts.moduleSpecifiers { // Simplify the full file path to something that can be resolved by Node. // If the module could be imported by a directory name, use that directory's name - let moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); + const moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); // Get a path that's relative to node_modules or the importing file's path - moduleSpecifier = getNodeResolvablePath(moduleSpecifier); + // if node_modules folder is in this folder or any of its parent folders, no need to keep it. + if (!startsWith(sourceDirectory, moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex))) return undefined; // If the module was found in @types, get the actual Node package name - return getPackageNameFromAtTypesDirectory(moduleSpecifier); + return getPackageNameFromAtTypesDirectory(moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1)); function getDirectoryOrExtensionlessFileName(path: string): string { // If the file is the main module, it can be imported by the package name @@ -224,17 +228,6 @@ namespace ts.moduleSpecifiers { return fullModulePathWithoutExtension; } - - function getNodeResolvablePath(path: string): string { - const basePath = path.substring(0, parts.topLevelNodeModulesIndex); - if (sourceDirectory.indexOf(basePath) === 0) { - // if node_modules folder is in this folder or any of its parent folders, no need to keep it. - return path.substring(parts.topLevelPackageNameIndex + 1); - } - else { - return ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); - } - } } interface NodeModulePathParts { diff --git a/src/services/completions.ts b/src/services/completions.ts index 45317be065e..4b31ed3c377 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1320,12 +1320,20 @@ namespace ts.Completions { function getSymbolsFromOtherSourceFileExports(symbols: Symbol[], tokenText: string, target: ScriptTarget): void { const tokenTextLowerCase = tokenText.toLowerCase(); + const seenResolvedModules = createMap(); + codefix.forEachExternalModuleToImportFrom(typeChecker, sourceFile, program.getSourceFiles(), moduleSymbol => { // Perf -- ignore other modules if this is a request for details if (detailsEntryId && detailsEntryId.source && stripQuotes(moduleSymbol.name) !== detailsEntryId.source) { return; } + const resolvedModuleSymbol = typeChecker.resolveExternalModuleSymbol(moduleSymbol); + // resolvedModuleSymbol may be a namespace. A namespace may be `export =` by multiple module declarations, but only keep the first one. + if (!addToSeen(seenResolvedModules, getSymbolId(resolvedModuleSymbol))) { + return; + } + for (let symbol of typeChecker.getExportsOfModule(moduleSymbol)) { // Don't add a completion for a re-export, only for the original. // The actual import fix might end up coming from a re-export -- we don't compute that until getting completion details. @@ -1333,7 +1341,7 @@ namespace ts.Completions { // // If `symbol.parent !== ...`, this comes from an `export * from "foo"` re-export. Those don't create new symbols. // If `some(...)`, this comes from an `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check). - if (typeChecker.getMergedSymbol(symbol.parent!) !== typeChecker.resolveExternalModuleSymbol(moduleSymbol) + if (typeChecker.getMergedSymbol(symbol.parent!) !== resolvedModuleSymbol || some(symbol.declarations, d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) { continue; } diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index e6a78e098e9..afae01e0c68 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -180,7 +180,7 @@ namespace ts.DocumentHighlights { default: // Don't cross function boundaries. // TODO: GH#20090 - return (isFunctionLike(node) && "quit") as false | "quit"; + return isFunctionLike(node) && "quit"; } }); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index cc13cfd28c4..f00046bd4ea 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1399,34 +1399,6 @@ namespace ts.FindAllReferences.Core { } } - /** - * Find symbol of the given property-name and add the symbol to the given result array - * @param symbol a symbol to start searching for the given propertyName - * @param propertyName a name of property to search for - * @param result an array of symbol of found property symbols - * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. - * The value of previousIterationSymbol is undefined when the function is first called. - */ - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, checker: TypeChecker, cb: (symbol: Symbol) => T | undefined): T | undefined { - const seen = createMap(); - return recur(symbol); - - function recur(symbol: Symbol): T | undefined { - // Use `addToSeen` to ensure we don't infinitely recurse in this situation: - // interface C extends C { - // /*findRef*/propName: string; - // } - if (!(symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) || !addToSeen(seen, getSymbolId(symbol))) return; - - return firstDefined(symbol.declarations, declaration => firstDefined(getAllSuperTypeNodes(declaration), typeReference => { - const type = checker.getTypeAtLocation(typeReference); - const propertySymbol = type && type.symbol && checker.getPropertyOfType(type, propertyName); - // Visit the typeReference as well to see if it directly or indirectly uses that property - return propertySymbol && (firstDefined(checker.getRootSymbols(propertySymbol), cb) || recur(type!.symbol)); - })); - } - } - function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): Symbol | undefined { const { checker } = state; return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker, diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 59251fe38b8..bfd371d1154 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -243,7 +243,7 @@ namespace ts.JsDoc { } const tokenAtPos = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); - const tokenStart = tokenAtPos.getStart(); + const tokenStart = tokenAtPos.getStart(sourceFile); if (!tokenAtPos || tokenStart < position) { return undefined; } @@ -253,7 +253,7 @@ namespace ts.JsDoc { return undefined; } const { commentOwner, parameters } = commentOwnerInfo; - if (commentOwner.getStart() < position) { + if (commentOwner.getStart(sourceFile) < position) { return undefined; } @@ -268,19 +268,6 @@ namespace ts.JsDoc { // replace non-whitespace characters in prefix with spaces. const indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character).replace(/\S/i, () => " "); - const isJavaScriptFile = hasJavaScriptFileExtension(sourceFile.fileName); - - let docParams = ""; - for (let i = 0; i < parameters.length; i++) { - const currentName = parameters[i].name; - const paramName = currentName.kind === SyntaxKind.Identifier ? currentName.escapedText : "param" + i; - if (isJavaScriptFile) { - docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`; - } - else { - docParams += `${indentationStr} * @param ${paramName}${newLine}`; - } - } // A doc comment consists of the following // * The opening comment line @@ -293,13 +280,21 @@ namespace ts.JsDoc { indentationStr + " * "; const result = preamble + newLine + - docParams + + parameterDocComments(parameters, hasJavaScriptFileExtension(sourceFile.fileName), indentationStr, newLine) + indentationStr + " */" + (tokenStart === position ? newLine + indentationStr : ""); return { newText: result, caretOffset: preamble.length }; } + function parameterDocComments(parameters: ReadonlyArray, isJavaScriptFile: boolean, indentationStr: string, newLine: string): string { + return parameters.map(({ name, dotDotDotToken }, i) => { + const paramName = name.kind === SyntaxKind.Identifier ? name.text : "param" + i; + const type = isJavaScriptFile ? (dotDotDotToken ? "{...any} " : "{any} ") : ""; + return `${indentationStr} * @param ${type}${paramName}${newLine}`; + }).join(""); + } + interface CommentOwnerInfo { readonly commentOwner: Node; readonly parameters?: ReadonlyArray; diff --git a/src/services/services.ts b/src/services/services.ts index dcea57b7159..441cb5a8ebd 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1735,17 +1735,9 @@ namespace ts { synchronizeHostData(); // Exclude default library when renaming as commonly user don't want to change that file. - let sourceFiles: SourceFile[] = []; - if (options && options.isForRename) { - for (const sourceFile of program.getSourceFiles()) { - if (!program.isSourceFileDefaultLibrary(sourceFile)) { - sourceFiles.push(sourceFile); - } - } - } - else { - sourceFiles = program.getSourceFiles().slice(); - } + const sourceFiles = options && options.isForRename + ? program.getSourceFiles().filter(sourceFile => !program.isSourceFileDefaultLibrary(sourceFile)) + : program.getSourceFiles(); return FindAllReferences.findReferencedEntries(program, cancellationToken, sourceFiles, getValidSourceFile(fileName), position, options); } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index de577ec5946..85afcf9d7bf 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1293,6 +1293,38 @@ namespace ts { return propSymbol; } + /** + * Find symbol of the given property-name and add the symbol to the given result array + * @param symbol a symbol to start searching for the given propertyName + * @param propertyName a name of property to search for + * @param result an array of symbol of found property symbols + * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. + * The value of previousIterationSymbol is undefined when the function is first called. + */ + export function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, checker: TypeChecker, cb: (symbol: Symbol) => T | undefined): T | undefined { + const seen = createMap(); + return recur(symbol); + + function recur(symbol: Symbol): T | undefined { + // Use `addToSeen` to ensure we don't infinitely recurse in this situation: + // interface C extends C { + // /*findRef*/propName: string; + // } + if (!(symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) || !addToSeen(seen, getSymbolId(symbol))) return; + + return firstDefined(symbol.declarations, declaration => firstDefined(getAllSuperTypeNodes(declaration), typeReference => { + const type = checker.getTypeAtLocation(typeReference); + const propertySymbol = type && type.symbol && checker.getPropertyOfType(type, propertyName); + // Visit the typeReference as well to see if it directly or indirectly uses that property + return type && propertySymbol && (firstDefined(checker.getRootSymbols(propertySymbol), cb) || recur(type.symbol)); + })); + } + } + + export function isMemberSymbolInBaseType(memberSymbol: Symbol, checker: TypeChecker): boolean { + return getPropertySymbolsFromBaseTypes(memberSymbol.parent!, memberSymbol.name, checker, _ => true) || false; + } + export class NodeSet { private map = createMap(); diff --git a/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js b/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js index 2c4f827be53..58b887c61a3 100644 --- a/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js +++ b/tests/baselines/reference/asyncAwaitIsolatedModules_es5.js @@ -56,8 +56,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/asyncAwait_es5.js b/tests/baselines/reference/asyncAwait_es5.js index 6434ae5a766..ee8f160b2a4 100644 --- a/tests/baselines/reference/asyncAwait_es5.js +++ b/tests/baselines/reference/asyncAwait_es5.js @@ -62,8 +62,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/asyncFunctionNoReturnType.js b/tests/baselines/reference/asyncFunctionNoReturnType.js index 6f4a3795118..b376e398d17 100644 --- a/tests/baselines/reference/asyncFunctionNoReturnType.js +++ b/tests/baselines/reference/asyncFunctionNoReturnType.js @@ -21,8 +21,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/asyncFunctionTempVariableScoping.js b/tests/baselines/reference/asyncFunctionTempVariableScoping.js index fb4137e1671..c237e03e0f6 100644 --- a/tests/baselines/reference/asyncFunctionTempVariableScoping.js +++ b/tests/baselines/reference/asyncFunctionTempVariableScoping.js @@ -20,8 +20,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/asyncFunctionWithForStatementNoInitializer.js b/tests/baselines/reference/asyncFunctionWithForStatementNoInitializer.js index 10f6c20eb06..99394281a15 100644 --- a/tests/baselines/reference/asyncFunctionWithForStatementNoInitializer.js +++ b/tests/baselines/reference/asyncFunctionWithForStatementNoInitializer.js @@ -40,8 +40,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/asyncImportNestedYield.js b/tests/baselines/reference/asyncImportNestedYield.js index 74d6dd59629..b92065950fb 100644 --- a/tests/baselines/reference/asyncImportNestedYield.js +++ b/tests/baselines/reference/asyncImportNestedYield.js @@ -11,8 +11,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/asyncImportedPromise_es5.js b/tests/baselines/reference/asyncImportedPromise_es5.js index ea9cf265a8a..8b56ebbd1fa 100644 --- a/tests/baselines/reference/asyncImportedPromise_es5.js +++ b/tests/baselines/reference/asyncImportedPromise_es5.js @@ -47,8 +47,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/asyncMultiFile_es5.js b/tests/baselines/reference/asyncMultiFile_es5.js index 67a3ce258b4..a6dbb44ef9e 100644 --- a/tests/baselines/reference/asyncMultiFile_es5.js +++ b/tests/baselines/reference/asyncMultiFile_es5.js @@ -21,8 +21,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/awaitUnionPromise.js b/tests/baselines/reference/awaitUnionPromise.js index df4c937fc63..90b894ee0f5 100644 --- a/tests/baselines/reference/awaitUnionPromise.js +++ b/tests/baselines/reference/awaitUnionPromise.js @@ -37,8 +37,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/blockScopedBindingsInDownlevelGenerator.js b/tests/baselines/reference/blockScopedBindingsInDownlevelGenerator.js index 5f3eed666ab..e177b7d4a0a 100644 --- a/tests/baselines/reference/blockScopedBindingsInDownlevelGenerator.js +++ b/tests/baselines/reference/blockScopedBindingsInDownlevelGenerator.js @@ -14,8 +14,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/castOfYield.js b/tests/baselines/reference/castOfYield.js index 9ad9ec52a31..86d35bedad4 100644 --- a/tests/baselines/reference/castOfYield.js +++ b/tests/baselines/reference/castOfYield.js @@ -14,8 +14,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; diff --git a/tests/baselines/reference/checkJsxChildrenProperty14.errors.txt b/tests/baselines/reference/checkJsxChildrenProperty14.errors.txt index 6878372be8b..cf999188ebc 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty14.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenProperty14.errors.txt @@ -1,8 +1,7 @@ -tests/cases/conformance/jsx/file.tsx(42,11): error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'. - Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'SingleChildProp'. - Types of property 'children' are incompatible. - Type 'Element[]' is not assignable to type 'Element'. - Property 'type' is missing in type 'Element[]'. +tests/cases/conformance/jsx/file.tsx(42,11): error TS2322: Type '{ children: Element[]; a: number; b: string; }' is not assignable to type 'SingleChildProp'. + Types of property 'children' are incompatible. + Type 'Element[]' is not assignable to type 'Element'. + Property 'type' is missing in type 'Element[]'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -49,8 +48,7 @@ tests/cases/conformance/jsx/file.tsx(42,11): error TS2322: Type '{ children: Ele // Error let k5 = <>