-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
nullish coalescing commit #32883
nullish coalescing commit #32883
Changes from 32 commits
2ef3e0f
91a04ed
ba39ae8
079d002
3822fde
f67e524
2327b3b
fb0d3c9
06149d0
3d94652
65b2008
e4497b8
c2e336b
b714a01
323ebf0
d659c83
55dd6ae
22d1c07
8427eca
cb76a3e
7d3ccae
b412e50
8227034
57be95d
78df31b
9e3852e
de81520
6418943
a719f66
cb187cb
7fd8658
6ef160f
8c572b1
b030f73
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 |
---|---|---|
|
@@ -33,6 +33,7 @@ namespace ts { | |
scanJsxAttributeValue(): SyntaxKind; | ||
reScanJsxToken(): JsxTokenSyntaxKind; | ||
reScanLessThanToken(): SyntaxKind; | ||
reScanQuestionToken(): SyntaxKind; | ||
scanJsxToken(): JsxTokenSyntaxKind; | ||
scanJsDocToken(): JSDocSyntaxKind; | ||
scan(): SyntaxKind; | ||
|
@@ -184,6 +185,7 @@ namespace ts { | |
"&&": SyntaxKind.AmpersandAmpersandToken, | ||
"||": SyntaxKind.BarBarToken, | ||
"?": SyntaxKind.QuestionToken, | ||
"??": SyntaxKind.QuestionQuestionToken, | ||
":": SyntaxKind.ColonToken, | ||
"=": SyntaxKind.EqualsToken, | ||
"+=": SyntaxKind.PlusEqualsToken, | ||
|
@@ -901,6 +903,7 @@ namespace ts { | |
scanJsxAttributeValue, | ||
reScanJsxToken, | ||
reScanLessThanToken, | ||
reScanQuestionToken, | ||
scanJsxToken, | ||
scanJsDocToken, | ||
scan, | ||
|
@@ -1828,6 +1831,9 @@ namespace ts { | |
pos++; | ||
return token = SyntaxKind.GreaterThanToken; | ||
case CharacterCodes.question: | ||
if (text.charCodeAt(pos + 1) === CharacterCodes.question) { | ||
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. Nit: If you re-order the 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 prefer to be consistent with the existed code. |
||
return pos += 2, token = SyntaxKind.QuestionQuestionToken; | ||
} | ||
pos++; | ||
return token = SyntaxKind.QuestionToken; | ||
case CharacterCodes.openBracket: | ||
|
@@ -2018,6 +2024,12 @@ namespace ts { | |
return token; | ||
} | ||
|
||
function reScanQuestionToken(): SyntaxKind { | ||
Debug.assert(token === SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); | ||
pos = tokenPos + 1; | ||
return token = SyntaxKind.QuestionToken; | ||
} | ||
|
||
function scanJsxToken(): JsxTokenSyntaxKind { | ||
startPos = tokenPos = pos; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
/*@internal*/ | ||
namespace ts { | ||
export function transformESNext(context: TransformationContext) { | ||
const { | ||
hoistVariableDeclaration, | ||
} = context; | ||
|
||
return chainBundle(transformSourceFile); | ||
|
||
function transformSourceFile(node: SourceFile) { | ||
|
@@ -16,9 +20,48 @@ namespace ts { | |
return node; | ||
} | ||
switch (node.kind) { | ||
case SyntaxKind.BinaryExpression: | ||
if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.QuestionQuestionToken) { | ||
return transformNullishCoalescingExpression(<BinaryExpression>node); | ||
} | ||
// falls through | ||
default: | ||
return visitEachChild(node, visitor, context); | ||
} | ||
} | ||
|
||
function createNotNullCondition(node: Expression) { | ||
return createBinary( | ||
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. Since optional chaining uses strict equality, can you switch this to strict equality? createBinary(
createBinary(
temp
createToken(SyntaxKind.ExclamationEqualsEqualsToken),
createNull()
),
createToken(SyntaxKind.AmpersandAmpersandToken),
createBinary(
temp,
createToken(SyntaxKind.ExclamationEqualsEqualsToken),
createVoidZero()
)
); |
||
createBinary( | ||
node, | ||
createToken(SyntaxKind.ExclamationEqualsEqualsToken), | ||
createNull() | ||
), | ||
createToken(SyntaxKind.AmpersandAmpersandToken), | ||
createBinary( | ||
node, | ||
createToken(SyntaxKind.ExclamationEqualsEqualsToken), | ||
createVoidZero() | ||
) | ||
); | ||
} | ||
|
||
function transformNullishCoalescingExpression(node: BinaryExpression) { | ||
const expressions: Expression[] = []; | ||
let left = visitNode(node.left, visitor, isExpression); | ||
if (!isIdentifier(left)) { | ||
const temp = createTempVariable(hoistVariableDeclaration); | ||
expressions.push(createAssignment(temp, left)); | ||
left = temp; | ||
} | ||
expressions.push( | ||
createParen( | ||
createConditional( | ||
createNotNullCondition(left), | ||
left, | ||
visitNode(node.right, visitor, isExpression))) | ||
); | ||
return inlineExpressions(expressions); | ||
} | ||
} | ||
} |
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.
Nit: This if-chain would be easier to read as a
switch
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.
I prefer to keep this because of so many other code similar to that.