-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Ensure that emitter calls callbacks #18284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
9815359
7d931bb
7d56deb
5b44de1
aae877d
8f775dc
bca3b09
15e2663
b33dbec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Edit: I was incorrect. Apparently emit does not have this guard.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get a test failure in the test |
||
| 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<ParameterDeclaration>) { | ||
| 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<Node>) { | ||
|
||
| Debug.assert(list.length === 1); | ||
| if (onBeforeEmitNodeArray) { | ||
| onBeforeEmitNodeArray(list); | ||
| } | ||
| emit(list[0]); | ||
| if (onAfterEmitNodeArray) { | ||
| onAfterEmitNodeArray(list); | ||
| } | ||
| } | ||
|
|
||
| function emitList(parentNode: Node, children: NodeArray<Node>, 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, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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<Modifier> | undefined, | ||
| typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, | ||
| parameters: ReadonlyArray<ParameterDeclaration>, | ||
| type: TypeNode | undefined, | ||
| body: ConciseBody): ArrowFunction; | ||
| export function updateArrowFunction( | ||
| node: ArrowFunction, | ||
| modifiers: ReadonlyArray<Modifier> | undefined, | ||
| typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, | ||
| parameters: ReadonlyArray<ParameterDeclaration>, | ||
| type: TypeNode | undefined, | ||
| body: ConciseBody) { | ||
| equalsGreaterThanToken: Token<SyntaxKind.EqualsGreaterThanToken>, | ||
| body: ConciseBody): ArrowFunction; | ||
| export function updateArrowFunction( | ||
| node: ArrowFunction, | ||
| modifiers: ReadonlyArray<Modifier> | undefined, | ||
| typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined, | ||
| parameters: ReadonlyArray<ParameterDeclaration>, | ||
| type: TypeNode | undefined, | ||
| equalsGreaterThanTokenOrBody: Token<SyntaxKind.EqualsGreaterThanToken> | ConciseBody, | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to ensure that we use the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add it at the end instead?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should always keep elements in the create/update methods in the order they are parsed. |
||
| bodyOrUndefined?: ConciseBody): ArrowFunction { | ||
| let equalsGreaterThanToken: Token<SyntaxKind.EqualsGreaterThanToken>; | ||
| let body: ConciseBody; | ||
| if (bodyOrUndefined === undefined) { | ||
| equalsGreaterThanToken = node.equalsGreaterThanToken; | ||
| body = cast(equalsGreaterThanTokenOrBody, isConciseBody); | ||
| } | ||
| else { | ||
| equalsGreaterThanToken = cast(equalsGreaterThanTokenOrBody, (n): n is Token<SyntaxKind.EqualsGreaterThanToken> => | ||
| 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; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4666,8 +4666,12 @@ namespace ts { | |
|
|
||
| /* @internal */ | ||
| export function isNodeArray<T extends Node>(array: ReadonlyArray<T>): array is NodeArray<T> { | ||
| return array.hasOwnProperty("pos") | ||
| && array.hasOwnProperty("end"); | ||
| const res = array.hasOwnProperty("pos") && array.hasOwnProperty("end"); | ||
| if (res) { | ||
|
||
| const { pos, end } = array as NodeArray<T>; | ||
| Debug.assert(typeof pos === "number" && typeof end === "number"); | ||
| } | ||
| return res; | ||
| } | ||
|
|
||
| // Literals | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We really should avoid calling
onEmitNodedirectly, and should be callingemitinstead, except in this case we need to emit a type parameter in a different fashion. For anyone writing a custom transform, they won't know whether theironEmitNodeis being called against a normal TypeParameter or the TypeParameter of a MappedType. That is the reason we haveEmitHint, as it allows us to provide a hint as to the context in which we are emitting a node.I would recommend we add
MappedTypeParameterto theEmitHintenum and add a branch topipelineEmitWithHintfor that branch that callsemitMappedTypeParameter. Then we can replace this code with a call topipelineEmitWithNotification(EmitHint.MappedTypeParameter, node.typeParameter).