From 98153599f76cf58beef4df916acfcaf9a9ab1527 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 5 Sep 2017 15:15:23 -0700 Subject: [PATCH 1/8] Ensure that emitter calls calbacks --- src/compiler/emitter.ts | 107 +++++++++++------- src/compiler/factory.ts | 35 +++++- src/compiler/transformers/es2017.ts | 1 + src/compiler/transformers/esnext.ts | 1 + src/compiler/transformers/ts.ts | 1 + src/compiler/utilities.ts | 8 +- src/compiler/visitor.ts | 1 + src/services/formatting/formatting.ts | 1 + src/services/refactors/extractMethod.ts | 6 +- src/services/textChanges.ts | 28 ++--- .../reference/extractMethod/extractMethod4.ts | 24 ++-- .../fourslash/extract-method-formatting.ts | 24 ++++ 12 files changed, 162 insertions(+), 75 deletions(-) create mode 100644 tests/cases/fourslash/extract-method-formatting.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5444c618353bd..7e9e1ae9e67b8 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1035,10 +1035,8 @@ namespace ts { function emitTypeLiteral(node: TypeLiteralNode) { write("{"); - // If the literal is empty, do not add spaces between braces. - if (node.members.length > 0) { - emitList(node, node.members, getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers); - } + const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers; + emitList(node, node.members, flags | ListFormat.NoSpaceIfEmpty); write("}"); } @@ -1095,11 +1093,14 @@ namespace ts { increaseIndent(); } writeIfPresent(node.readonlyToken, "readonly "); - write("["); - emit(node.typeParameter.name); - write(" in "); - emit(node.typeParameter.constraint); - write("]"); + + if (onEmitNode) { + onEmitNode(EmitHint.Unspecified, node.typeParameter, emitMappedTypeParameter); + } + else { + emitMappedTypeParameter(EmitHint.Unspecified, node.typeParameter); + } + writeIfPresent(node.questionToken, "?"); write(": "); emit(node.type); @@ -1114,6 +1115,14 @@ namespace ts { write("}"); } + function emitMappedTypeParameter(_hint: EmitHint, node: TypeParameterDeclaration) { + write("["); + emit(node.name); + write(" in "); + emit(node.constraint); + write("]"); + } + function emitLiteralType(node: LiteralTypeNode) { emitExpression(node.literal); } @@ -1159,33 +1168,22 @@ namespace ts { function emitArrayLiteralExpression(node: ArrayLiteralExpression) { const elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; - emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine); - } + const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; + emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine); } function emitObjectLiteralExpression(node: ObjectLiteralExpression) { - const properties = node.properties; - if (properties.length === 0) { - write("{}"); + const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; + if (indentedFlag) { + increaseIndent(); } - else { - const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; - if (indentedFlag) { - increaseIndent(); - } - const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; - const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None; - emitList(node, properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine); + const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; + const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None; + emitList(node, node.properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine); - if (indentedFlag) { - decreaseIndent(); - } + if (indentedFlag) { + decreaseIndent(); } } @@ -1286,7 +1284,8 @@ namespace ts { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitWithPrefix(": ", node.type); - write(" =>"); + write(" "); + emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node: DeleteExpression) { @@ -1382,7 +1381,10 @@ namespace ts { } function emitYieldExpression(node: YieldExpression) { - write(node.asteriskToken ? "yield*" : "yield"); + write("yield"); + if (node.asteriskToken) { + emit(node.asteriskToken); + } emitExpressionWithPrefix(" ", node.expression); } @@ -1662,7 +1664,11 @@ namespace ts { function emitFunctionDeclarationOrExpression(node: FunctionDeclaration | FunctionExpression) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.asteriskToken ? "function* " : "function "); + write("function"); + if (node.asteriskToken) { + emit(node.asteriskToken); + } + write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -2068,9 +2074,7 @@ namespace ts { function emitJsxExpression(node: JsxExpression) { if (node.expression) { write("{"); - if (node.dotDotDotToken) { - write("..."); - } + writeIfPresent(node.dotDotDotToken, "..."); emitExpression(node.expression); write("}"); } @@ -2130,7 +2134,7 @@ namespace ts { if (emitAsSingleStatement) { write(" "); - emit(statements[0]); + emitSingleElementList(statements); } else { emitList(parentNode, statements, ListFormat.CaseOrDefaultClauseStatements); @@ -2384,7 +2388,7 @@ namespace ts { function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emit(parameters[0]); + emitSingleElementList(parameters); } else { emitParameters(parentNode, parameters); @@ -2395,6 +2399,17 @@ namespace ts { emitList(parentNode, parameters, ListFormat.IndexSignatureParameters); } + function emitSingleElementList(list: NodeArray) { + Debug.assert(list.length === 1); + if (onBeforeEmitNodeArray) { + onBeforeEmitNodeArray(list); + } + emit(list[0]); + if (onAfterEmitNodeArray) { + onAfterEmitNodeArray(list); + } + } + function emitList(parentNode: Node, children: NodeArray, format: ListFormat, start?: number, count?: number) { emitNodeList(emit, parentNode, children, format, start, count); } @@ -2427,7 +2442,7 @@ namespace ts { if (format & ListFormat.MultiLine) { writeLine(); } - else if (format & ListFormat.SpaceBetweenBraces) { + else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) { write(" "); } } @@ -2570,7 +2585,7 @@ namespace ts { function writeIfPresent(node: Node, text: string) { if (node) { - write(text); + writeTokenAndCallCallbacks(node, text); } } @@ -2580,16 +2595,20 @@ namespace ts { : writeTokenText(token, pos); } - function writeTokenNode(node: Node) { + function writeTokenAndCallCallbacks(node: Node, text: string) { if (onBeforeEmitToken) { onBeforeEmitToken(node); } - writeTokenText(node.kind); + write(text); if (onAfterEmitToken) { onAfterEmitToken(node); } } + function writeTokenNode(node: Node) { + writeTokenAndCallCallbacks(node, tokenToString(node.kind)); + } + function writeTokenText(token: SyntaxKind, pos?: number) { const tokenString = tokenToString(token); write(tokenString); @@ -3107,6 +3126,8 @@ namespace ts { NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list. NoInterveningComments = 1 << 17, // Do not emit comments between each node + NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces. + // Precomputed Formats Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments, HeritageClauses = SingleLine | SpaceBetweenSiblings, @@ -3118,7 +3139,7 @@ namespace ts { IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings, ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings, - ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces, + ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 4492c3ed47426..0b12834597728 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -281,7 +281,7 @@ namespace ts { || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer - ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node) + ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) : node; } @@ -1016,19 +1016,48 @@ namespace ts { return node; } + /* @deprecated */ export function updateArrowFunction( + node: ArrowFunction, + modifiers: ReadonlyArray | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: ConciseBody): ArrowFunction; export function updateArrowFunction( node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, - body: ConciseBody) { + equalsGreaterThanToken: Token, + body: ConciseBody): ArrowFunction; + export function updateArrowFunction( + node: ArrowFunction, + modifiers: ReadonlyArray | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + equalsGreaterThanTokenOrBody: Token | ConciseBody, + bodyOrUndefined?: ConciseBody): ArrowFunction { + let equalsGreaterThanToken: Token; + let body: ConciseBody; + if (bodyOrUndefined === undefined) { + equalsGreaterThanToken = node.equalsGreaterThanToken; + body = cast(equalsGreaterThanTokenOrBody, isConciseBody); + } + else { + equalsGreaterThanToken = cast(equalsGreaterThanTokenOrBody, (n): n is Token => + n.kind === SyntaxKind.EqualsGreaterThanToken); + body = bodyOrUndefined; + } + return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type + || node.equalsGreaterThanToken !== equalsGreaterThanToken || node.body !== body - ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node) + ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) : node; } diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 43058358ee5f7..bd9139034d9cd 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -197,6 +197,7 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, + node.equalsGreaterThanToken, getFunctionFlags(node) & FunctionFlags.Async ? transformAsyncFunctionBody(node) : visitFunctionBody(node.body, visitor, context) diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 3bdcc9e9ee722..6a21b4a032bce 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -595,6 +595,7 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, + node.equalsGreaterThanToken, transformFunctionBody(node) ); enclosingFunctionFlags = savedEnclosingFunctionFlags; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 692c758bc7504..e265efc5d0594 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2291,6 +2291,7 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, + node.equalsGreaterThanToken, visitFunctionBody(node.body, visitor, context) ); return updated; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2a07d2b656061..384c6a7283043 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4666,8 +4666,12 @@ namespace ts { /* @internal */ export function isNodeArray(array: ReadonlyArray): array is NodeArray { - return array.hasOwnProperty("pos") - && array.hasOwnProperty("end"); + const res = array.hasOwnProperty("pos") && array.hasOwnProperty("end"); + if (res) { + const { pos, end } = array as NodeArray; + Debug.assert(typeof pos === "number" && typeof end === "number"); + } + return res; } // Literals diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 1ce42199372d8..a863c4adb1424 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -488,6 +488,7 @@ namespace ts { nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), + visitNode((node).equalsGreaterThanToken, visitor, n => n.kind === SyntaxKind.EqualsGreaterThanToken), visitFunctionBody((node).body, visitor, context)); case SyntaxKind.DeleteExpression: diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 83f87483194b5..a4df7933604a9 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -728,6 +728,7 @@ namespace ts.formatting { parent: Node, parentStartLine: number, parentDynamicIndentation: DynamicIndentation): void { + Debug.assert(isNodeArray(nodes)); const listStartToken = getOpenTokenForList(parent, nodes); const listEndToken = getCloseTokenForOpenToken(listStartToken); diff --git a/src/services/refactors/extractMethod.ts b/src/services/refactors/extractMethod.ts index 1a96857b73e56..90be8800100e8 100644 --- a/src/services/refactors/extractMethod.ts +++ b/src/services/refactors/extractMethod.ts @@ -656,11 +656,13 @@ namespace ts.refactor.extractMethod { const typeParametersAndDeclarations = arrayFrom(typeParameterUsages.values()).map(type => ({ type, declaration: getFirstDeclaration(type) })); const sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder); - const typeParameters: ReadonlyArray = sortedTypeParametersAndDeclarations.map(t => t.declaration as TypeParameterDeclaration); + const typeParameters: ReadonlyArray | undefined = sortedTypeParametersAndDeclarations.length === 0 + ? undefined + : sortedTypeParametersAndDeclarations.map(t => t.declaration as TypeParameterDeclaration); // Strictly speaking, we should check whether each name actually binds to the appropriate type // parameter. In cases of shadowing, they may not. - const callTypeArguments: ReadonlyArray | undefined = typeParameters.length > 0 + const callTypeArguments: ReadonlyArray | undefined = typeParameters !== undefined ? typeParameters.map(decl => createTypeReferenceNode(decl.name, /*typeArguments*/ undefined)) : undefined; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 6462b64e22670..45447d8aa204a 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -5,19 +5,25 @@ namespace ts.textChanges { * Currently for simplicity we store recovered positions on the node itself. * It can be changed to side-table later if we decide that current design is too invasive. */ - function getPos(n: TextRange) { - return (n)["__pos"]; + function getPos(n: TextRange): number { + const result = (n)["__pos"]; + Debug.assert(typeof result === "number"); + return result; } - function setPos(n: TextRange, pos: number) { + function setPos(n: TextRange, pos: number): void { + Debug.assert(typeof pos === "number"); (n)["__pos"] = pos; } - function getEnd(n: TextRange) { - return (n)["__end"]; + function getEnd(n: TextRange): number { + const result = (n)["__end"]; + Debug.assert(typeof result === "number"); + return result; } - function setEnd(n: TextRange, end: number) { + function setEnd(n: TextRange, end: number): void { + Debug.assert(typeof end === "number"); (n)["__end"] = end; } @@ -582,7 +588,7 @@ namespace ts.textChanges { readonly node: Node; } - export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText { + function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLine: NewLineKind): NonFormattedText { const options = { newLine, target: sourceFile && sourceFile.languageVersion }; const writer = new Writer(getNewLineCharacter(options)); const printer = createPrinter(options, writer); @@ -590,7 +596,7 @@ namespace ts.textChanges { return { text: writer.getText(), node: assignPositionsToNode(node) }; } - export function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) { + function applyFormatting(nonFormattedText: NonFormattedText, sourceFile: SourceFile, initialIndentation: number, delta: number, rulesProvider: formatting.RulesProvider) { const lineMap = computeLineStarts(nonFormattedText.text); const file: SourceFileLike = { text: nonFormattedText.text, @@ -616,14 +622,10 @@ namespace ts.textChanges { function assignPositionsToNode(node: Node): Node { const visited = visitEachChild(node, assignPositionsToNode, nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // create proxy node for non synthesized nodes - const newNode = nodeIsSynthesized(visited) - ? visited - : (Proxy.prototype = visited, new (Proxy)()); + const newNode = nodeIsSynthesized(visited) ? visited : Object.create(visited) as Node; newNode.pos = getPos(node); newNode.end = getEnd(node); return newNode; - - function Proxy() { } } function assignPositionsToNodeArray(nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) { diff --git a/tests/baselines/reference/extractMethod/extractMethod4.ts b/tests/baselines/reference/extractMethod/extractMethod4.ts index 107f99e669b8d..4e9811501f4dc 100644 --- a/tests/baselines/reference/extractMethod/extractMethod4.ts +++ b/tests/baselines/reference/extractMethod/extractMethod4.ts @@ -24,9 +24,9 @@ namespace A { async function newFunction() { let y = 5; - if(z) { - await z1; - } + if (z) { + await z1; + } return foo(); } } @@ -44,9 +44,9 @@ namespace A { async function newFunction(z: number, z1: any) { let y = 5; - if(z) { - await z1; - } + if (z) { + await z1; + } return foo(); } } @@ -64,9 +64,9 @@ namespace A { async function newFunction(z: number, z1: any) { let y = 5; - if(z) { - await z1; - } + if (z) { + await z1; + } return foo(); } } @@ -83,8 +83,8 @@ namespace A { } async function newFunction(z: number, z1: any, foo: () => void) { let y = 5; - if(z) { - await z1; -} + if (z) { + await z1; + } return foo(); } diff --git a/tests/cases/fourslash/extract-method-formatting.ts b/tests/cases/fourslash/extract-method-formatting.ts new file mode 100644 index 0000000000000..1342e5632e800 --- /dev/null +++ b/tests/cases/fourslash/extract-method-formatting.ts @@ -0,0 +1,24 @@ +/// + +////function f(x: number): number { +//// /*start*/switch (x) {case 0: +////return 0;}/*end*/ +////} + +goTo.select('start', 'end') +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_1", + actionDescription: "Extract function into global scope", +}); +verify.currentFileContentIs( +`function f(x: number): number { + return newFunction(x); +} +function newFunction(x: number) { + switch (x) { + case 0: + return 0; + } +} +`); From 7d931bb1cde111aa0e13228189eb488cd9bedca1 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 7 Sep 2017 08:35:28 -0700 Subject: [PATCH 2/8] Move new parameter to end of parameters --- src/compiler/factory.ts | 31 +++-------------------------- src/compiler/transformers/es2017.ts | 4 ++-- src/compiler/transformers/esnext.ts | 2 +- src/compiler/transformers/ts.ts | 2 +- src/compiler/visitor.ts | 4 ++-- 5 files changed, 9 insertions(+), 34 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 0b12834597728..ac38c9cf314b7 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1016,40 +1016,15 @@ namespace ts { return node; } - /* @deprecated */ export function updateArrowFunction( - node: ArrowFunction, - modifiers: ReadonlyArray | undefined, - typeParameters: ReadonlyArray | undefined, - parameters: ReadonlyArray, - type: TypeNode | undefined, - body: ConciseBody): ArrowFunction; - export function updateArrowFunction( - node: ArrowFunction, - modifiers: ReadonlyArray | undefined, - typeParameters: ReadonlyArray | undefined, - parameters: ReadonlyArray, - type: TypeNode | undefined, - equalsGreaterThanToken: Token, - body: ConciseBody): ArrowFunction; export function updateArrowFunction( node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, - equalsGreaterThanTokenOrBody: Token | ConciseBody, - bodyOrUndefined?: ConciseBody): ArrowFunction { - let equalsGreaterThanToken: Token; - let body: ConciseBody; - if (bodyOrUndefined === undefined) { - equalsGreaterThanToken = node.equalsGreaterThanToken; - body = cast(equalsGreaterThanTokenOrBody, isConciseBody); - } - else { - equalsGreaterThanToken = cast(equalsGreaterThanTokenOrBody, (n): n is Token => - n.kind === SyntaxKind.EqualsGreaterThanToken); - body = bodyOrUndefined; - } + body: ConciseBody, + // Optional for backwards-compatibility only -- should always provide this. + equalsGreaterThanToken: Token = node.equalsGreaterThanToken): ArrowFunction { return node.modifiers !== modifiers || node.typeParameters !== typeParameters diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index bd9139034d9cd..1b1f0e93163c5 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -197,10 +197,10 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - node.equalsGreaterThanToken, getFunctionFlags(node) & FunctionFlags.Async ? transformAsyncFunctionBody(node) - : visitFunctionBody(node.body, visitor, context) + : visitFunctionBody(node.body, visitor, context), + node.equalsGreaterThanToken, ); } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 6a21b4a032bce..a51fa95c5662a 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -595,8 +595,8 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, + transformFunctionBody(node), node.equalsGreaterThanToken, - transformFunctionBody(node) ); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index e265efc5d0594..a85dfa64a2530 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2291,8 +2291,8 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, + visitFunctionBody(node.body, visitor, context), node.equalsGreaterThanToken, - visitFunctionBody(node.body, visitor, context) ); return updated; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index a863c4adb1424..19bb3b7425a25 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -488,8 +488,8 @@ namespace ts { nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), - visitNode((node).equalsGreaterThanToken, visitor, n => n.kind === SyntaxKind.EqualsGreaterThanToken), - visitFunctionBody((node).body, visitor, context)); + visitFunctionBody((node).body, visitor, context), + visitNode((node).equalsGreaterThanToken, visitor, n => n.kind === SyntaxKind.EqualsGreaterThanToken)); case SyntaxKind.DeleteExpression: return updateDelete(node, From 5b44de1f1502216dd4901069e15bd8490d2ca221 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 7 Sep 2017 11:15:28 -0700 Subject: [PATCH 3/8] Fix for ConditionalExpression --- src/compiler/emitter.ts | 4 +- src/compiler/factory.ts | 13 +- src/compiler/visitor.ts | 4 +- .../sourceMapValidationStatements.js.map | 2 +- ...ourceMapValidationStatements.sourcemap.txt | 132 +++++++++++------- .../ternaryExpressionSourceMap.js.map | 2 +- .../ternaryExpressionSourceMap.sourcemap.txt | 90 ++++++------ ...ypeGuardsInRightOperandOfAndAndOperator.js | 2 + .../typeGuardsInRightOperandOfOrOrOperator.js | 2 + tests/cases/fourslash/extract-method5.ts | 2 +- 10 files changed, 152 insertions(+), 101 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a88878671675a..d4d866bb2bdf2 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1363,13 +1363,13 @@ namespace ts { emitExpression(node.condition); increaseIndentIf(indentBeforeQuestion, " "); - write("?"); + emit(node.questionToken); increaseIndentIf(indentAfterQuestion, " "); emitExpression(node.whenTrue); decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion); increaseIndentIf(indentBeforeColon, " "); - write(":"); + emit(node.colonToken); increaseIndentIf(indentAfterColon, " "); emitExpression(node.whenFalse); decreaseIndentIf(indentBeforeColon, indentAfterColon); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index ac38c9cf314b7..5719c0f798daa 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1139,11 +1139,20 @@ namespace ts { return node; } - export function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression) { + export function updateConditional( + node: ConditionalExpression, + condition: Expression, + whenTrue: Expression, + whenFalse: Expression, + questionToken: Token = node.questionToken, + colonToken: Token = node.colonToken, + ) { return node.condition !== condition + || node.questionToken !== questionToken || node.whenTrue !== whenTrue + || node.colonToken !== colonToken || node.whenFalse !== whenFalse - ? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node) + ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) : node; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 19bb3b7425a25..aec5c92f9471c 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -525,7 +525,9 @@ namespace ts { return updateConditional(node, visitNode((node).condition, visitor, isExpression), visitNode((node).whenTrue, visitor, isExpression), - visitNode((node).whenFalse, visitor, isExpression)); + visitNode((node).whenFalse, visitor, isExpression), + visitNode((node).questionToken, visitor, n => n.kind === SyntaxKind.QuestionToken), + visitNode((node).colonToken, visitor, n => n.kind === SyntaxKind.ColonToken)); case SyntaxKind.TemplateExpression: return updateTemplateExpression(node, diff --git a/tests/baselines/reference/sourceMapValidationStatements.js.map b/tests/baselines/reference/sourceMapValidationStatements.js.map index 5841f329e5edf..40d65e0106c1c 100644 --- a/tests/baselines/reference/sourceMapValidationStatements.js.map +++ b/tests/baselines/reference/sourceMapValidationStatements.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationStatements.js.map] -{"version":3,"file":"sourceMapValidationStatements.js","sourceRoot":"","sources":["sourceMapValidationStatements.ts"],"names":[],"mappings":"AAAA;IACI,IAAI,CAAC,CAAC;IACN,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,CAAC,IAAI,CAAC,CAAC;QACP,CAAC,IAAI,CAAC,CAAC;IACX,CAAC;IACD,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACT,CAAC,IAAI,CAAC,CAAC;IACX,CAAC;IAAC,IAAI,CAAC,CAAC;QACJ,CAAC,IAAI,EAAE,CAAC;QACR,CAAC,EAAE,CAAC;IACR,CAAC;IACD,IAAI,CAAC,GAAG;QACJ,CAAC;QACD,CAAC;QACD,CAAC;KACJ,CAAC;IACF,IAAI,GAAG,GAAG;QACN,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,OAAO;KACb,CAAC;IACF,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACD,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IACnB,CAAC;IAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACT,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACb,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;QAClB,CAAC;IACL,CAAC;IACD,IAAI,CAAC;QACD,MAAM,IAAI,KAAK,EAAE,CAAC;IACtB,CAAC;IAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACV,IAAI,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;YAAS,CAAC;QACP,CAAC,GAAG,EAAE,CAAC;IACX,CAAC;IACD,MAAM,GAAG,EAAE,CAAC;QACR,CAAC,GAAG,CAAC,CAAC;QACN,CAAC,GAAG,EAAE,CAAC;IACX,CAAC;IACD,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACZ,KAAK,CAAC,EAAE,CAAC;YACL,CAAC,EAAE,CAAC;YACJ,KAAK,CAAC;QAEV,CAAC;QACD,KAAK,CAAC,EAAE,CAAC;YACL,CAAC,EAAE,CAAC;YACJ,KAAK,CAAC;QAEV,CAAC;QACD,SAAS,CAAC;YACN,CAAC,IAAI,CAAC,CAAC;YACP,CAAC,GAAG,EAAE,CAAC;YACP,KAAK,CAAC;QAEV,CAAC;IACL,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;QACZ,CAAC,EAAE,CAAC;IACR,CAAC;IACD,GAAG,CAAC;QACA,CAAC,EAAE,CAAC;IACR,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAC;IACf,CAAC,GAAG,CAAC,CAAC;IACN,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC,KAAK,CAAC,CAAC;IACR,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IACX,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,CAAC;AACX,CAAC;AACD,IAAI,CAAC,GAAG;IACJ,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACd,CAAC,CAAC;AACF,CAAC,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationStatements.js","sourceRoot":"","sources":["sourceMapValidationStatements.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationStatements.sourcemap.txt b/tests/baselines/reference/sourceMapValidationStatements.sourcemap.txt index 7c5c5bfcfeba6..aec7eaafc0629 100644 --- a/tests/baselines/reference/sourceMapValidationStatements.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationStatements.sourcemap.txt @@ -1251,15 +1251,19 @@ sourceFile:sourceMapValidationStatements.ts 7 > ^^^^ 8 > ^ 9 > ^ -10> ^^^ -11> ^ -12> ^^^ -13> ^ -14> ^^^ -15> ^ -16> ^^^ -17> ^ -18> ^ +10> ^ +11> ^ +12> ^ +13> ^ +14> ^^^ +15> ^ +16> ^ +17> ^ +18> ^ +19> ^ +20> ^^^ +21> ^ +22> ^ 1-> > 2 > var @@ -1270,15 +1274,19 @@ sourceFile:sourceMapValidationStatements.ts 7 > == 8 > 1 9 > ) -10> ? -11> x -12> + -13> 1 -14> : -15> x -16> - -17> 1 -18> ; +10> +11> ? +12> +13> x +14> + +15> 1 +16> +17> : +18> +19> x +20> - +21> 1 +22> ; 1->Emitted(74, 5) Source(72, 5) + SourceIndex(0) 2 >Emitted(74, 9) Source(72, 9) + SourceIndex(0) 3 >Emitted(74, 10) Source(72, 10) + SourceIndex(0) @@ -1288,15 +1296,19 @@ sourceFile:sourceMapValidationStatements.ts 7 >Emitted(74, 19) Source(72, 19) + SourceIndex(0) 8 >Emitted(74, 20) Source(72, 20) + SourceIndex(0) 9 >Emitted(74, 21) Source(72, 21) + SourceIndex(0) -10>Emitted(74, 24) Source(72, 24) + SourceIndex(0) -11>Emitted(74, 25) Source(72, 25) + SourceIndex(0) -12>Emitted(74, 28) Source(72, 28) + SourceIndex(0) -13>Emitted(74, 29) Source(72, 29) + SourceIndex(0) -14>Emitted(74, 32) Source(72, 32) + SourceIndex(0) -15>Emitted(74, 33) Source(72, 33) + SourceIndex(0) -16>Emitted(74, 36) Source(72, 36) + SourceIndex(0) -17>Emitted(74, 37) Source(72, 37) + SourceIndex(0) -18>Emitted(74, 38) Source(72, 38) + SourceIndex(0) +10>Emitted(74, 22) Source(72, 22) + SourceIndex(0) +11>Emitted(74, 23) Source(72, 23) + SourceIndex(0) +12>Emitted(74, 24) Source(72, 24) + SourceIndex(0) +13>Emitted(74, 25) Source(72, 25) + SourceIndex(0) +14>Emitted(74, 28) Source(72, 28) + SourceIndex(0) +15>Emitted(74, 29) Source(72, 29) + SourceIndex(0) +16>Emitted(74, 30) Source(72, 30) + SourceIndex(0) +17>Emitted(74, 31) Source(72, 31) + SourceIndex(0) +18>Emitted(74, 32) Source(72, 32) + SourceIndex(0) +19>Emitted(74, 33) Source(72, 33) + SourceIndex(0) +20>Emitted(74, 36) Source(72, 36) + SourceIndex(0) +21>Emitted(74, 37) Source(72, 37) + SourceIndex(0) +22>Emitted(74, 38) Source(72, 38) + SourceIndex(0) --- >>> (x == 1) ? x + 1 : x - 1; 1 >^^^^ @@ -1305,15 +1317,19 @@ sourceFile:sourceMapValidationStatements.ts 4 > ^^^^ 5 > ^ 6 > ^ -7 > ^^^ -8 > ^ -9 > ^^^ -10> ^ -11> ^^^ -12> ^ -13> ^^^ -14> ^ -15> ^ +7 > ^ +8 > ^ +9 > ^ +10> ^ +11> ^^^ +12> ^ +13> ^ +14> ^ +15> ^ +16> ^ +17> ^^^ +18> ^ +19> ^ 1 > > 2 > ( @@ -1321,30 +1337,38 @@ sourceFile:sourceMapValidationStatements.ts 4 > == 5 > 1 6 > ) -7 > ? -8 > x -9 > + -10> 1 -11> : -12> x -13> - -14> 1 -15> ; +7 > +8 > ? +9 > +10> x +11> + +12> 1 +13> +14> : +15> +16> x +17> - +18> 1 +19> ; 1 >Emitted(75, 5) Source(73, 5) + SourceIndex(0) 2 >Emitted(75, 6) Source(73, 6) + SourceIndex(0) 3 >Emitted(75, 7) Source(73, 7) + SourceIndex(0) 4 >Emitted(75, 11) Source(73, 11) + SourceIndex(0) 5 >Emitted(75, 12) Source(73, 12) + SourceIndex(0) 6 >Emitted(75, 13) Source(73, 13) + SourceIndex(0) -7 >Emitted(75, 16) Source(73, 16) + SourceIndex(0) -8 >Emitted(75, 17) Source(73, 17) + SourceIndex(0) -9 >Emitted(75, 20) Source(73, 20) + SourceIndex(0) -10>Emitted(75, 21) Source(73, 21) + SourceIndex(0) -11>Emitted(75, 24) Source(73, 24) + SourceIndex(0) -12>Emitted(75, 25) Source(73, 25) + SourceIndex(0) -13>Emitted(75, 28) Source(73, 28) + SourceIndex(0) -14>Emitted(75, 29) Source(73, 29) + SourceIndex(0) -15>Emitted(75, 30) Source(73, 30) + SourceIndex(0) +7 >Emitted(75, 14) Source(73, 14) + SourceIndex(0) +8 >Emitted(75, 15) Source(73, 15) + SourceIndex(0) +9 >Emitted(75, 16) Source(73, 16) + SourceIndex(0) +10>Emitted(75, 17) Source(73, 17) + SourceIndex(0) +11>Emitted(75, 20) Source(73, 20) + SourceIndex(0) +12>Emitted(75, 21) Source(73, 21) + SourceIndex(0) +13>Emitted(75, 22) Source(73, 22) + SourceIndex(0) +14>Emitted(75, 23) Source(73, 23) + SourceIndex(0) +15>Emitted(75, 24) Source(73, 24) + SourceIndex(0) +16>Emitted(75, 25) Source(73, 25) + SourceIndex(0) +17>Emitted(75, 28) Source(73, 28) + SourceIndex(0) +18>Emitted(75, 29) Source(73, 29) + SourceIndex(0) +19>Emitted(75, 30) Source(73, 30) + SourceIndex(0) --- >>> x === 1; 1 >^^^^ diff --git a/tests/baselines/reference/ternaryExpressionSourceMap.js.map b/tests/baselines/reference/ternaryExpressionSourceMap.js.map index 9340c972274f0..27160910378f4 100644 --- a/tests/baselines/reference/ternaryExpressionSourceMap.js.map +++ b/tests/baselines/reference/ternaryExpressionSourceMap.js.map @@ -1,2 +1,2 @@ //// [ternaryExpressionSourceMap.js.map] -{"version":3,"file":"ternaryExpressionSourceMap.js","sourceRoot":"","sources":["ternaryExpressionSourceMap.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,CAAC,CAAC;AACV,IAAI,GAAG,GAAG,CAAC,GAAG,cAAM,OAAA,CAAC,EAAD,CAAC,GAAG,cAAM,OAAA,CAAC,EAAD,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"ternaryExpressionSourceMap.js","sourceRoot":"","sources":["ternaryExpressionSourceMap.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG,CAAC,CAAC;AACV,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,cAAM,OAAA,CAAC,EAAD,CAAC,CAAC,CAAC,CAAC,cAAM,OAAA,CAAC,EAAD,CAAC,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/ternaryExpressionSourceMap.sourcemap.txt b/tests/baselines/reference/ternaryExpressionSourceMap.sourcemap.txt index d46e703e3570d..87e3ce023047a 100644 --- a/tests/baselines/reference/ternaryExpressionSourceMap.sourcemap.txt +++ b/tests/baselines/reference/ternaryExpressionSourceMap.sourcemap.txt @@ -35,55 +35,67 @@ sourceFile:ternaryExpressionSourceMap.ts 3 > ^^^ 4 > ^^^ 5 > ^ -6 > ^^^ -7 > ^^^^^^^^^^^^^^ -8 > ^^^^^^^ -9 > ^ -10> ^^ -11> ^ -12> ^^^ -13> ^^^^^^^^^^^^^^ -14> ^^^^^^^ -15> ^ -16> ^^ -17> ^ -18> ^ +6 > ^ +7 > ^ +8 > ^ +9 > ^^^^^^^^^^^^^^ +10> ^^^^^^^ +11> ^ +12> ^^ +13> ^ +14> ^ +15> ^ +16> ^ +17> ^^^^^^^^^^^^^^ +18> ^^^^^^^ +19> ^ +20> ^^ +21> ^ +22> ^ 1-> > 2 >var 3 > foo 4 > = 5 > x -6 > ? -7 > () => -8 > -9 > 0 -10> -11> 0 -12> : -13> () => -14> -15> 0 -16> -17> 0 -18> ; +6 > +7 > ? +8 > +9 > () => +10> +11> 0 +12> +13> 0 +14> +15> : +16> +17> () => +18> +19> 0 +20> +21> 0 +22> ; 1->Emitted(2, 1) Source(2, 1) + SourceIndex(0) 2 >Emitted(2, 5) Source(2, 5) + SourceIndex(0) 3 >Emitted(2, 8) Source(2, 8) + SourceIndex(0) 4 >Emitted(2, 11) Source(2, 11) + SourceIndex(0) 5 >Emitted(2, 12) Source(2, 12) + SourceIndex(0) -6 >Emitted(2, 15) Source(2, 15) + SourceIndex(0) -7 >Emitted(2, 29) Source(2, 21) + SourceIndex(0) -8 >Emitted(2, 36) Source(2, 21) + SourceIndex(0) -9 >Emitted(2, 37) Source(2, 22) + SourceIndex(0) -10>Emitted(2, 39) Source(2, 21) + SourceIndex(0) -11>Emitted(2, 40) Source(2, 22) + SourceIndex(0) -12>Emitted(2, 43) Source(2, 25) + SourceIndex(0) -13>Emitted(2, 57) Source(2, 31) + SourceIndex(0) -14>Emitted(2, 64) Source(2, 31) + SourceIndex(0) -15>Emitted(2, 65) Source(2, 32) + SourceIndex(0) -16>Emitted(2, 67) Source(2, 31) + SourceIndex(0) -17>Emitted(2, 68) Source(2, 32) + SourceIndex(0) -18>Emitted(2, 69) Source(2, 33) + SourceIndex(0) +6 >Emitted(2, 13) Source(2, 13) + SourceIndex(0) +7 >Emitted(2, 14) Source(2, 14) + SourceIndex(0) +8 >Emitted(2, 15) Source(2, 15) + SourceIndex(0) +9 >Emitted(2, 29) Source(2, 21) + SourceIndex(0) +10>Emitted(2, 36) Source(2, 21) + SourceIndex(0) +11>Emitted(2, 37) Source(2, 22) + SourceIndex(0) +12>Emitted(2, 39) Source(2, 21) + SourceIndex(0) +13>Emitted(2, 40) Source(2, 22) + SourceIndex(0) +14>Emitted(2, 41) Source(2, 23) + SourceIndex(0) +15>Emitted(2, 42) Source(2, 24) + SourceIndex(0) +16>Emitted(2, 43) Source(2, 25) + SourceIndex(0) +17>Emitted(2, 57) Source(2, 31) + SourceIndex(0) +18>Emitted(2, 64) Source(2, 31) + SourceIndex(0) +19>Emitted(2, 65) Source(2, 32) + SourceIndex(0) +20>Emitted(2, 67) Source(2, 31) + SourceIndex(0) +21>Emitted(2, 68) Source(2, 32) + SourceIndex(0) +22>Emitted(2, 69) Source(2, 33) + SourceIndex(0) --- >>>//# sourceMappingURL=ternaryExpressionSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js index be1c497e3ea0d..5483f314fb9e4 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js @@ -85,6 +85,8 @@ function foo7(x) { return typeof x !== "string" && ((z = x) // number | boolean && (typeof x === "number" + // change value of x ? ((x = 10) && x.toString()) // x is number + // do not change value : ((y = x) && x.toString()))); // x is boolean } diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js index a8d66dc5fa22c..c3143999d3a2c 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js @@ -87,6 +87,8 @@ function foo7(x) { return typeof x === "string" || ((z = x) // number | boolean || (typeof x === "number" + // change value of x ? ((x = 10) && x.toString()) // number | boolean | string + // do not change value : ((y = x) && x.toString()))); // number | boolean | string } diff --git a/tests/cases/fourslash/extract-method5.ts b/tests/cases/fourslash/extract-method5.ts index d1e70d10716ac..8b0bd4fec6dd5 100644 --- a/tests/cases/fourslash/extract-method5.ts +++ b/tests/cases/fourslash/extract-method5.ts @@ -20,6 +20,6 @@ verify.currentFileContentIs( var x: 1 | 2 | 3 = newFunction(); function newFunction(): 1 | 2 | 3 { - return 1 + 1 === 2?1: 2; + return 1 + 1 === 2 ? 1 : 2; } }`); \ No newline at end of file From aae877d6fb5881a5977d8a00002bd529e02bc8b3 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 7 Sep 2017 11:59:58 -0700 Subject: [PATCH 4/8] Make suggested changes to emitter --- src/compiler/emitter.ts | 87 +++++++++++++++++++---------------------- src/compiler/types.ts | 1 + 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d4d866bb2bdf2..8cc8770df34e9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -406,6 +406,14 @@ namespace ts { setWriter(/*output*/ undefined); } + // TODO: Should this just be `emit`? + // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034 + function emitIfPresent(node: Node | undefined) { + if (node) { + pipelineEmitWithNotification(EmitHint.Unspecified, node); + } + } + function emit(node: Node) { pipelineEmitWithNotification(EmitHint.Unspecified, node); } @@ -451,6 +459,7 @@ namespace ts { case EmitHint.SourceFile: return pipelineEmitSourceFile(node); case EmitHint.IdentifierName: return pipelineEmitIdentifierName(node); case EmitHint.Expression: return pipelineEmitExpression(node); + case EmitHint.MappedTypeParameter: return pipelineEmitMappedTypeParameter(cast(node, isTypeParameterDeclaration)); case EmitHint.Unspecified: return pipelineEmitUnspecified(node); } } @@ -465,6 +474,12 @@ namespace ts { emitIdentifier(node); } + function pipelineEmitMappedTypeParameter(node: TypeParameterDeclaration): void { + emit(node.name); + write(" in "); + emit(node.constraint); + } + function pipelineEmitUnspecified(node: Node): void { const kind = node.kind; @@ -898,9 +913,9 @@ namespace ts { function emitParameter(node: ParameterDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } @@ -918,7 +933,7 @@ namespace ts { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); write(";"); } @@ -927,7 +942,7 @@ namespace ts { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); write(";"); @@ -937,7 +952,7 @@ namespace ts { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); @@ -947,9 +962,9 @@ namespace ts { function emitMethodDeclaration(node: MethodDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - writeIfPresent(node.asteriskToken, "*"); + emitIfPresent(node.asteriskToken); emit(node.name); - writeIfPresent(node.questionToken, "?"); + emitIfPresent(node.questionToken); emitSignatureAndBody(node, emitSignatureHead); } @@ -1092,16 +1107,16 @@ namespace ts { writeLine(); increaseIndent(); } - writeIfPresent(node.readonlyToken, "readonly "); - - if (onEmitNode) { - onEmitNode(EmitHint.Unspecified, node.typeParameter, emitMappedTypeParameter); - } - else { - emitMappedTypeParameter(EmitHint.Unspecified, node.typeParameter); + if (node.readonlyToken) { + emit(node.readonlyToken); + write(" "); } - writeIfPresent(node.questionToken, "?"); + write("["); + pipelineEmitWithNotification(EmitHint.MappedTypeParameter, node.typeParameter); + write("]"); + + emitIfPresent(node.questionToken); write(": "); emit(node.type); write(";"); @@ -1115,14 +1130,6 @@ namespace ts { write("}"); } - function emitMappedTypeParameter(_hint: EmitHint, node: TypeParameterDeclaration) { - write("["); - emit(node.name); - write(" in "); - emit(node.constraint); - write("]"); - } - function emitLiteralType(node: LiteralTypeNode) { emitExpression(node.literal); } @@ -1157,7 +1164,7 @@ namespace ts { function emitBindingElement(node: BindingElement) { emitWithSuffix(node.propertyName, ": "); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } @@ -1382,9 +1389,7 @@ namespace ts { function emitYieldExpression(node: YieldExpression) { write("yield"); - if (node.asteriskToken) { - emit(node.asteriskToken); - } + emit(node.asteriskToken); emitExpressionWithPrefix(" ", node.expression); } @@ -1665,9 +1670,7 @@ namespace ts { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); write("function"); - if (node.asteriskToken) { - emit(node.asteriskToken); - } + emitIfPresent(node.asteriskToken); write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); @@ -2074,7 +2077,7 @@ namespace ts { function emitJsxExpression(node: JsxExpression) { if (node.expression) { write("{"); - writeIfPresent(node.dotDotDotToken, "..."); + emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); write("}"); } @@ -2132,13 +2135,12 @@ namespace ts { emitTrailingCommentsOfPosition(statements.pos); } + let format = ListFormat.CaseOrDefaultClauseStatements; if (emitAsSingleStatement) { write(" "); - emitSingleElementList(statements); - } - else { - emitList(parentNode, statements, ListFormat.CaseOrDefaultClauseStatements); + format &= ~(ListFormat.MultiLine | ListFormat.Indented); } + emitList(parentNode, statements, format); } function emitHeritageClause(node: HeritageClause) { @@ -2583,32 +2585,22 @@ namespace ts { } } - function writeIfPresent(node: Node, text: string) { - if (node) { - writeTokenAndCallCallbacks(node, text); - } - } - function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) { return onEmitSourceMapOfToken ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) : writeTokenText(token, pos); } - function writeTokenAndCallCallbacks(node: Node, text: string) { + function writeTokenNode(node: Node) { if (onBeforeEmitToken) { onBeforeEmitToken(node); } - write(text); + write(tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } } - function writeTokenNode(node: Node) { - writeTokenAndCallCallbacks(node, tokenToString(node.kind)); - } - function writeTokenText(token: SyntaxKind, pos?: number) { const tokenString = tokenToString(token); write(tokenString); @@ -3127,6 +3119,7 @@ namespace ts { NoInterveningComments = 1 << 17, // Do not emit comments between each node NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces. + SingleElement = 1 << 19, // Precomputed Formats Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 75e1cb05bc94e..917a4935dd054 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4261,6 +4261,7 @@ namespace ts { SourceFile, // Emitting a SourceFile Expression, // Emitting an Expression IdentifierName, // Emitting an IdentifierName + MappedTypeParameter, // Emitting a TypeParameterDeclaration inside of a MappedTypeNode Unspecified, // Emitting an otherwise unspecified node } From 8f775dc117645461ff26ccc2d726c1ad535aebc4 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 7 Sep 2017 12:57:10 -0700 Subject: [PATCH 5/8] Fix parameter ordering --- src/compiler/factory.ts | 51 +++++++++++++++++++++++++---- src/compiler/transformers/es2017.ts | 2 +- src/compiler/transformers/esnext.ts | 2 +- src/compiler/transformers/ts.ts | 2 +- src/compiler/visitor.ts | 10 +++--- 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 5719c0f798daa..2bf6d6e879db5 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1016,15 +1016,41 @@ namespace ts { return node; } + /* @deprecated */ export function updateArrowFunction( + node: ArrowFunction, + modifiers: ReadonlyArray | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: ConciseBody): ArrowFunction; + export function updateArrowFunction( + node: ArrowFunction, + modifiers: ReadonlyArray | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + equalsGreaterThanToken: Token, + body: ConciseBody): ArrowFunction; export function updateArrowFunction( node: ArrowFunction, modifiers: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, - body: ConciseBody, - // Optional for backwards-compatibility only -- should always provide this. - equalsGreaterThanToken: Token = node.equalsGreaterThanToken): ArrowFunction { + equalsGreaterThanTokenOrBody: Token | ConciseBody, + bodyOrUndefined?: ConciseBody, + ): ArrowFunction { + let equalsGreaterThanToken: Token; + let body: ConciseBody; + if (bodyOrUndefined === undefined) { + equalsGreaterThanToken = node.equalsGreaterThanToken; + body = cast(equalsGreaterThanTokenOrBody, isConciseBody); + } + else { + equalsGreaterThanToken = cast(equalsGreaterThanTokenOrBody, (n): n is Token => + n.kind === SyntaxKind.EqualsGreaterThanToken); + body = bodyOrUndefined; + } return node.modifiers !== modifiers || node.typeParameters !== typeParameters @@ -1139,14 +1165,25 @@ namespace ts { return node; } + /* @deprecated */ export function updateConditional( + node: ConditionalExpression, + condition: Expression, + whenTrue: Expression, + whenFalse: Expression): ConditionalExpression; export function updateConditional( node: ConditionalExpression, condition: Expression, + questionToken: Token, whenTrue: Expression, - whenFalse: Expression, - questionToken: Token = node.questionToken, - colonToken: Token = node.colonToken, - ) { + colonToken: Token, + whenFalse: Expression): ConditionalExpression; + export function updateConditional(node: ConditionalExpression, condition: Expression, ...args: any[]) { + if (args.length === 2) { + const [whenTrue, whenFalse] = args; + return updateConditional(node, condition, node.questionToken, whenTrue, node.colonToken, whenFalse); + } + Debug.assert(args.length === 4); + const [questionToken, whenTrue, colonToken, whenFalse] = args; return node.condition !== condition || node.questionToken !== questionToken || node.whenTrue !== whenTrue diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 1b1f0e93163c5..85a44e35983d4 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -197,10 +197,10 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, + node.equalsGreaterThanToken, getFunctionFlags(node) & FunctionFlags.Async ? transformAsyncFunctionBody(node) : visitFunctionBody(node.body, visitor, context), - node.equalsGreaterThanToken, ); } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index a51fa95c5662a..0fca09b454017 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -595,8 +595,8 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - transformFunctionBody(node), node.equalsGreaterThanToken, + transformFunctionBody(node), ); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 39f598bb16f06..ebce55aa7e5e4 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2309,8 +2309,8 @@ namespace ts { /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, - visitFunctionBody(node.body, visitor, context), node.equalsGreaterThanToken, + visitFunctionBody(node.body, visitor, context), ); return updated; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index aec5c92f9471c..c45672fea2e4e 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -488,8 +488,8 @@ namespace ts { nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), - visitFunctionBody((node).body, visitor, context), - visitNode((node).equalsGreaterThanToken, visitor, n => n.kind === SyntaxKind.EqualsGreaterThanToken)); + visitNode((node).equalsGreaterThanToken, visitor, n => n.kind === SyntaxKind.EqualsGreaterThanToken), + visitFunctionBody((node).body, visitor, context)); case SyntaxKind.DeleteExpression: return updateDelete(node, @@ -524,10 +524,10 @@ namespace ts { case SyntaxKind.ConditionalExpression: return updateConditional(node, visitNode((node).condition, visitor, isExpression), - visitNode((node).whenTrue, visitor, isExpression), - visitNode((node).whenFalse, visitor, isExpression), visitNode((node).questionToken, visitor, n => n.kind === SyntaxKind.QuestionToken), - visitNode((node).colonToken, visitor, n => n.kind === SyntaxKind.ColonToken)); + visitNode((node).whenTrue, visitor, isExpression), + visitNode((node).colonToken, visitor, n => n.kind === SyntaxKind.ColonToken), + visitNode((node).whenFalse, visitor, isExpression)); case SyntaxKind.TemplateExpression: return updateTemplateExpression(node, From bca3b097004a784aa2bafff1d280aa55b2ade602 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 7 Sep 2017 13:40:55 -0700 Subject: [PATCH 6/8] Respond to minor comments --- src/compiler/types.ts | 8 ++++---- src/compiler/visitor.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 917a4935dd054..502b333d60280 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4258,11 +4258,11 @@ namespace ts { } export const enum EmitHint { - SourceFile, // Emitting a SourceFile - Expression, // Emitting an Expression - IdentifierName, // Emitting an IdentifierName + SourceFile, // Emitting a SourceFile + Expression, // Emitting an Expression + IdentifierName, // Emitting an IdentifierName MappedTypeParameter, // Emitting a TypeParameterDeclaration inside of a MappedTypeNode - Unspecified, // Emitting an otherwise unspecified node + Unspecified, // Emitting an otherwise unspecified node } /* @internal */ diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index c45672fea2e4e..7d46630e227d4 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -488,7 +488,7 @@ namespace ts { nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), - visitNode((node).equalsGreaterThanToken, visitor, n => n.kind === SyntaxKind.EqualsGreaterThanToken), + visitNode((node).equalsGreaterThanToken, visitor, isToken), visitFunctionBody((node).body, visitor, context)); case SyntaxKind.DeleteExpression: @@ -524,9 +524,9 @@ namespace ts { case SyntaxKind.ConditionalExpression: return updateConditional(node, visitNode((node).condition, visitor, isExpression), - visitNode((node).questionToken, visitor, n => n.kind === SyntaxKind.QuestionToken), + visitNode((node).questionToken, visitor, isToken), visitNode((node).whenTrue, visitor, isExpression), - visitNode((node).colonToken, visitor, n => n.kind === SyntaxKind.ColonToken), + visitNode((node).colonToken, visitor, isToken), visitNode((node).whenFalse, visitor, isExpression)); case SyntaxKind.TemplateExpression: From 15e26635e93fa5d6bdf0ac16223cbed15d2705ec Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 7 Sep 2017 13:42:24 -0700 Subject: [PATCH 7/8] Remove potentially expensive assertion --- src/compiler/utilities.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6f3e06b8d06f3..97bc20093a330 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4664,12 +4664,7 @@ namespace ts { /* @internal */ export function isNodeArray(array: ReadonlyArray): array is NodeArray { - const res = array.hasOwnProperty("pos") && array.hasOwnProperty("end"); - if (res) { - const { pos, end } = array as NodeArray; - Debug.assert(typeof pos === "number" && typeof end === "number"); - } - return res; + return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } // Literals From b33dbecfd60b6665e744b0e3219012a73eda2222 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 7 Sep 2017 14:17:32 -0700 Subject: [PATCH 8/8] More emitter cleanup --- src/compiler/emitter.ts | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8cc8770df34e9..5abeecd4107e2 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -410,7 +410,7 @@ namespace ts { // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034 function emitIfPresent(node: Node | undefined) { if (node) { - pipelineEmitWithNotification(EmitHint.Unspecified, node); + emit(node); } } @@ -459,7 +459,7 @@ namespace ts { case EmitHint.SourceFile: return pipelineEmitSourceFile(node); case EmitHint.IdentifierName: return pipelineEmitIdentifierName(node); case EmitHint.Expression: return pipelineEmitExpression(node); - case EmitHint.MappedTypeParameter: return pipelineEmitMappedTypeParameter(cast(node, isTypeParameterDeclaration)); + case EmitHint.MappedTypeParameter: return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration)); case EmitHint.Unspecified: return pipelineEmitUnspecified(node); } } @@ -474,7 +474,7 @@ namespace ts { emitIdentifier(node); } - function pipelineEmitMappedTypeParameter(node: TypeParameterDeclaration): void { + function emitMappedTypeParameter(node: TypeParameterDeclaration): void { emit(node.name); write(" in "); emit(node.constraint); @@ -2390,7 +2390,7 @@ namespace ts { function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { if (canEmitSimpleArrowHead(parentNode, parameters)) { - emitSingleElementList(parameters); + emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis); } else { emitParameters(parentNode, parameters); @@ -2401,17 +2401,6 @@ namespace ts { emitList(parentNode, parameters, ListFormat.IndexSignatureParameters); } - function emitSingleElementList(list: NodeArray) { - Debug.assert(list.length === 1); - if (onBeforeEmitNodeArray) { - onBeforeEmitNodeArray(list); - } - emit(list[0]); - if (onAfterEmitNodeArray) { - onAfterEmitNodeArray(list); - } - } - function emitList(parentNode: Node, children: NodeArray, format: ListFormat, start?: number, count?: number) { emitNodeList(emit, parentNode, children, format, start, count); }